Archive add-shared-schema-package and swap-superstruct-valibot changes to openspec/changes/archive/
48 lines
2.9 KiB
Markdown
48 lines
2.9 KiB
Markdown
## 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/schema` package with proper `package.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 `api` and `web` can 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
|
|
|
|
1. **Package name `@workspace/schema`** — follows the existing `packages/` directory pattern; scoped to avoid conflicts with npm; private: true in package.json.
|
|
|
|
2. **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.ts` barrel re-exports everything. The `exports` field in `package.json` may expose sub-paths if the package grows large.
|
|
|
|
3. **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.
|
|
|
|
4. **`tsconfig.json` extends the root** — no root tsconfig exists yet, so `packages/schema` gets its own with `module: nodenext`, `target: ES2023`, strict mode, and declaration output.
|
|
|
|
5. **Build via `tsc`** — simple `tsc` build; 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 `^build` dependsOn already handles topological order, so no config changes needed — just ensure api/web list `@workspace/schema` in dependencies.
|