# Generation Playbook Step-by-step instructions for generating and regenerating artifacts in this repository. Read `AGENTS.md` and `docs/source-of-truth.md` first. --- ## Pipeline overview ``` Tier 1 — Single Source of Truth (hand-authored, never generated) domain/toir.api.dsl ──┐ enums, DTOs, endpoints, HTTP methods, │ entity field mappings, primary keys │ ▼ Tier 2 — Deterministic Preprocessing (npm scripts, no LLM) api-summary.json ←─ npm run generate:api-summary openapi.json ←─ npm run generate:openapi (auxiliary) │ ▼ Tier 1 (api.dsl) + Tier 2 (context) + prompts/*.md ──► LLM Generation prompts/general-prompt.md prompts/backend-rules.md ──► server/src/modules// prompts/frontend-rules.md ──► client/src/resources// prompts/prisma-rules.md ──► server/prisma/schema.prisma prompts/auth-rules.md ──► (auth seam reference) prompts/runtime-rules.md ──► (env/docker reference) prompts/validation-rules.md ──► (validation gate reference) │ ▼ Tier 4 — Validation Gate node tools/validate-generation.mjs --artifacts-only ``` --- ## Prerequisites Before any generation run: 1. `domain/*.api.dsl` is current and valid. 2. Refresh the Tier 2 intermediate context: ```bash npm run generate:api-summary ``` 3. Run `node tools/validate-generation.mjs --artifacts-only` to confirm the baseline passes. --- ## Standard generation workflow ### Step 1 — Refresh Tier 2 derived artifacts ```bash # From repo root npm run generate:api-summary ``` ### Step 2 — Read generation inputs (context budget) > **`prompts/general-prompt.md` is the master generation prompt.** It contains all core > type mappings, naming conventions, DTO/controller/service/frontend rules, mutation > boundaries, and the complete generation workflow. Load it as the single entrypoint. > > For artifact-specific details (Prisma FK rules, auth JWKS chain, detailed validation > groups), load the relevant companion file: `prompts/prisma-rules.md`, > `prompts/auth-rules.md`, `prompts/validation-rules.md`, or `prompts/runtime-rules.md`. > > See `prompts/general-prompt.md §CONTEXT BUDGET` for the full budget model. 1. `prompts/general-prompt.md` — master generation prompt (always load) 2. `api-summary.json §` — compact entity index (fast-path context anchor) 3. `domain/*.api.dsl §API.` — **only the api block + its referenced DTOs + enums** (entity-scoped) 4. **If needed:** `prompts/prisma-rules.md` (Prisma) or `prompts/auth-rules.md` (auth seams) Before generating any DTO or component: **quote the relevant DSL field definitions verbatim first**, then generate from those quotes. This prevents training-data contamination. ### Step 3 — Generate Prisma schema Generate `server/prisma/schema.prisma` from `domain/*.api.dsl` following `prompts/prisma-rules.md`. If the schema changed, run Prisma migration in `server/`: ```bash cd server npx prisma migrate dev --name ``` ### Step 4 — Generate backend modules For each `api` block in `domain/*.api.dsl`, generate: 1. `server/src/modules//.module.ts` 2. `server/src/modules//dto/create-.dto.ts` — fields from the `DTO.Create` block in api.dsl 3. `server/src/modules//dto/update-.dto.ts` — fields from the `DTO.Update` block in api.dsl 4. `server/src/modules//.service.ts` — CRUD operations using Prisma; respect type mappings from `prompts/backend-rules.md` 5. `server/src/modules//.controller.ts` — one method per `endpoint` in the `api` block; HTTP verb and path from the `label` Register the module in `server/src/app.module.ts`. ### Step 5 — Generate frontend resources For each `api` block in `domain/*.api.dsl`, generate: 1. `client/src/resources//List.tsx` — columns from `DTO.` (response shape) 2. `client/src/resources//Create.tsx` — fields from `DTO.Create` 3. `client/src/resources//Edit.tsx` — fields from `DTO.Update` 4. `client/src/resources//Show.tsx` — fields from `DTO.` Register the resource in `client/src/App.tsx`. ### Step 6 — Verify (two-stage gate) **Stage 1 — Structural gate:** ```bash node tools/validate-generation.mjs --artifacts-only ``` Checks file existence, field names, class-validator decorators, auth guards, and RA component types. Full structural verification (requires installed deps): ```bash node tools/validate-generation.mjs ``` **Stage 2 — Eval harness:** ```bash npm run eval:generation ``` Fixture-based semantic checks. See `tools/eval/README.md`. Both must pass before the task is complete. --- ## Adding a new entity 1. Add the entity's enums, DTOs, and `api` block to `domain/toir.api.dsl`. 2. Run `npm run generate:api-summary`. 3. **Before generating:** create `tools/eval/fixtures//meta.json`, `backend.assertions.json`, and `frontend.assertions.json` with expected patterns. 4. Run `npm run eval:generation` — it will fail (entity files don't exist yet). That's expected. 5. Generate backend and frontend artifacts (Steps 3–5). 6. Run `npm run eval:generation` again — now it should pass. 7. Run `node tools/validate-generation.mjs --artifacts-only` — both gates must pass. > This is **eval-driven development**: write the failing eval first (step 3), then generate to make it pass (step 6). A passing eval confirms the LLM followed the rules. --- ## Changing an existing entity **If the domain model changes** (new field, changed type, new FK, new enum): 1. Update `domain/toir.api.dsl` (enums, DTO attributes, `map` references). 2. Run `npm run generate:api-summary`. 3. Regenerate `server/prisma/schema.prisma`, run migration. 4. Regenerate the affected modules and resources (Steps 4–6). **If only the API contract changes** (different nullability, new endpoint, different HTTP method): 1. Update `domain/toir.api.dsl` only. 2. Run `npm run generate:api-summary` to refresh `api-summary.json`. 3. Run Steps 4–6. No Prisma migration needed. --- ## Artifact traceability matrix | Artifact | DSL source | Prompt rule | Validator check | | ---------------------------------------------- | ---------------------- | ---------------------------------------------- | --------------------------------------- | | `server/prisma/schema.prisma` | `domain/*.api.dsl` | `prompts/prisma-rules.md` | `§validateBuildChecks` (file exists) | | `api-summary.json` | `domain/*.api.dsl` | — (deterministic) | `§validateBuildChecks` (freshness) | | `server/src/modules//*.ts` | `domain/*.api.dsl` | `prompts/backend-rules.md` | `§validateApiDslCoverage` | | `server/src/modules//dto/create-.dto.ts` | `DTO.Create` fields | `prompts/backend-rules.md §DTO-field-coverage` | `§validateApiDslCoverage` (field names) | | `server/src/modules//dto/update-.dto.ts` | `DTO.Update` fields | `prompts/backend-rules.md §DTO-field-coverage` | `§validateApiDslCoverage` (field names) | | `client/src/resources//*.tsx` | `domain/*.api.dsl` | `prompts/frontend-rules.md` | `§validateApiDslCoverage` | | `client/src/auth/keycloak.ts` | — (Tier 4 handwritten) | `prompts/auth-rules.md` | `§validateAuthChecks` | | `toir-realm.json` | — (Tier 4 handwritten) | `prompts/auth-rules.md` | `§validateRealmChecks` | | `docker-compose.yml` | — (Tier 4 handwritten) | `prompts/runtime-rules.md` | `§validateRuntimeContractChecks` | --- ## Verification commands reference | Command | When to use | | ----------------------------------------------------- | ------------------------------------------ | | `npm run generate:api-summary` | After any change to `domain/*.api.dsl` | | `npm run generate:openapi` | To regenerate OpenAPI 3.0.3 documentation | | `node tools/validate-generation.mjs --artifacts-only` | After every generation run (required) | | `node tools/validate-generation.mjs` | Before committing; requires installed deps | | `node tools/validate-generation.mjs --run-runtime` | End-to-end; requires running DB | --- ## OpenRouter invocation Set environment variables before any LLM-mode tool call: ``` OPENAI_API_KEY= OPENAI_BASE_URL=https://openrouter.ai/api/v1 OPENAI_MODEL= ``` The `OPENAI_BASE_URL` variable is consumed by `tools/api-format-to-openapi/convert.mjs --mode llm`. For agent-driven generation via Cursor or direct API calls, the standard workflow above applies regardless of model provider. --- ## Auxiliary tools ### `tools/api-summary-to-openapi.mjs` Generates `openapi.json` (OpenAPI 3.0.3) from `api-summary.json` deterministically. This is a documentation/integration artifact, not part of the core generation pipeline. ```bash npm run generate:openapi ``` ### `tools/api-format-to-openapi/` Auxiliary integration tool for external consumers using the `api-format` JSON schema. Not connected to the main DSL pipeline. See `docs/AID_EXPORT_README.md` for details.