Files
suaveplan/packages/api-stack/api/api-plugin-database/src/config/config-schema.md
2026-05-27 23:29:53 +01:00

70 lines
3.3 KiB
Markdown

# `config-schema`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Defines the Zod schemas that validate every public option bundle accepted by `@suaveplan/api-plugin-database`. The schemas live in one place so the plugin factory, the pool, the migration runner, and the tenancy callables all parse their inputs through a single canonical surface. Defaults match production-sensible knobs (10-connection pool ceiling, 5-second acquire timeout, 60-second migration lease, jittered 3-attempt retry) so callers can pass only what they want to override.
The schemas use `z.object().default(...)` on every nested section so partial input is filled out completely. Two cross-section invariants are enforced via `superRefine`: `pool.min <= pool.max` and `retry.baseBackoffMs <= retry.maxBackoffMs`. Failed parses surface a `ZodError` that callers wrap into a `DatabaseError(DATABASE.INVALID_CONFIG)` with the underlying error attached as `cause`.
## Features
- Five nested sections: `pool`, `retry`, `tenancy`, `migrations`, plus top-level connection fields.
- Every leaf carries a default so `parse({})` succeeds end-to-end.
- Two `superRefine` invariants prevent nonsensical combinations.
- All numeric knobs are `z.number().int().min(...)` so floating-point values and negative budgets are rejected before they hit production code.
## Usage: Basic
```ts
import { DatabasePluginOptionsSchema } from "@suaveplan/api-plugin-database/config/config-schema";
const config = DatabasePluginOptionsSchema.parse({
url: "ws://localhost:8000/rpc",
});
console.log(config.pool.max); // 10 (default)
```
## Usage: Advanced
```ts
import {
DatabasePluginOptionsSchema,
type DatabasePluginConfigParsed,
} from "@suaveplan/api-plugin-database";
function loadConfig(json: unknown): DatabasePluginConfigParsed {
const result = DatabasePluginOptionsSchema.safeParse(json);
if (!result.success) {
throw new Error(
`Database config failed validation: ${result.error.message}`
);
}
return result.data;
}
```
## API Reference
### `PoolConfigSchema`, `RetryConfigSchema`, `TenancyConfigSchema`, `MigrationConfigSchema`
Section schemas with `.default(...)`-applied fields. Exported in case downstream packages want to compose them into a larger config.
### `DatabasePluginOptionsSchema`
Top-level schema. Accepts a partial input bundle; emits a fully populated `DatabasePluginConfigParsed`. Throws `ZodError` on invalid input. `superRefine` enforces `pool.min <= pool.max` and `retry.baseBackoffMs <= retry.maxBackoffMs`.
### `type DatabasePluginConfigParsed`
`z.infer` of the top-level schema — the canonical parsed shape consumed by every internal module.
## Implementation Notes
- The schemas live at the package boundary; internal modules consume `DatabasePluginConfigParsed`, not the raw options shape. This makes every internal call site cast-free.
- `url` defaults to `ws://localhost:8000/rpc` so the schema can be invoked with `parse({})` in tests and dev scaffolding without crashing on missing fields. Production deployments are expected to pass a real URL.
- `superRefine` runs after every section has been defaulted, so cross-section invariants always see fully populated values.
- The `zod` package is imported via the default-import form (`import z from "zod"`) per the suaveplan convention documented in `feedback_zod_import.md`.