Archive add-shared-schema-package and swap-superstruct-valibot changes to openspec/changes/archive/
2.9 KiB
Context
The monorepo currently has three workspace roots: apps/api (NestJS), apps/web (Nuxt), and packages/schema (empty placeholder). The API and web apps share no type definitions, validation logic, or database schema — each would need to duplicate these. The packages/schema directory exists but has no package.json, no tsconfig.json, and no source files.
The chosen stack is:
- Drizzle ORM (PostgreSQL) for database table definitions, relations, and migrations
- Superstruct for runtime schema validation (request payloads, configs, etc.)
- TypeScript types derived from both Drizzle and Superstruct schemas
Goals / Non-Goals
Goals:
- Create a working
@workspace/schemapackage with properpackage.json,tsconfig.json, and build pipeline - Define Drizzle table schemas, relations, and enums targeting PostgreSQL
- Define Superstruct validators for runtime data validation
- Export derived TypeScript types that both
apiandwebcan consume - Wire the package into the Turborepo build graph so it builds before its consumers
Non-Goals:
- No migrations or database connections — this package only provides schema definitions
- No API endpoints or web UI — this is purely a data layer package
- No initial table definitions — the package structure and conventions will be set up; actual tables come in follow-up changes
Decisions
-
Package name
@workspace/schema— follows the existingpackages/directory pattern; scoped to avoid conflicts with npm; private: true in package.json. -
Entry points split by concern — three source entry points (or one barrel export):
src/drizzle/— Drizzle table definitions (pgTable, relations, enums)src/validation/— Superstruct schemas (object(),string(), etc.)src/types/— Re-exported TypeScript types (inferred from Drizzle and Superstruct)
Single
src/index.tsbarrel re-exports everything. Theexportsfield inpackage.jsonmay expose sub-paths if the package grows large. -
Drizzle schema is the source of truth for DB structure — Superstruct validators mirror the same shapes but can be more permissive (e.g., optional fields for partial updates). TypeScript types are inferred from both.
-
tsconfig.jsonextends the root — no root tsconfig exists yet, sopackages/schemagets its own withmodule: nodenext,target: ES2023, strict mode, and declaration output. -
Build via
tsc— simpletscbuild; no bundler needed since it's consumed internally by the monorepo.
Risks / Trade-offs
- [Duplication risk] Superstruct schemas and Drizzle definitions could drift apart. Mitigation: Superstruct validators should reference Drizzle-derived types where possible, and tests should assert consistency.
- [Build order] Turborepo's
^builddependsOn already handles topological order, so no config changes needed — just ensure api/web list@workspace/schemain dependencies.