work-hub-server/openspec/changes/add-shared-schema-package/design.md
Nicolas HOARAU d1dbf3fe77 docs(schema): Documentation of first change
Creation of specs for openspec and opencode to start working
2026-06-04 10:58:36 +04:00

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.