docs(dev-seed): canonical doc updates + refactor-log entry
- CLAUDE.md Key Conventions: 'App bootstrap' rule rewritten as 'Three binding modes per feature' — describes USE_DEV_SEED + NODE_ENV resolution order and the new ./di/bind-dev-seed export. - AGENTS.md (root): exports list now mentions ./ui + ./di/bind-dev-seed; Per-feature public-API surface table gains a row; Apps section shows the bindAll() dispatcher with three-rule logic. - docs/architecture/vertical-feature-spec.md §6: file shape now includes bind-dev-seed.ts, bind-dev-seed.test.ts, __seeds__/dev.ts; package.json exports list updated to include ./di/bind-dev-seed. - docs/architecture/data-flow-explainer.html: anatomy tree gains __seeds__/ row; LAYERS.di description updated with new binders + cross-link to di-explainer.html; new LAYERS.seeds entry; public- surface card expanded to six subpaths. - docs/superpowers/refactor-logs/2026-05-06-input-output-unification.md §7: new 'Post-Plan-9: dev-seed binders' entry summarizing the rollout (commits, per-feature additions, app wiring, tests, turbo, docs). - bind-production.test.ts: dispatcher tests use vi.stubEnv (typesafe way to test process.env in TypeScript 5+ with @types/node read-only process.env types). 4 dispatcher tests + 2 bindAllProduction tests = 7 tests total.
This commit is contained in:
@@ -1338,7 +1338,8 @@ footer .colophon {
|
||||
<span class="tree-row" data-layer="di"> <span class="dim">├─</span> symbols.ts<span class="dim"> ← inversify Symbol.for(...) keys</span></span>
|
||||
<span class="tree-row" data-layer="di"> <span class="dim">├─</span> module.ts<span class="dim"> ← ContainerModule with .toDynamicValue</span></span>
|
||||
<span class="tree-row" data-layer="di"> <span class="dim">├─</span> container.ts<span class="dim"> ← Container + .load(Module)</span></span>
|
||||
<span class="tree-row" data-layer="di"> <span class="dim">└─</span> bind-production.ts<span class="dim"> ← swaps mocks → real impls at boot</span></span>
|
||||
<span class="tree-row" data-layer="di"> <span class="dim">├─</span> bind-production.ts<span class="dim"> ← swaps mocks → real impls at boot</span></span>
|
||||
<span class="tree-row" data-layer="di"> <span class="dim">└─</span> bind-dev-seed.ts<span class="dim"> ← swaps empty mocks → populated mocks</span></span>
|
||||
<span class="tree-row" data-layer="integrations"><span class="dim">├─</span> integrations/</span>
|
||||
<span class="tree-row" data-layer="integrations"> <span class="dim">├─</span> api/</span>
|
||||
<span class="tree-row" data-layer="integrations"> <span class="dim">│ ├─</span> procedures.ts<span class="dim"> ← xProcedure + defineErrorMiddleware</span></span>
|
||||
@@ -1349,6 +1350,7 @@ footer .colophon {
|
||||
<span class="tree-row" data-layer="ui"> <span class="dim">└─</span> query.ts<span class="dim"> ← React Query option builders</span></span>
|
||||
<span class="tree-row" data-layer="testing"><span class="dim">├─</span> __factories__/<span class="dim"> ← defineFactory<Entity>((seq)=>{...})</span></span>
|
||||
<span class="tree-row" data-layer="testing"><span class="dim">├─</span> __contracts__/<span class="dim"> ← defineContractSuite<IRepo>(...)</span></span>
|
||||
<span class="tree-row" data-layer="seeds"><span class="dim">├─</span> __seeds__/<span class="dim"> ← buildDev<Entities>() — dev-mode realistic data</span></span>
|
||||
<span class="tree-row" data-layer="public"><span class="dim">└─</span> index.ts<span class="dim"> ← root: contracts only</span></span>
|
||||
</div>
|
||||
|
||||
@@ -1854,8 +1856,14 @@ const LAYERS = {
|
||||
di: {
|
||||
tag: "wiring",
|
||||
title: "DI — <em>per-feature</em> container",
|
||||
body: "Symbols are <code>Symbol.for(\"<feature>:I<X>\")</code> keys. The <code>ContainerModule</code> wires them: the repository to its mock by default; use cases and controllers via <code>.toDynamicValue</code> so their factory functions are constructed on every <code>container.get()</code>. <code>bind-production.ts</code> swaps the mock for the real impl at app boot using <code>.toConstantValue</code>.",
|
||||
meta: "Files · symbols.ts · module.ts · container.ts · bind-production.ts"
|
||||
body: "Symbols are <code>Symbol.for(\"<feature>:I<X>\")</code> keys. The <code>ContainerModule</code> wires them: the repository to its mock by default; use cases and controllers via <code>.toDynamicValue</code> so their factory functions are constructed on every <code>container.get()</code>. Three binders sit alongside: <code>bind-production.ts</code> swaps the mock for the real Payload impl, <code>bind-dev-seed.ts</code> swaps the empty mock for a populated one. App boot's <code>bindAll()</code> picks one based on <code>USE_DEV_SEED</code> + <code>NODE_ENV</code>. See the dedicated <a href=\"di-explainer.html\">DI explainer page</a> for the full lifecycle.",
|
||||
meta: "Files · symbols.ts · module.ts · container.ts · bind-production.ts · bind-dev-seed.ts"
|
||||
},
|
||||
seeds: {
|
||||
tag: "dev ergonomics",
|
||||
title: "<em>__seeds__/</em> — dev-mode data",
|
||||
body: "A lazy <code>buildDev<Entities>()</code> function per feature, built on top of the feature's existing factory. The dev-seed binder calls it to populate a <code>MockXRepository</code> at app boot when <code>USE_DEV_SEED=true</code> or <code>NODE_ENV ≠ 'production'</code>. Tests never touch this file — they construct mocks and seed via factories per-test.",
|
||||
meta: "Powered by · the feature's __factories__ · consumed by di/bind-dev-seed.ts"
|
||||
},
|
||||
integrations: {
|
||||
tag: "outside world",
|
||||
@@ -1878,8 +1886,8 @@ const LAYERS = {
|
||||
public: {
|
||||
tag: "package.json exports",
|
||||
title: "<em>index.ts</em> — the public surface",
|
||||
body: "Five subpaths per feature: <code>.</code> (contracts: types, errors, schemas, IUseCase / IController aliases, router type, constants), <code>./ui</code> (queries + components), <code>./api</code> (the tRPC router — only <code>core-api</code> consumes it), <code>./cms</code> (Payload collections — only <code>core-cms</code> consumes), <code>./di/bind-production</code> (called by app boot). Anything else is private.",
|
||||
meta: "Five subpaths · enforced by ESLint boundaries + Turborepo + the package.json exports map"
|
||||
body: "Six subpaths per feature: <code>.</code> (contracts: types, errors, schemas, IUseCase / IController aliases, router type, constants), <code>./ui</code> (queries + components), <code>./api</code> (the tRPC router — only <code>core-api</code> consumes it), <code>./cms</code> (Payload collections — only <code>core-cms</code> consumes), <code>./di/bind-production</code> (production binder, called by app boot), <code>./di/bind-dev-seed</code> (dev-seed binder, also called by app boot or by storybook). Anything else is private.",
|
||||
meta: "Six subpaths · enforced by ESLint boundaries + Turborepo + the package.json exports map"
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user