# OpenSpec Change: enterprise-server-seed - **Change ID**: enterprise-server-seed - **Package**: `@suaveplan/seed` - **Category**: server/infra - **Target path**: `server/infra/seed` - **Status**: PROPOSED - **Date**: 2026-04-24 - **Reference spec**: `/mnt/s/web/suaveplan/enterprise/seed.md` --- ## Summary Deliver `@suaveplan/seed` on the genesis branch from scratch at enterprise quality. The package provides a database seeding and fixture framework for development, testing, and demo environments. It exposes a `SeedRunner` with declarative `SeedDefinition` entries (each with `name`, `run`, optional `dependsOn`, `condition`, and `teardown`), ordered execution based on dependency graph, idempotent re-run via `onConflict: 'skip' | 'update' | 'error'`, and a `SeedContext` injected into each handler carrying a `DatabaseAdapter` (from `@suaveplan/db`), logger, and factory helpers. Genesis adds Zod schemas, `@suaveplan/error` codes, OTel spans per seed step, and full integration tests against `@suaveplan/db-sqlite`. --- ## Current-state audit (genesis) Does not exist on genesis — fresh build. --- ## Available workspace deps on genesis | Package | Role | |---|---| | `@suaveplan/error` (`workspace:^`) | Typed `SEED.*` error codes | | `@suaveplan/types` (`workspace:^`) | `DatabaseLike`, `LoggerLike` | | `@suaveplan/db` (`workspace:^`) | `DatabaseAdapter` interface | | `@suaveplan/logger` (`workspace:^`) | Structured logs | | `zod` (`catalog:forms`) | Options and definition schemas | | `@opentelemetry/api` (`catalog:observability`) | Spans + counters | | `tslib` (`catalog:build`) | Runtime helpers | --- ## Public API surface ```ts class SeedRunner { constructor(options: SeedRunnerOptions) register(definition: SeedDefinition): void run(names?: string[]): Promise teardown(names?: string[]): Promise } function createSeedRunner(options: SeedRunnerOptions): SeedRunner type SeedFn = (ctx: SeedContext) => Promise interface SeedDefinition { name: string run: SeedFn teardown?: SeedFn dependsOn?: string[] condition?: (ctx: SeedContext) => Promise onConflict?: 'skip' | 'update' | 'error' // default: 'skip' } interface SeedContext { db: DatabaseAdapter logger: LoggerLike env: string // 'development' | 'test' | 'production' } interface SeedRunnerOptions { db: DatabaseAdapter env?: string // default: process.env.NODE_ENV ?? 'development' logger?: LoggerLike } interface SeedReport { total: number ran: number skipped: number failed: number results: SeedStepResult[] } interface SeedStepResult { name: string status: 'ran' | 'skipped' | 'failed' duration: number error?: string } type SeedErrorCode = | 'SEED_CIRCULAR_DEPENDENCY' | 'SEED_STEP_FAILED' | 'SEED_DEFINITION_NOT_FOUND' | 'SEED_DEPENDENCY_NOT_REGISTERED' function registerSeedErrorCodes(): void ``` --- ## File layout ```text server/infra/seed/ package.json tsconfig.json vitest.config.ts src/ index.ts error-codes.ts constants/index.ts types/ seed.types.ts seed.types.md runner/ seed-runner/ seed-runner.ts seed-runner.md seed-runner.types.ts seed-runner.test.ts index.ts graph/ dependency-graph/ dependency-graph.ts dependency-graph.md dependency-graph.test.ts index.ts tests/ integration.test.ts ``` --- ## Impact Downstream: all server packages that need development data (auth, user, product seeds). Works with any `@suaveplan/db`-compatible adapter. **Prerequisites on Verdaccio**: `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/db`, `@suaveplan/logger`. **Integration tests** use `@suaveplan/db-sqlite` (dev dep).