4.2 KiB
4.2 KiB
Tasks: enterprise-server-seed
Change ID: enterprise-server-seed
Package: @suaveplan/seed
Target path: server/infra/seed
Prerequisites on Verdaccio: @suaveplan/error, @suaveplan/types, @suaveplan/db, @suaveplan/logger
0. Pre-flight (non-negotiable)
- 0.1 Confirm clean working tree (
git statusreports nothing) and no in-flight worktrees with uncommitted work (git worktree listthengit statusin each) - 0.2 If any worktrees exist under
.claude/worktrees/, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (git worktree remove) before opening a new one — code that has been lost twice on main is the failure mode this guards against. - 0.3 Confirm the package set in
MANIFEST.mdmatchesfind packages -maxdepth 3 -name package.jsoncount. Drift here means a prior change archived without regenerating the manifest.
1. Scaffold
- Create directory tree per
proposal.md. package.jsonat0.1.0,"sideEffects": false, exports"."+runner+graph.- Deps:
@suaveplan/error workspace:^,@suaveplan/types workspace:^,@suaveplan/db workspace:^,@suaveplan/logger workspace:^,zod catalog:forms,@opentelemetry/api catalog:observability,tslib catalog:build. - DevDeps:
vitest catalog:testing,@vitest/coverage-istanbul catalog:testing,@suaveplan/testing workspace:^,@suaveplan/db-sqlite workspace:^. tsconfig.jsonextendinglibrary-node.json;vitest.config.tswithcreateTestConfig().- Scripts:
lint,typecheck,test,test:coverage,build,docs:check.
2. Types and errors
- Define all interfaces and Zod schemas (
SeedDefinitionSchema,SeedRunnerOptionsSchema) insrc/types/seed.types.ts. - Write
seed.types.md(≥200 words, both examples, API reference). src/error-codes.ts: four codes;registerSeedErrorCodes(); eager call.
3. Dependency graph
- Implement
src/graph/dependency-graph/dependency-graph.ts:topologicalSort(nodes: Map<string, string[]>): string[]— Kahn's algorithm; throwSEED_CIRCULAR_DEPENDENCYon cycle.validateDependencies(definitions: SeedDefinition[]): void— throwSEED_DEPENDENCY_NOT_REGISTEREDifdependsOnreferences unknown names.
- Write
dependency-graph.test.ts: linear chain, diamond, cycle detection, missing dependency. - Write
dependency-graph.md(≥200 words).
4. Seed runner
- Implement
SeedRunnerinsrc/runner/seed-runner/seed-runner.ts:register(definition): store in internal Map; validate that name is unique.run(names?): ifnamesprovided, run only those + their transitive deps; else run all. Topologically sort; execute in order; passSeedContext; handlecondition(skip if returns false); handleonConflict; collectSeedStepResult; returnSeedReport. OTel spanseed.runper step; counterseed.steps_total.teardown(names?): runteardownfn for each (in reverse dependency order).- Errors from handlers wrapped in
SEED_STEP_FAILED; other steps continue unlessonConflict === 'error'.
- Write
seed-runner.types.ts. - Write
seed-runner.test.ts(≤500 lines): all steps run; dependency ordering; condition-skip; onConflict modes; teardown reverse order; partial run by names; circular dependency throws before execution. - Write
seed-runner.md(≥200 words, simple + advanced, API reference).
5. Integration tests
tests/integration.test.ts: use@suaveplan/db-sqlitewith in-memory DB; register three seeds with dependency chain; run → verify DB state; teardown → verify cleanup;{ timeout: 15000 }.
6. Docs + verify + publish
- Root
README.md: quick-start with SQLite, dependency graph example, conditional seeding, API table. bunx turbo lint --filter=@suaveplan/seed— zero errors.bunx turbo typecheck --filter=@suaveplan/seed— zero errors.bunx turbo test --filter=@suaveplan/seed— all pass.bunx turbo test:coverage --filter=@suaveplan/seed— 100%.bun scripts/publish.ts --package @suaveplan/seed.- Update
CLAUDE.md; archive toopenspec/archive/2026-04-24-enterprise-server-seed/.