Archive add-shared-schema-package and swap-superstruct-valibot changes to openspec/changes/archive/
38 lines
2.4 KiB
Markdown
38 lines
2.4 KiB
Markdown
## Context
|
|
|
|
The schema package currently has two manually maintained modules (`validation/` and `types/`) that mirror Drizzle table definitions. Drizzle ORM has built-in Valibot support (`drizzle-orm/valibot`) that can derive insert, update, and select schemas directly from `pgTable` definitions — eliminating the need for hand-written validators and separate type files.
|
|
|
|
The constant arrays in `drizzle/enums.ts` (`PROJECT_STATUSES`, `TASK_STATUSES`, `PRIORITIES`) already define the allowed values. These can feed into Valibot `picklist()` refinements via the customization callback in `createInsertSchema`/`createUpdateSchema`.
|
|
|
|
## Goals / Non-Goals
|
|
|
|
**Goals:**
|
|
|
|
- Replace Superstruct with Valibot as the validation library
|
|
- Derive insert/update schemas from Drizzle tables using `drizzle-orm/valibot`
|
|
- Remove the `validation/` and `types/` source directories
|
|
- Remove `superstruct` dependency; add `valibot`
|
|
- Keep DB-level CHECK constraints — Valibot refinements layer on top
|
|
- Ensure `createUpdateSchema` produces all-optional shapes (replacing manual partial logic)
|
|
|
|
**Non-Goals:**
|
|
|
|
- No change to `drizzle/` module structure or table definitions
|
|
- No change to the public import paths consumers use
|
|
- No migration or database changes
|
|
|
|
## Decisions
|
|
|
|
1. **Use `drizzle-orm/valibot` not `drizzle-valibot` package** — the integration is built into `drizzle-orm` itself (since v1.0.0-beta.15). No separate package needed.
|
|
|
|
2. **One composer file for all Valibot schemas** — a single `src/valibot.ts` (or inline in `drizzle/`) containing `createInsertSchema` and `createUpdateSchema` calls for each table. No separate `validation/` directory.
|
|
|
|
3. **Customization via the second argument callback** — enum-constrained fields use `(schema) => pipe(schema, picklist([...ARRAY]))` to add the allowed-value constraint on top of Drizzle's auto-generated type info.
|
|
|
|
4. **Types are inferred, not declared** — `v.InferOutput<typeof projectInsert>` replaces the manual type aliases in `types/`. Consumers import the Valibot schema and derive types as needed.
|
|
|
|
## Risks / Trade-offs
|
|
|
|
- **[New dependency]** Valibot replaces Superstruct. The API surface is similar but not identical — consumers may need to adjust error handling (Valibot uses `ValiError` not `StructError`).
|
|
- **[Picklist sync]** The `picklist()` values reference the constant arrays, so they stay in sync automatically. No new drift risk.
|