113 lines
8.3 KiB
Markdown
113 lines
8.3 KiB
Markdown
# Tasks — seed
|
||
|
||
> Every checkbox MUST reflect work actually done in this change.
|
||
|
||
## 1. Spec authoring
|
||
|
||
- [x] 1.1 Read `openspec/AGENTS.md` §0, §0a, §0b, §0c, §6a, §7, §13, §14 end-to-end
|
||
- [x] 1.2 Read `../suaveplan/packages/server/seed/src/` — all 17 implementation files
|
||
- [x] 1.3 Read `../suaveplan/enterprise/seed.md` in full
|
||
- [x] 1.4 Read `openspec/archive/2026-05-16-add-storage-http/` end-to-end as the closest precedent (universal-tier, error-coded, AbortSignal-plumbed migration)
|
||
- [x] 1.5 Draft `proposal.md` with parity checklist, source mapping, affected dependents
|
||
- [x] 1.6 Draft `design.md` covering layout, rename rationale, error-code map, topoSort rewrite, LoggerLike injection, AbortSignal plumbing
|
||
- [x] 1.7 Draft `specs/seed/spec.md` in OpenSpec `### Requirement: / #### Scenario:` form
|
||
- [x] 1.8 Every requirement carries a `**Verified by:**` line naming concrete planned `it(...)` titles
|
||
- [x] 1.9 Build the numbered Requirement/Scenario implementation checklist (§0c step 6)
|
||
|
||
## 2. Scaffolding
|
||
|
||
- [x] 2.1 Create `packages/database/seed/` mirroring the storage-http layout
|
||
- [x] 2.2 Write `package.json` v0.0.0, `"sideEffects": false`, subpath exports for `./builder/builder`, `./registry/registry`, `./runner/runner`, `./fixtures/fixtures`, `./utils/topo-sort/topo-sort`, `./types/common`, `./constants`, `./error-codes/error-codes`
|
||
- [x] 2.3 Wire deps: `@suaveplan/error: workspace:^`, `@suaveplan/types: workspace:^`, `tslib: catalog:build`
|
||
- [x] 2.4 Wire devDeps: `@suaveplan/testing: workspace:*`, `@vitest/coverage-istanbul: catalog:`, `fast-check: catalog:`, `typescript: catalog:`, `vite: catalog:build`, `vite-plugin-dts: catalog:build`, `vitest: catalog:`
|
||
- [x] 2.5 Write `tsconfig.json`, `tsconfig.lib.json` extending `@suaveplan/typescript-config`
|
||
- [x] 2.6 Write `vite.config.ts` (multi-entry build for every subpath export)
|
||
- [x] 2.7 Write `vitest.config.ts` using `createTestConfig()` from `@suaveplan/testing/config`
|
||
- [x] 2.8 Write `README.md` (≥ 200 words, required sections per CLAUDE.md docs gate)
|
||
|
||
## 3. Implementation — constants & errors
|
||
|
||
- [x] 3.1 `src/constants/index.ts` — `DEFAULT_ENVIRONMENTS`, `MAX_DEPENDENCY_DEPTH`, `DEFAULT_BATCH_SIZE`, `SEED_STATUS` (as-const)
|
||
- [x] 3.2 `src/error-codes/error-codes.ts` — `defineCodes("SEED", [...])` registry (7 codes), `SeedError extends SuaveplanError<SeedErrorCode>` with `seedName?` / `dependency?` discriminants
|
||
- [x] 3.3 `src/error-codes/error-codes.test.ts` — every code is reachable via `SeedError` construction; cause-chain preservation verified
|
||
- [x] 3.4 `src/error-codes/error-codes.md` — Purpose / Features / Usage Basic / Usage Advanced / API Reference / Implementation Notes
|
||
|
||
## 4. Implementation — types
|
||
|
||
- [x] 4.1 `src/types/common.ts` — every public type from upstream `types/common.ts` preserved verbatim; `SeedStore` methods gain optional `signal?: AbortSignal`; `SeedRunConfig` gains optional `signal?: AbortSignal`
|
||
- [x] 4.2 `src/types/common.md` — co-located doc per docs-coverage gate
|
||
|
||
## 5. Implementation — builder
|
||
|
||
- [x] 5.1 `src/builder/builder.types.ts` — `ISeedBuilder` interface mirroring the fluent surface
|
||
- [x] 5.2 `src/builder/builder.ts` — `SeedBuilder` class + `defineSeed(name)` convenience, behaviour-identical to upstream
|
||
- [x] 5.3 `src/builder/builder.test.ts` — every fluent method, including default-table-equals-name, environments empty-vs-set, dataFactory wins over data, build() output shape
|
||
- [x] 5.4 `src/builder/builder.md` — Purpose / Features / Usage Basic / Usage Advanced / API Reference / Implementation Notes
|
||
- [x] 5.5 `src/builder/index.ts` — explicit named re-exports (no `export *`)
|
||
|
||
## 6. Implementation — registry
|
||
|
||
- [x] 6.1 `src/registry/registry.types.ts` — `ISeedRegistry` interface
|
||
- [x] 6.2 `src/registry/registry.ts` — `SeedRegistry` class; `register` raises `SeedError({ code: SEED.DUPLICATE_NAME, seedName })` on collision; `getForEnvironment` returns defensive copies
|
||
- [x] 6.3 `src/registry/registry.test.ts` — register/registerMany/get/getAll/getForEnvironment/has/remove/clear/size/names + duplicate-name error
|
||
- [x] 6.4 `src/registry/registry.md`
|
||
- [x] 6.5 `src/registry/index.ts` — explicit named re-exports
|
||
|
||
## 7. Implementation — topo-sort
|
||
|
||
- [x] 7.1 `src/utils/topo-sort/topo-sort.ts` — clean Kahn's-algorithm rewrite per design.md; `topoSort` + `detectCycles`; raises `SeedError` with `UNREGISTERED_DEPENDENCY`/`CIRCULAR_DEPENDENCY`/`DEPENDENCY_DEPTH_EXCEEDED`
|
||
- [x] 7.2 `src/utils/topo-sort/topo-sort.test.ts` — port every upstream test case verbatim (characterisation), plus property-based DAG tests via `fast-check`, plus cycle-reporter tests
|
||
- [x] 7.3 `src/utils/topo-sort/topo-sort.md`
|
||
- [x] 7.4 `src/utils/topo-sort/index.ts` — explicit named re-exports
|
||
|
||
## 8. Implementation — runner
|
||
|
||
- [x] 8.1 `src/runner/runner.types.ts` — `ISeedRunner` interface
|
||
- [x] 8.2 `src/runner/runner.ts` — `SeedRunner` class:
|
||
- constructor `(registry, store, logger?)` with no-op `LoggerLike` default
|
||
- `run(config)` applies `only`/`exclude` filter, env-filter, topo-sort
|
||
- per-seed: skip if dep failed, honour `truncate`, batch by `batchSize ?? DEFAULT_BATCH_SIZE`, apply `skip`/`update`/`replace` strategy
|
||
- `dryRun` short-circuit returns synthesised result without store IO
|
||
- `signal` checked before each seed → remaining seeds marked `skipped` with `error: "Aborted"`
|
||
- `continueOnError` controls whether failure halts the run
|
||
- `onProgress` callback emits per completed seed
|
||
- structured log events (`seed.run.start`, `seed.run.complete`, `seed.completed`, `seed.skipped`, `seed.failed`)
|
||
- any error thrown by injected `SeedStore` wrapped as `SeedError({ code: SEED.STORE_ERROR, cause })` and recorded on `SeedResult.error`
|
||
- [x] 8.3 `src/runner/runner.test.ts` — every behaviour above; mirror upstream test names where applicable; integrate with `InMemorySeedStore`
|
||
- [x] 8.4 `src/runner/runner.md`
|
||
- [x] 8.5 `src/runner/index.ts` — explicit named re-exports
|
||
|
||
## 9. Implementation — fixtures
|
||
|
||
- [x] 9.1 `src/fixtures/fixtures.types.ts` — if any local types needed
|
||
- [x] 9.2 `src/fixtures/fixtures.ts` — `FixtureFactory<T>`, `createFixtureFactory`, `InMemorySeedStore`, `createInMemoryStore` (preserve upstream `SeedStore` shape; gain optional `signal?` plumbing as no-op)
|
||
- [x] 9.3 `src/fixtures/fixtures.test.ts` — counter, overrides, createMany, store insert/update/findExisting/truncate/tableExists/getRecords/clear
|
||
- [x] 9.4 `src/fixtures/fixtures.md`
|
||
- [x] 9.5 `src/fixtures/index.ts` — explicit named re-exports
|
||
|
||
## 10. Root barrel & public surface
|
||
|
||
- [x] 10.1 `src/index.ts` — re-export every symbol listed in design.md "Package contract surface" using explicit named exports (no `export *` — rule §6a)
|
||
- [x] 10.2 Verify `bunx turbo build --filter=@suaveplan/seed` succeeds and dist contains every advertised subpath
|
||
|
||
## 11. Pre-archive gates
|
||
|
||
- [x] 11.1 `bunx turbo lint --filter=@suaveplan/seed` green; zero biome suppressions
|
||
- [x] 11.2 `bunx turbo typecheck --filter=@suaveplan/seed` green
|
||
- [x] 11.3 `bunx turbo test --filter=@suaveplan/seed` green; zero `.skip` / `.only` / `it.todo`
|
||
- [x] 11.4 `bunx turbo test:coverage --filter=@suaveplan/seed` green at 100% statement/branch/function/line (Istanbul)
|
||
- [x] 11.5 `bun run docs:check --filter=@suaveplan/seed` green
|
||
- [x] 11.6 `grep -rnE "from ['\"](vitest|bun:test)['\"]" packages/database/seed/src/` → zero matches (rule §7)
|
||
- [x] 11.7 `grep -rnE "^export \*" packages/database/seed/src/` → only the root barrel and exempt forms (rule §6a)
|
||
- [x] 11.8 `grep -rnE "from ['\"](node:|bun:|fs|path|stream|net|http)['\"]" packages/database/seed/src/` → zero matches (tier purity)
|
||
- [x] 11.9 `grep -rn "@deprecated\|TODO\|FIXME\|ts-ignore\|ts-expect-error\|\\bany\\b\|console\\.log" packages/database/seed/src/ --include="*.ts"` → zero matches
|
||
- [x] 11.10 Every `### Requirement` in `specs/seed/spec.md` checked off against the implementation checklist from §1.9
|
||
- [x] 11.11 `bun scripts/folder-reorg/generate-manifest.ts` run; `MANIFEST.md` includes `@suaveplan/seed`
|
||
- [x] 11.12 `STATUS.md` `@suaveplan/seed` row flipped from `–` to `✅`
|
||
|
||
## 12. Fold + archive
|
||
|
||
- [x] 12.1 Fold `specs/seed/spec.md` into `openspec/specs/seed/spec.md` (canonical file is created here for the first time, since the package is net-new)
|
||
- [x] 12.2 Move `openspec/changes/add-seed/` to `openspec/archive/<yyyy-mm-dd>-add-seed/`
|
||
- [x] 12.3 Commit per CLAUDE.md commit-style; do not push without user approval
|