Files
KIS-TOiR/docs/generation-playbook.md

9.8 KiB
Raw Blame History

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/<entity>/
  prompts/frontend-rules.md    ──► client/src/resources/<entity>/
  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:
    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

# 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 §<entity> — compact entity index (fast-path context anchor)
  3. domain/*.api.dsl §API.<EntityName>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/:

cd server
npx prisma migrate dev --name <description>

Step 4 — Generate backend modules

For each api block in domain/*.api.dsl, generate:

  1. server/src/modules/<kebab>/<entity>.module.ts
  2. server/src/modules/<kebab>/dto/create-<kebab>.dto.ts — fields from the DTO.<Entity>Create block in api.dsl
  3. server/src/modules/<kebab>/dto/update-<kebab>.dto.ts — fields from the DTO.<Entity>Update block in api.dsl
  4. server/src/modules/<kebab>/<entity>.service.ts — CRUD operations using Prisma; respect type mappings from prompts/backend-rules.md
  5. server/src/modules/<kebab>/<entity>.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/<kebab>/<Entity>List.tsx — columns from DTO.<Entity> (response shape)
  2. client/src/resources/<kebab>/<Entity>Create.tsx — fields from DTO.<Entity>Create
  3. client/src/resources/<kebab>/<Entity>Edit.tsx — fields from DTO.<Entity>Update
  4. client/src/resources/<kebab>/<Entity>Show.tsx — fields from DTO.<Entity>

Register the resource in client/src/App.tsx.

Step 6 — Verify (two-stage gate)

Stage 1 — Structural gate:

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):

node tools/validate-generation.mjs

Stage 2 — Eval harness:

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/<kebab>/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 35).
  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 46).

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 46. 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/<e>/*.ts domain/*.api.dsl prompts/backend-rules.md §validateApiDslCoverage
server/src/modules/<e>/dto/create-<e>.dto.ts DTO.<E>Create fields prompts/backend-rules.md §DTO-field-coverage §validateApiDslCoverage (field names)
server/src/modules/<e>/dto/update-<e>.dto.ts DTO.<E>Update fields prompts/backend-rules.md §DTO-field-coverage §validateApiDslCoverage (field names)
client/src/resources/<e>/<E>*.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=<openrouter-key>
OPENAI_BASE_URL=https://openrouter.ai/api/v1
OPENAI_MODEL=<model-id>

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.

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.