scaffold · git:20261013.7afecc2 · 2026-10-13 · sha256 3e96349d28629f11
scaffold git:20261013.7afecc2A
Immutable. This exact content never changes and is served at /api/v1/blob/3e96349d28629f11.
--- name: scaffold description: >- Creates ONE file of a ddd-ts-kit role from a template with `ddd-ts-kit generate`, with its spec, fake and registration, then lists the places where business logic is expected. Use whenever a single aggregate, entity, value object, domain event, error or service, port, repository, adapter, gateway, policy, job, background job, state machine, process manager, event handler, builder, end-to-end spec or context is needed, instead of writing it by hand, or when the guard refuses a hand-written file. For a whole feature use use-case; for events between contexts use integration-event. argument-hint: "<kind> <context> <Name> [options]" allowed-tools: - Read - Edit - Bash(npx ddd-ts-kit generate *) - Bash(npx ddd-ts-kit check *) - Bash(npx ddd-ts-kit list *) --- # Scaffold one file Requested: `$ARGUMENTS` Boilerplate is generated, never typed: the generator and the checker share one definition of the tree, so a generated file conforms by construction and costs no tokens. ## Procedure 1. **Name from the glossary** of the context's `CONTEXT.md`. A missing term is added in the same command with `--term "<Term>=<meaning>"`. Technical words (`Manager`, `Helper`, `Data`, `Info`, `Impl`, `Model`, ...) are refused (`language/no-technical-name`): find the business word; `--allow-name` only when the word really is the business term. 2. **Run with `--json`** (`--dry-run` first when unsure): ```bash npx ddd-ts-kit generate <kind> ... --json ``` Exact arguments of every kind: [kinds.md](kinds.md), or `npx ddd-ts-kit --help`. A worker confined to one context adds `--local-only`: the command refuses, and writes nothing, when it would write a shared file. 3. **Open only the `next` places**, each a `file:line` holding a `TODO(domain)` that states the decision expected. Decide, write, delete the marker. A marker you cannot resolve is a question for the user, not a guess. `notes` says what the generator could not do. 4. **Replace each `it.todo`** of the generated spec by a real test (skill `ddd-ts-kit:testing`). 5. `npx ddd-ts-kit check --changed-since HEAD` and the tests of the context. ## What the generator settles for you - **Registration.** In the declared style (the default with tsyringe) the class carries its decorator and the barrel `<context>.declarations.ts` is rewritten; never edit the barrel. In the explicit style the binding is added between the markers of `<context>.module.ts`. - **Dependencies.** A generated class states what it depends on in its constructor, each parameter typed by a port, and its decorator lists nothing: the generator reads the signature into the generated file of the context. Add a dependency by adding a parameter, then `npx ddd-ts-kit docs` (skill `ddd-ts-kit:wiring`). - **Names.** A generated handler names the aggregate after its concept, `const invoice = Invoice.create(..)`, and a generated search names its lines after what it searches (`invoice`, `invoices`). Keep the business word when you fill the `TODO(domain)`: never `target`, `data` or `item` (`naming/business-name`). - **Access.** `command` and `query` are refused without `--permission <aggregate>.<action>` or `--public`; the permission joins `<context>.permissions.ts`. - **Ports.** A port is an abstract class, used as its own injection token: no constant, no token file. `port` and `repository` write the fake and the contract suite with it. - **Dependencies between kinds.** A missing repository or domain event is created; a missing aggregate, port, use case or route stops the command with the one to run first. - **Value objects.** `value-object` writes a class extending `ValueObject` of the kernel, a private constructor, a static factory that checks the rules (`create`, renamed after what it builds when there are several: `of`, `between`, `closed`) and the type of its props. A value is always this class, never a function answering a plain object nor an exported object literal (`domain/value-object-class`, under `"stack.values": "classes"`, which `init` writes; `npx ddd-ts-kit explain domain/value-object-class` says what it reads): the class compares by value (`equals`), checks its invariants once, keeps its operations next to its data and is recognised with `instanceof` by a mapper. - `route` writes a controller class in its own folder (or a `defineRoute` function under `"stack.routes": "functions"`); `controller` always writes the class; `route-group` writes a group with its prefix and guards, `guard` a guard of the project with its spec; `representation <context> <UseCase> xml,csv` adds what a controller answers in besides JSON, `form <context> <UseCase>` the hints of its form. - `schema` writes one shape of the HTTP contract several routes use, declared once and shared, in `presentation/http/shared/` of the context, or in `presentation/` of the shared kernel with `schema shared-kernel <Name>`; a command route answers an identifier with `acceptedSchema`. - **Documents.** The generated lists of `CONTEXT.md` and the generated documentation are refreshed. Never change the structure the generator produced (constructor visibility, factories, suffixes, folders, decorators). If it does not fit, the model is probably wrong: go back to `ddd-ts-kit:glossary` or `ddd-ts-kit:bounded-contexts`.