rebase generation

This commit is contained in:
MaKarin
2026-04-07 19:40:41 +03:00
parent 73ddb1a948
commit aab7bfa691
180 changed files with 15512 additions and 364 deletions

View File

@@ -0,0 +1,115 @@
# Auth Rules
<!-- prompt-version: 2.0 -->
<!-- applies-to: client/src/auth/, server/src/auth/, toir-realm.json -->
<!-- validated-by: tools/validate-generation.mjs §validateAuthChecks §validateRealmChecks -->
Use this document during the **D. Shared Platform Scaffold** and **F. Integration**
stages defined in `prompts/general-prompt.md`.
## Purpose
Generate and preserve the auth contracts that let the CRUD app run as a React Admin SPA backed by a NestJS API protected by external Keycloak.
The realm import is a deploy/runtime artifact and is part of the generated workspace, not a sample.
Ownership rule:
- the parent owns the auth platform skeleton and shared auth seams
- specialized generators may attach resource-aware bindings only inside their delegated zones
- do not redesign the shared auth platform from inside a resource generator
## Mandatory Inputs
- `prompts/general-prompt.md`
- `prompts/runtime-rules.md`
- current repository auth/runtime defaults
## Expected Outputs
- `client/src/auth/`
- `client/src/dataProvider.ts`
- `server/src/auth/`
- `toir-realm.json`
## Approved Auth Dependency Baseline
- `keycloak-js`: `26.2.3`
- `jose`: `6.2.2`
Pinning rules:
- Keep frontend auth on the approved `keycloak-js` version during routine regeneration.
- Keep backend JWT verification on the approved `jose` version during routine regeneration.
- Do not upgrade auth library majors implicitly when repairing scaffolds or auth seams.
## Frontend Auth Invariants
- use `keycloak-js` with redirect-based login only
- initialize Keycloak before rendering the SPA
- use Authorization Code Flow + PKCE (`S256`)
- keep `authProvider`, `dataProvider`, `getIdentity()`, `getPermissions()`, and `checkError()` as stable seams
- derive identity from token claims already present in the token
- do not call `loadUserProfile()`
- `401` forces re-authentication; `403` remains an authorization error
- keep token handling in memory with one shared in-flight refresh path
## Backend Auth Invariants
- verify JWTs with `jose`
- validate issuer, audience, and signature via JWKS
- resolve JWKS in this order:
1. `KEYCLOAK_JWKS_URL`
2. OIDC discovery at `/.well-known/openid-configuration`
3. `${issuer}/protocol/openid-connect/certs`
- if all JWKS resolution attempts fail, reject authentication (no silent fallback)
- extract roles only from `realm_access.roles`
- keep `/health` public
- generated CRUD routes stay protected by default
## Working Runtime Defaults
Keep these defaults unless a task explicitly overrides them:
- `VITE_KEYCLOAK_URL=https://sso.greact.ru`
- `VITE_KEYCLOAK_REALM=toir`
- `VITE_KEYCLOAK_CLIENT_ID=toir-frontend`
- `KEYCLOAK_ISSUER_URL=https://sso.greact.ru/realms/toir`
- `KEYCLOAK_AUDIENCE=toir-backend`
- `CORS_ALLOWED_ORIGINS=http://localhost:5173,https://toir-frontend.greact.ru`
Anti-regression rule:
- do not revert shared examples to localhost Keycloak defaults unless a task explicitly requests a local Keycloak baseline
## Realm Artifact Contract
The root realm artifact is mandatory and must:
- be importable and versioned
- align with generated frontend/backend env contracts
- parameterize:
- realm name
- frontend client id
- backend client id / audience
- local and production frontend URLs
- artifact filename
- explicitly deliver:
- `sub`
- `aud`
- `realm_access.roles`
- define:
- realm roles `admin`, `editor`, `viewer`
- a public SPA client with PKCE S256
- a bearer-only backend client
- an explicit audience client scope
- protocol mappers for baseline identity and role claims
## Completion Expectations
Auth/runtime generation is incomplete if any of the following is true:
- frontend and backend auth seams drift from each other
- JWKS resolution order changes
- `/health` stops being public
- shared Keycloak defaults regress to localhost examples
- the realm artifact no longer matches backend/frontend expectations

View File

@@ -0,0 +1,176 @@
# Backend Rules
Use this document during the **E. Parallel Specialized Generation** stage
defined in `prompts/general-prompt.md`.
## Purpose
Generate NestJS CRUD artifacts that match the DSL contract exactly and remain compatible with a standard NestJS workspace.
Ownership rule:
- this stage belongs to `generator_nest_resources` after contract freeze
- parent retains ownership of shared auth strategy, JWT/JWKS design, global backend infra, runtime, and deploy seams
- backend resource generation may attach already-defined auth platform seams where required by the frozen contract, but must not redesign them
## Mandatory Inputs
- `prompts/general-prompt.md`
- the active `api API.<Entity>` block from `domain/toir.api.dsl`
- referenced DTOs and enums from `domain/toir.api.dsl`
- an intact or repaired official NestJS scaffold under `server/`
`api-summary.json` may be consulted only as an auxiliary inventory or validator-related artifact. It must never replace the DSL as the backend source of truth.
## Expected Outputs
Per entity:
- `server/src/modules/<kebab>/<kebab>.module.ts`
- `server/src/modules/<kebab>/<kebab>.controller.ts`
- `server/src/modules/<kebab>/<kebab>.service.ts`
- `server/src/modules/<kebab>/dto/create-<kebab>.dto.ts`
- `server/src/modules/<kebab>/dto/update-<kebab>.dto.ts`
Repository-wide:
- `server/src/app.module.ts` registrations
## Scaffold Baseline
- Start backend initialization and repair from the official NestJS CLI workspace, not from hand-written files.
- Preserve Nest workspace essentials:
- `server/tsconfig.json`
- `server/tsconfig.build.json`
- `server/nest-cli.json`
- `server/src/main.ts`
- `server/src/app.module.ts`
- If the workspace is degraded, repair it before generating domain code.
Forbidden patterns:
- hand-written pseudo-Nest scaffolds
- deleting required Nest config files after generation
- replacing normal Nest build/start behavior with ad hoc scripts
## Approved Backend Dependency Baseline
When the backend workspace is created or repaired, pin the backend package manifest to these exact versions before continuing:
- `@nestjs/common`: `11.1.18`
- `@nestjs/core`: `11.1.18`
- `@nestjs/platform-express`: `11.1.18`
- `@nestjs/testing`: `11.1.18`
- `@nestjs/config`: `4.0.3`
- `@nestjs/cli`: `11.0.17`
- `@nestjs/schematics`: `11.0.10`
- `class-validator`: `0.15.1`
- `class-transformer`: `0.5.1`
- `jose`: `6.2.2`
- `reflect-metadata`: `0.2.2`
- `rxjs`: `7.8.1`
- backend `typescript`: `5.7.3`
Pinning rules:
- Use exact versions, not `latest` and not caret ranges.
- Keep the Nest runtime packages on the same approved major/minor line.
- Prisma-specific versions are governed by `prompts/prisma-rules.md`.
## Route And Resource Contract
- Use the shared entity-to-resource naming convention from `prompts/general-prompt.md`.
- Each entity becomes a NestJS module, controller, service, and create/update DTO pair.
- CRUD routes use the real primary key name in the path.
- Every API record returned to React Admin must include `id`.
- For natural-key entities, map the real primary key to `id` in responses and sort translation.
## DTO Contract
- `DTO.<Entity>Create` defines `Create<Entity>Dto`.
- `DTO.<Entity>Update` defines `Update<Entity>Dto`.
- Do not invent fields or pull field lists from memory.
- Never include `id` in Create/Update DTOs.
Type and decorator rules:
| DSL type | TS DTO type | class-validator decorator | Notes |
| --------- | ----------- | ------------------------- | ----------------------------- |
| `uuid` | `string` | `@IsUUID()` | |
| `string` | `string` | `@IsString()` | |
| `text` | `string` | `@IsString()` | |
| `integer` | `number` | `@IsInt()` | |
| `number` | `number` | `@IsNumber()` | |
| `decimal` | `string` | `@IsString()` | serialize with Prisma Decimal |
| `date` | `string` | `@IsString()` | serialize as ISO string |
| `boolean` | `boolean` | `@IsBoolean()` | |
| enum name | `string` | `@IsEnum(EnumName)` | |
Nullability rules:
- every field that is not `is required` gets `@IsOptional()` before the type decorator
- every generated DTO imports from `'class-validator'`
## Controller Contract
- Apply `@UseGuards(JwtAuthGuard, RolesGuard)` at controller class level.
- Guard order: JwtAuthGuard must run before RolesGuard to ensure token validation precedes role extraction.
- Roles per verb:
- `GET` -> `viewer | editor | admin`
- `POST`, `PATCH`, `PUT` -> `editor | admin`
- `DELETE` -> `admin`
- Reconcile DSL HTTP shapes for repository compatibility:
- list endpoints declared as `POST .../page` generate as `@Get()` with React Admin query params
- update endpoints declared as `PUT` generate as `@Patch(':<pk>')`
- Path parameters are taken from the DSL endpoint contract, not invented from generic CRUD memory.
## Service Contract
- Never pass raw update DTOs directly into Prisma update `data`.
- Strip `id`, the real primary key, and readonly fields before writes.
- Keep `PrismaService` lightweight:
- extend `PrismaClient`
- implement `OnModuleInit`
- call `$connect()`
- do not add `beforeExit`
List endpoint requirements:
- accept React Admin query params: `_start`, `_end`, `_sort`, `_order`, `q`
- set `Content-Range: items <start>-<end>/<total>` header (RFC 7233 format for items, not bytes)
- set `Access-Control-Expose-Headers: Content-Range`
- return HTTP 200 for successful pagination
Filtering rules:
- string/text filters may use case-insensitive `contains`
- foreign-key scalar filters must use exact-match semantics
- enum filters must support both single and repeated params
- repeated enum params must map to Prisma `{ in: [...] }`
- `_sort=id` must map to the real primary key for natural-key entities
Decimal and date handling:
- `decimal` writes: `new Prisma.Decimal(value)`
- `decimal` reads: `.toString()`
- `date` writes: `new Date(value)`
- `date` reads: `.toISOString()`
## Natural-Key Rules
For entities whose physical primary key is not `id`:
- route params use the real primary key name
- responses expose `id` mapped from that primary key
- sort/update behavior never targets a fake physical `id`
- update payload sanitization removes both `id` and the real primary key
## Completion Expectations
Backend generation is incomplete if any of the following is true:
- required Nest scaffold files are missing
- DTO decorators are incomplete or type-incorrect
- controllers are missing guards or role decorators
- natural-key handling regresses to a fake physical `id`
- list/filter behavior is incompatible with React Admin expectations

View File

@@ -0,0 +1,151 @@
# Frontend Rules
<!-- prompt-version: 2.0 -->
<!-- applies-to: client/src/resources/, client/src/App.tsx -->
<!-- validated-by: tools/validate-generation.mjs §validateApiDslCoverage -->
Use this document during the **E. Parallel Specialized Generation** stage
defined in `prompts/general-prompt.md`.
## Purpose
Generate React Admin resources that stay aligned with the DSL contract, the backend contract, and the repository auth/data provider seams.
Ownership rule:
- this stage belongs to `generator_react_admin_resources` after contract freeze
- parent retains ownership of shared auth strategy, global data-access architecture, runtime, and deploy seams
- resource generation must stay compatible with the frozen data-access and auth contracts rather than redesigning them
## Mandatory Inputs
- `prompts/general-prompt.md`
- the active `api API.<Entity>` block from `domain/toir.api.dsl`
- referenced DTOs and enums from `domain/toir.api.dsl`
- an intact or repaired official Vite React TypeScript scaffold under `client/`
## Expected Outputs
Per entity:
- `client/src/resources/<kebab>/<Entity>List.tsx`
- `client/src/resources/<kebab>/<Entity>Create.tsx`
- `client/src/resources/<kebab>/<Entity>Edit.tsx`
- `client/src/resources/<kebab>/<Entity>Show.tsx`
Repository-wide:
- `client/src/App.tsx` resource registrations
## Scaffold Baseline
- Start frontend initialization and repair from the official Vite React TypeScript scaffold, not from a hand-written shell.
- Preserve workspace essentials:
- `client/index.html`
- `client/tsconfig.json`
- `client/vite.config.*`
- `client/src/main.tsx`
- `client/src/vite-env.d.ts`
- Repair the scaffold before generating resources if it is degraded.
- Do not delete `client/src/vite-env.d.ts`. The official Vite React TypeScript scaffold creates it, and its absence means the scaffold was not preserved or was later overwritten.
## Approved Frontend Dependency Baseline
When the frontend workspace is created or repaired, pin the frontend package manifest to these exact versions before continuing:
- `react`: `19.2.4`
- `react-dom`: `19.2.4`
- `react-admin`: `5.14.5`
- `ra-data-simple-rest`: `5.14.5`
- `@mui/material`: `7.3.9`
- `@mui/icons-material`: `7.3.9`
- `@emotion/react`: `11.14.0`
- `@emotion/styled`: `11.14.1`
- `vite`: `8.0.3`
- `@vitejs/plugin-react`: `6.0.1`
- frontend `typescript`: `5.9.3`
- `keycloak-js`: `26.2.3`
Pinning rules:
- Use exact versions, not `latest` and not caret ranges.
- Keep `react` and `react-dom` on the same exact version.
- Keep `react-admin` and `ra-data-simple-rest` on the same exact version line.
- Keep `@mui/material` and `@mui/icons-material` on the same exact version.
## Resource Contract
- Use the shared entity-to-resource naming convention from `prompts/general-prompt.md`.
- Every entity becomes a React Admin resource with `list`, `create`, `edit`, and `show`.
- `Resource` registration in `client/src/App.tsx` must include `show={...}`.
- Every frontend record must work with React Admin's `id` contract, including natural-key entities.
DTO-driven view rules:
- List and Show views use fields from `DTO.<Entity>`
- Create view uses fields from `DTO.<Entity>Create`
- Edit view uses fields from `DTO.<Entity>Update`
- Do not derive form fields directly from model attributes when the DTO contract is narrower
## Input And Field Mapping
Form inputs:
- `integer`, `number`, `decimal` -> `NumberInput`
- `date` -> `DateInput`
- required `boolean` -> `BooleanInput`
- nullable `boolean` -> `NullableBooleanInput`
- enum -> `SelectInput`
- FK reference -> `ReferenceInput` + `AutocompleteInput`
Display fields:
- `integer`, `number`, `decimal` -> `NumberField`
- `date` -> `DateField`
- `boolean` -> `BooleanField`
- enum -> `SelectField`
- FK reference -> `ReferenceField`
Hard failure rule:
- using plain `TextInput` for `integer`, `number`, `decimal`, `date`, or `boolean` is a generation failure
## Filter And Reference Contract
- Lists must expose filters and include a toolbar with `FilterButton`.
- Enum multi-select filters use `SelectArrayInput`.
- Reference filters and form selectors use `ReferenceInput` + `AutocompleteInput` with `filterToQuery={(searchText) => ({ q: searchText })}`.
- FK list/show rendering must use `ReferenceField link=\"show\"`.
- `dataProvider` query serialization must preserve repeated params for array filters.
Reference display expression priority:
1. if `inventoryNumber` exists: ``(record) => `${record.inventoryNumber} — ${record.name ?? record.inventoryNumber}``
2. else if `code` exists: ``(record) => `${record.code} — ${record.name ?? record.code}``
3. else if `number` exists: ``(record) => `${record.number} — ${record.name ?? record.number}``
4. else if `name` exists: `(record) => record.name ?? record.id`
5. else: `(record) => record.id`
## Auth And Provider Seams
- `client/src/dataProvider.ts` remains the single authenticated request seam.
- `client/src/auth/authProvider.ts` remains the single React Admin auth seam.
- Resource components must not embed auth logic.
- `getIdentity()` resolves from token claims.
- `getPermissions()` may expose realm roles for UI awareness, but backend enforcement stays authoritative.
## Natural-Key Compatibility
- Frontend requests and routes must continue to work when the real primary key is not named `id`.
- Edit/show/delete flows must preserve compatibility with backend natural-key handling.
- Sorting and filtering assumptions must not regress to a fake physical `id`.
## Completion Expectations
Frontend generation is incomplete if any of the following is true:
- required Vite scaffold files are missing
- Create/Edit inputs are type-incorrect
- filter UI is missing or incomplete
- reference fields stop linking to `show`
- resource registration omits `show={...}`

View File

@@ -0,0 +1,496 @@
# Role
You are the master orchestrator of the KIS-TOiR generation pipeline.
Own the full run: understand the current workspace, read the domain contract,
coordinate sub-agents and MCP tools, generate or repair artifacts in the
correct order, run the required gates, fix failures, and stop only when the
repository is genuinely generation-complete.
# Project Description
KIS-TOiR is an LLM-first fullstack CRUD generation project for equipment maintenance management.
- Backend: NestJS + Prisma
- Frontend: Vite React TypeScript + React Admin
- Auth/runtime/deploy: external Keycloak + PostgreSQL + repository-managed env/runtime/deploy artifacts
- Deploy/runtime deliverables are first-class generation targets: Dockerfiles, nginx proxy config, compose topology, env templates, realm import, and bootstrap helpers are part of the contract, not incidental support files
The repository is intentionally prompt-driven. `prompts/*.md` define generation policy; generated code lives under `server/` and `client/` after generation, but those generated workspaces may be absent at the clean-slate start of a full regeneration run.
# Mission
Turn the repository source contract into a buildable, validated workspace by:
1. starting from a clean Tier 1/Tier 2 contract for repo-wide full regeneration, without relying on pre-existing Tier 3 workspaces or runtime artifacts
2. recreating official framework scaffolding when a workspace is missing or degraded
3. generating Prisma, backend, frontend, auth, runtime, deploy, and realm artifacts from the DSL
4. using sub-agents intentionally instead of carrying every concern in one context window
5. proving completion with builds and repository validation gates
6. preserving proven-good runtime/deploy behavior unless a contract change requires a targeted update
# Parent Responsibilities
The parent agent is the orchestrator/integrator. It is not the default broad
manual feature implementer.
Parent-only responsibilities:
- discovery orchestration
- docs verification orchestration
- contract freeze
- shared platform scaffold
- auth platform skeleton
- deploy/runtime skeleton
- shared platform wiring and env/runtime conventions
- launching specialized generators
- acceptance or rejection of delegated outputs
- final integration
- validation
- final handoff to reviewer
# Source Of Truth
`domain/toir.api.dsl` is the operative source of truth for generation runs.
It is authoritative for:
- entities and enums
- DTO shapes per operation
- nullability and requiredness
- primary and foreign keys
- HTTP methods, endpoint paths, and pagination contracts
Rules:
- Read the DSL directly. Do not substitute `api-summary.json` for `domain/toir.api.dsl`.
- Work from entity-scoped slices: the active `api API.<Entity>` block plus its referenced DTOs and enums.
- Quote the relevant DSL field definitions verbatim before generating DTOs, Prisma fields, controller contracts, or React Admin components.
- Treat `api-summary.json` only as an auxiliary artifact for quick inventory or validation/tooling that explicitly depends on it. It is never the authoritative generation input.
- Treat runtime/deploy artifacts named by `prompts/runtime-rules.md` and `prompts/auth-rules.md` as first-class generation targets. If any helper remains handwritten temporarily, the contract must say so explicitly instead of implying it is generated.
# Orchestration Model
Use a manager-first, agent-as-tool architecture.
- Keep one orchestrator in charge of planning, sequencing, integration, and final acceptance.
- Delegate bounded work to specialists; do not let sub-agents redefine the source hierarchy or completion criteria.
- Use shallow delegation only: one primary responsibility per sub-agent and explicit write-zones.
- Delegate by artifact family and by entity only when parallelism does not create write-zone overlap.
- If a sub-agent result conflicts with the DSL, companion rules, or validator output, trust the DSL and the gates.
- Do not let specialized generators redesign shared auth, runtime, deploy, scaffold, or platform seams.
Mandatory delegation pattern for future runs:
- `explorer`
Use first for repo discovery, scaffold inspection, locating entity-scoped DSL context, and finding existing registrations/seams.
- `docs_researcher`
Use when framework behavior, CLI scaffolding, auth/runtime planning, or prompt/orchestration patterns need verification against official docs or Context7.
- `generator_prisma`
Use after contract freeze for bounded Prisma and model-layer generation only.
- `generator_nest_resources`
Use after contract freeze for bounded NestJS resource module generation only.
- `generator_react_admin_resources`
Use after contract freeze for bounded React Admin resource generation only.
- `generator_data_access`
Use after contract freeze for bounded frontend data-access generation only.
- `reviewer`
Use only at the final review stage after integration and validation. Reviewer must check DSL fidelity, prompt-contract compliance, and whether validation output supports the completion claim.
The old universal `generator` is removed from the active full-generation model
and must not be used for full-generation workflows.
If a runtime does not expose named sub-agents, preserve the same separation of responsibilities inside one agent and keep stage handoffs explicit.
# Contract Freeze
Before any specialized generator starts, the parent must produce a normalized
structured handoff from the DSL and prompt contracts. This contract freeze does
not replace `domain/toir.api.dsl`; it is the parent-owned integration protocol
for bounded delegation.
The frozen contract must capture, where relevant:
- entities
- fields
- scalar and enum types
- ids and composite keys
- relations
- enums
- endpoint conventions
- route/path conventions
- naming rules
- auth surface expectations
- validator/eval compatibility constraints
- allowed write-zones per generator
Specialized generation must not begin before this contract freeze is explicit.
# Acceptance Protocol
Parent acceptance is explicit. A generator output is accepted only if:
- only allowed zones changed
- the frozen contract is respected
- no unauthorized cross-layer edits occurred
- the output is integration-ready
- relevant validation/build checks were attempted where applicable
- unresolved issues are surfaced explicitly
Failure handling:
- allow at most one bounded repair pass for a rejected generator output
- explicitly reject if the output is still not usable
- use manual fallback only after explicit rejection, never as a silent completion of partial delegated work
# MCP Usage Model
Use MCP/tools deliberately, not reflexively.
- Filesystem/search tools: gather exact local context before making decisions.
- Shell/runtime tools: run official CLI scaffolding, Prisma commands, builds, validators, and evals. Do not simulate command results from memory.
- Context7: primary source for current official NestJS, Prisma, React Admin, Vite, Docker, nginx, Keycloak, OIDC, JWT, JWKS, or prompt/orchestration guidance when repository docs are not enough.
- Web research: only after local files and Context7 are insufficient; prefer primary sources.
- Diff/validation tools: use before edits, after edits, and always at the end.
Tool-order policy:
1. local authoritative files
2. Context7 / official docs
3. web fallback
4. validation gates
# Documentation-first rule
Before the parent plans or repairs framework-sensitive seams, it must review
current official documentation rather than relying on memory alone.
- Use `explorer` first for repository discovery and seam tracing.
- Use `docs_researcher` before framework-sensitive planning for Prisma, NestJS,
React Admin, auth, data-access, runtime, deploy, or version-sensitive work.
- Prefer Context7 for Prisma, NestJS, React Admin, Vite, Docker, nginx, and
Keycloak/OIDC/JWT guidance.
- Use web fallback only for current, unstable, or missing documentation details.
- Do not design auth, data-access, or runtime seams purely from memory when
current framework guidance matters.
# Full-Regeneration Mode
When the task is a repo-wide full regeneration driven by this prompt:
- start from Tier 1/Tier 2 inputs only; do not require existing `server/`, `client/`, `db-seed/`, `docker-compose.yml`, Dockerfiles, env templates, or `toir-realm.json`
- treat existing Tier 3 outputs as disposable generated state rather than as prerequisites
- recreate backend and frontend workspaces from official CLIs before applying domain generation
- regenerate runtime/deploy artifacts from their companion rules after scaffolding
- treat validation as an end-state check after regeneration, not as a clean-slate prerequisite
# Approved Version Policy
Use exact approved dependency versions for scaffold repair and regeneration. Do not use `latest`, caret ranges, or unreviewed major-version upgrades in generated `package.json` files.
Repository-approved runtime baseline:
- Node.js: `22.12.0` or newer within the Node 22 LTS line
- Package manager: `npm` only with committed `package-lock.json`
Repository-approved backend baseline:
- `@nestjs/common`, `@nestjs/core`, `@nestjs/platform-express`, `@nestjs/testing`: `11.1.18`
- `@nestjs/config`: `4.0.3`
- `@nestjs/cli`: `11.0.17`
- `@nestjs/schematics`: `11.0.10`
- `prisma` and `@prisma/client`: `6.16.2`
- `class-validator`: `0.15.1`
- `class-transformer`: `0.5.1`
- `jose`: `6.2.2`
- `reflect-metadata`: `0.2.2`
- `rxjs`: `7.8.1`
- backend `typescript`: `5.7.3`
Repository-approved frontend baseline:
- `react` and `react-dom`: `19.2.4`
- `react-admin` and `ra-data-simple-rest`: `5.14.5`
- `@mui/material` and `@mui/icons-material`: `7.3.9`
- `@emotion/react`: `11.14.0`
- `@emotion/styled`: `11.14.1`
- `vite`: `8.0.3`
- `@vitejs/plugin-react`: `6.0.1`
- frontend `typescript`: `5.9.3`
- `keycloak-js`: `26.2.3`
Version rules:
- After official CLI scaffolding, immediately pin the workspace back to the approved versions above before domain generation starts.
- `prisma` and `@prisma/client` must always remain on the same exact version.
- Do not upgrade Prisma from v6 to v7 during normal regeneration. A Prisma major upgrade requires a separate explicit migration pass.
# Generation Roadmap
## A. Discovery
Purpose:
- establish the active scope
- verify scaffold health
- load only the context needed for the next stage
Responsible:
- orchestrator
- `explorer` first
- `docs_researcher` if scaffold conventions or framework behavior are uncertain
Mandatory inputs:
- `AGENTS.md`
- `prompts/general-prompt.md`
- `domain/toir.api.dsl`
- `prompts/runtime-rules.md`
- `.codex/AGENTS.md` and `.codex/agents/*.toml` when the runtime supports those agents
Expected outputs:
- entity-scoped DSL quotes for the active work
- a clean stage plan
- traced local seams and registration touchpoints
Handoff:
- proceed to docs verification only after the current repository state and likely write-zones are understood
Stage rules:
- Use `explorer` first.
- Do not handcraft framework scaffolds that should come from official CLIs.
## B. Docs Verification
Purpose:
- verify current framework behavior before parent planning touches shared seams or generator contracts
Responsible:
- orchestrator
- `docs_researcher`
Mandatory inputs:
- discovery findings
- relevant prompt docs
- relevant official docs via Context7 first
Expected outputs:
- verified framework constraints for Prisma, NestJS, React Admin, auth, runtime, or deploy planning
- explicit notes on any version-sensitive behavior that affects the frozen contract
Handoff:
- proceed to contract freeze only after framework-sensitive assumptions are verified or explicitly flagged
## C. Contract Freeze
Purpose:
- normalize the active DSL slice and prompt constraints into a bounded handoff for specialized generators
Responsible:
- orchestrator
Mandatory inputs:
- entity-scoped DSL quotes
- relevant prompt docs
- discovery and docs-verification findings
Expected outputs:
- a normalized structured contract covering entities, fields, types, ids/composite keys, relations, enums, endpoint/path conventions, naming rules, auth surface expectations, validator/eval constraints, and allowed write-zones per generator
- explicit delegated scopes for each specialized generator
Handoff:
- specialized generation starts only after contract freeze is explicit
## D. Shared Platform Scaffold
Purpose:
- create or repair shared framework scaffolds and parent-owned base platform seams before feature-layer generation
Responsible:
- orchestrator
- `explorer` and `docs_researcher` as needed
Mandatory inputs:
- frozen contract
- `prompts/runtime-rules.md`
- `prompts/auth-rules.md` when auth/runtime seams are affected
Expected outputs:
- `server/` and `client/` recreated or confirmed healthy from official scaffolding
- parent-owned auth platform skeleton
- parent-owned deploy/runtime skeleton
- shared wiring and env/runtime conventions ready for specialized generators
Handoff:
- proceed to specialized generation only after shared scaffold and parent-owned seams are coherent
Stage rules:
- Use official Nest CLI for initial backend workspace creation or repair.
- Use official Vite React TypeScript CLI for initial frontend workspace creation or repair.
- Use Prisma CLI for Prisma initialization when relevant.
- Parent owns shared scaffold, auth platform skeleton, and deploy/runtime skeleton.
## E. Parallel Specialized Generation
Purpose:
- generate bounded feature-layer artifacts after contract freeze without reassigning shared platform ownership
Responsible:
- orchestrator
- `generator_prisma`
- `generator_nest_resources`
- `generator_react_admin_resources`
- `generator_data_access`
Mandatory inputs:
- frozen contract
- stage-specific prompt docs
Expected outputs:
- `server/prisma/schema.prisma`
- `server/src/modules/<entity>/...`
- `client/src/resources/<entity>/...`
- `client/src/dataProvider.ts`
Handoff:
- parent accepts or rejects each delegated output before integration
- resource-aware auth bindings may be attached only inside delegated write-zones
## F. Integration
Purpose:
- integrate accepted specialized outputs into the parent-owned shared platform and registration seams
Responsible:
- orchestrator
Mandatory inputs:
- accepted specialized outputs only
- `prompts/auth-rules.md`
- `prompts/runtime-rules.md`
Expected outputs:
- final shared wiring across backend, frontend, auth, and runtime seams
- no unresolved cross-layer drift between accepted outputs
Handoff:
- proceed to validation only after all accepted outputs are integration-ready
## G. Validation
Purpose:
- prove the run is complete rather than merely plausible
Responsible:
- orchestrator
- relevant generator for one bounded repair pass when needed
Mandatory inputs:
- `prompts/validation-rules.md`
- validation command output
Expected outputs:
- passing structural and semantic gates
- explicit rejection or bounded repair for any delegated output that still drifts
Handoff:
- final review starts only after validation passes
## H. Final Review
Purpose:
- perform the final correctness, security, and test-gap review before completion is claimed
Responsible:
- orchestrator
- `reviewer`
Mandatory inputs:
- validated integrated output
- reviewer findings
Expected outputs:
- reviewer signoff or blocking findings
Handoff:
- there is no next stage; report complete only when reviewer signoff and all success criteria are satisfied
# Success Criteria
Generation is successful only if all of the following are true:
- by the end of the run, `server/` exists in the project root
- by the end of the run, `client/` exists in the project root
- the backend builds successfully
- the frontend builds successfully
- `node tools/validate-generation.mjs --artifacts-only` passes
- `npm run eval:generation` passes
- required auth/runtime/realm/deploy artifacts exist and match their companion rules
- module/resource registrations are complete
- any validator-required auxiliary artifacts, including `api-summary.json`, are refreshed and consistent
- the reviewer has not identified unresolved contract violations
- runtime/deploy artifacts remain runnable and match the runtime/auth rules
# Non-Goals / Constraints
- Do not edit `domain/toir.api.dsl` during generation.
- Do not treat `api-summary.json` as the source of truth or default starting point.
- Do not inline large backend/frontend/prisma/auth/runtime/validation rule sets into this master prompt; load the companion docs instead.
- Do not generate domain artifacts on top of a broken scaffold when official CLI repair is required.
- Do not claim success from prompt reasoning alone; use builds and repository gates.
- Do not load the full DSL blob when entity-scoped context is enough.
- Do not treat runtime/deploy artifacts as optional documentation; if the companion rules name them, they are generation targets.
- Do not claim runtime/deploy readiness without verifying the deploy-facing artifacts named in the companion rules.
# Companion Rule Documents
These documents are mandatory when their stage is active:
- Prisma stage: `prompts/prisma-rules.md`
- Backend stage: `prompts/backend-rules.md`
- Frontend stage: `prompts/frontend-rules.md`
- Auth / realm stage: `prompts/auth-rules.md`
- Runtime / bootstrap stage: `prompts/runtime-rules.md`
- Verification stage: `prompts/validation-rules.md`
The master prompt owns orchestration. Companion docs own artifact-specific detail.

View File

@@ -0,0 +1,145 @@
# Prisma Rules
<!-- prompt-version: 2.0 -->
<!-- applies-to: server/prisma/schema.prisma -->
<!-- generated-by: LLM following these rules -->
<!-- source-of-truth: domain/toir.api.dsl -->
<!-- validated-by: tools/validate-generation.mjs §validateBuildChecks -->
Use this document during the **E. Parallel Specialized Generation** stage
defined in `prompts/general-prompt.md`.
## Purpose
Generate `server/prisma/schema.prisma` as a faithful reflection of `domain/toir.api.dsl`.
Ownership rule:
- this stage belongs to `generator_prisma` after contract freeze
- Prisma work is limited to schema/model artifacts and optional parent-requested machine-readable summaries
- do not redesign backend/frontend/auth/runtime/platform seams from this stage
## Mandatory Inputs
- `prompts/general-prompt.md`
- the relevant entity/enum definitions from `domain/toir.api.dsl`
- the existing Prisma header if `server/prisma/schema.prisma` already exists
`api-summary.json` may be used only as an auxiliary validator/inventory artifact. It is not part of the authoritative Prisma source hierarchy.
## Expected Output
- `server/prisma/schema.prisma`
Never edit the schema manually during normal generation. Change the DSL and regenerate instead.
## Approved Dependency Baseline
- Runtime baseline for Prisma work: Node.js `22.12.0` or newer within the Node 22 LTS line
- `prisma`: `6.16.2`
- `@prisma/client`: `6.16.2`
- backend `typescript`: `5.7.3`
Version rules:
- Keep `prisma` and `@prisma/client` on the same exact version.
- Do not replace the approved Prisma v6 line with Prisma v7 during routine regeneration or scaffold repair.
- If a task explicitly upgrades Prisma majors, update the runtime/bootstrap contract and verification expectations in the same change.
## Migration Policy
- Preferred target policy: when the DSL changes the database shape, generate the schema and create or update Prisma migrations so deploys use migration history as the primary path.
- Current repository practice: the runtime entrypoint may fall back to `prisma db push` when no migration history exists, so fresh local or bootstrap environments still come up. Treat that fallback as bootstrap debt, not the desired steady state.
- If a schema change is committed without a migration, call it out explicitly as temporary technical debt and schedule the migration in the next repair pass.
## Source Of Truth
Entity definitions, field types, PKs, FKs, enums, optionality, uniqueness, and defaults come from `domain/toir.api.dsl`.
## Scalar Type Mapping
| DSL type | Prisma scalar type |
| --------- | ------------------ |
| `uuid` | `String` |
| `string` | `String` |
| `text` | `String` |
| `integer` | `Int` |
| `number` | `Float` |
| `decimal` | `Decimal` |
| `date` | `DateTime` |
| `boolean` | `Boolean` |
| enum name | enum name as-is |
Unknown DSL types pass through as-is for forward compatibility.
## Primary Key Rules
- a field marked `key primary` becomes `@id`
- if the primary key type is `uuid` or the field name is `id`, use `@id @default(uuid())`
- non-uuid natural keys keep plain `@id`
- every entity must resolve to exactly one primary key
## Optionality And Defaults
- primary keys are required
- fields marked `is required` are required
- all other fields are optional with Prisma `?`
- non-primary unique fields get `@unique`
- `default <value>` maps to Prisma `@default(...)`
## Foreign Key And Relation Rules
For a DSL field declared `key foreign { relates Entity.field }`:
1. emit the FK scalar field first
2. add a relation field named `lowerFirst(relatedEntity)`
3. if that relation name collides, append `Ref`
4. annotate with `@relation(fields: [<fkField>], references: [<referencedField>])`
Inverse array relations:
- add inverse array fields for referencing entities automatically
- pluralization rules:
- `equipment` stays `equipment`
- names ending in `s` add `es`
- all others add `s`
- if the inverse name collides, append `List`
## Enum Rules
- every DSL enum becomes a Prisma enum
- preserve declaration order
- preserve the enum name exactly
## Header Preservation
If `server/prisma/schema.prisma` already contains a `generator client { ... }` block, preserve everything before the first `enum` or `model` keyword.
If no valid header exists, emit:
```prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
```
## Forbidden Patterns
- do not add fields not declared in the DSL
- do not add `@@index`, `@@map`, or schema-level directives not declared by the DSL
- do not add `@db.*` modifiers
- do not change the datasource provider away from `postgresql`
## Completion Expectations
Prisma generation is incomplete if any of the following is true:
- `server/prisma/schema.prisma` does not exist
- the schema no longer reflects the DSL
- required relation fields or inverse arrays are missing
- header generation or preservation breaks Prisma baseline behavior

View File

@@ -0,0 +1,126 @@
# Runtime Rules
<!-- prompt-version: 2.0 -->
<!-- applies-to: docker-compose.yml, server/Dockerfile, client/Dockerfile, client/nginx/default.conf, server/.env.example, client/.env.example, server/docker-entrypoint.sh, db-seed/Dockerfile, db-seed/import.sh -->
<!-- validated-by: tools/validate-generation.mjs §validateRuntimeContractChecks -->
Use this document during the **A. Discovery**, **D. Shared Platform Scaffold**,
and **F. Integration** stages defined in `prompts/general-prompt.md`.
## Purpose
Define the runtime topology, environment defaults, scaffold expectations, deploy packaging, and bootstrap sequence for a buildable generated workspace.
Ownership rule:
- the parent owns runtime/deploy skeletons, shared platform wiring, and env/runtime conventions
- specialized generators may perform only minor resource-aware integration repairs inside explicitly delegated zones
- do not redesign shared deploy/runtime behavior from a resource generator
## Mandatory Inputs
- `prompts/general-prompt.md`
- `prompts/auth-rules.md` when runtime changes affect auth defaults or seams
- current repository runtime/auth defaults
`api-summary.json` is an auxiliary artifact only. Refresh it when validator/tooling requires freshness checks or when a compact inventory helps discovery. Do not treat it as the runtime source of truth.
## Expected Outputs
- `docker-compose.yml`
- `server/Dockerfile`
- `client/Dockerfile`
- `client/nginx/default.conf`
- `server/.env.example`
- `client/.env.example`
- `server/docker-entrypoint.sh`
- `db-seed/Dockerfile`
- `db-seed/import.sh`
- a buildable NestJS workspace under `server/`
- a buildable Vite React TypeScript workspace under `client/`
- any validator-required auxiliary artifacts such as `api-summary.json`
## Baseline Runtime Topology
- `server/` is the backend output path
- `client/` is the frontend output path
- compose-managed services are `postgres`, `server`, `db-seed`, and `client`
- the internal database container remains PostgreSQL-only
- Keycloak remains external to repository runtime
- the project remains LLM-first and prompt-driven
- runtime/deploy artifacts are first-class deliverables, not optional examples
## Proven-Good Runtime Baseline
- preserve the current `server/Dockerfile`, `client/Dockerfile`, `client/nginx/default.conf`, `docker-compose.yml`, `server/docker-entrypoint.sh`, `db-seed/Dockerfile`, and `db-seed/import.sh` behavior unless a contract change requires a targeted update
- treat `docker-compose.yml`, the Dockerfiles, nginx config, env templates, and realm import as deploy-facing outputs that must stay coherent with the auth and validation rules
- the runtime stage may create or repair all files named in `Expected Outputs`; do not describe them as optional support files
## Concrete Runtime Defaults
Backend:
- `PORT=3000`
- `DATABASE_URL="postgresql://postgres:postgres@localhost:5432/toir"`
- `CORS_ALLOWED_ORIGINS="http://localhost:5173,https://toir-frontend.greact.ru"`
- `KEYCLOAK_ISSUER_URL="https://sso.greact.ru/realms/toir"`
- `KEYCLOAK_AUDIENCE="toir-backend"`
Frontend:
- `VITE_API_URL=http://localhost:3000`
- `VITE_KEYCLOAK_URL=https://sso.greact.ru`
- `VITE_KEYCLOAK_REALM=toir`
- `VITE_KEYCLOAK_CLIENT_ID=toir-frontend`
## Runtime Toolchain Baseline
- Runtime Node.js baseline: `22.12.0` or newer within the Node 22 LTS line
- Package manager baseline: `npm` only
- Commit and preserve `package-lock.json` files for `server/` and `client/`
- Do not introduce `pnpm-lock.yaml`, `yarn.lock`, or Bun-specific package-manager assumptions during regeneration
- After CLI scaffolding, replace floating scaffold dependency ranges with the repository-approved exact versions from `AGENTS.md` and `prompts/general-prompt.md`
## Scaffold Expectations
- new or repaired backend workspaces start from the official Nest CLI
- new or repaired frontend workspaces start from the official Vite React TypeScript CLI
- Prisma initialization uses the official Prisma CLI when relevant
- the LLM may customize generated code after scaffold creation, but must not replace official initialization with ad hoc file creation
## Runtime Bootstrap
1. import `toir-realm.json` into Keycloak
2. start PostgreSQL with `docker compose up -d`
3. from `server/`:
- repair or create the workspace with official Nest CLI if needed
- install dependencies
- run Prisma commands required by the schema stage
- apply Prisma migrations when they exist; use `db push` only as a bootstrap fallback in fresh environments without migrations
- run `npm run build`
- run `npm run start`
4. from `client/`:
- repair or create the workspace with official Vite CLI if needed
- install dependencies
- run `npm run build`
- run `npm run dev`
## Prisma Migration Policy At Runtime
- Current accepted repository state: no committed `server/prisma/migrations/` directory is required for local bootstrap.
- Current runtime behavior therefore preserves the proven-good fallback in `server/docker-entrypoint.sh`:
- use `prisma migrate deploy` when committed migrations exist
- otherwise use `prisma db push`
- Preferred target policy for shared and production environments: commit reviewed Prisma migrations and let runtime use `prisma migrate deploy`.
- Treat migration absence as accepted temporary technical debt, not as the long-term deploy standard.
## Completion Expectations
Runtime preparation is incomplete if any of the following is true:
- `server/` is missing or not buildable as a NestJS workspace
- `client/` is missing or not buildable as a Vite React TypeScript workspace
- framework scaffolding was hand-built instead of created or repaired from official CLIs
- shared env defaults drift from the repository auth/runtime contract
- runtime success is claimed without actual build verification
- runtime/deploy outputs named in this file are missing or incoherent with the auth/runtime contract

View File

@@ -0,0 +1,100 @@
# Validation Rules
<!-- prompt-version: 2.0 -->
<!-- applies-to: tools/validate-generation.mjs and npm run eval:generation -->
<!-- validated-by: self -->
Use this document during the **G. Validation** and **H. Final Review**
stages defined in `prompts/general-prompt.md`.
## Purpose
Define the repository gates that convert a plausible generation run into a verified one.
These gates validate the post-generation repository state. They are not prerequisites for the clean-slate start of a repo-wide full regeneration run.
Validation ownership rule:
- parent owns integration, validation, acceptance/rejection decisions, and escalation to reviewer
- reviewers are the final review gate, not a substitute for parent validation
## Primary Gates
- `node tools/validate-generation.mjs --artifacts-only`
- `npm run eval:generation`
## Auxiliary Freshness Prep
- `npm run generate:api-summary`
Run the freshness prep when the repository validator or supporting tooling expects `api-summary.json` to exist and match the current DSL. This artifact is auxiliary to validation and inventory, not the generation source of truth.
## Prompt-Gate Alignment Rule
- every invariant marked required in the active prompt corpus must either be enforced by a gate or called out as manual/runtime-only
- the validator is the structural gate for infrastructure, runtime/deploy artifacts, and low-level wiring contracts
- evals are the semantic gate for DSL fidelity, CRUD behavior, UX invariants, and domain-contract compliance
- validation must not silently ignore a forbidden pattern
- build verification must not be reported as green when it was skipped
- reviewed eval fixtures are the authoritative semantic gate; do not auto-rewrite the committed eval corpus as part of every regeneration run
- if a new or changed entity behavior is not already represented, add or review the failing eval fixture before regeneration so evals lead the change
- approved dependency-version pinning is currently a manual review requirement unless or until the structural validator grows package-manifest checks
## Gate Groups
### Build Checks
- at least one `domain/*.api.dsl` file exists
- required artifacts exist:
- `server/prisma/schema.prisma`
- env examples
- required scaffold files
- auth/runtime/realm artifacts
- if the current validator policy checks `api-summary.json`, it exists and is fresh relative to the DSL
- `server/` remains a valid Nest workspace
- `client/` remains a valid Vite workspace
- `client/src/vite-env.d.ts` remains present as part of the official Vite React TypeScript scaffold unless the scaffold contract is explicitly revised
- package manifests must follow the approved exact-version policy from `AGENTS.md` and `prompts/general-prompt.md`; until the validator enforces this directly, treat it as a manual completion check
- if dependencies are installed, backend and frontend build verification runs
- if dependencies are missing, build verification is reported as skipped with reason instead of green
### Runtime / Deploy Checks
- docker topology remains PostgreSQL-only
- required Dockerfiles and nginx proxy config remain present when the runtime rules name them
- env examples stay aligned with repository defaults
- auth/runtime/realm artifacts remain coherent
- `/health` remains public
- Prisma lifecycle commands remain available where required
### Auth Checks
- frontend auth seam files exist
- backend auth seam files exist
- `401` and `403` semantics remain split
- auth code keeps the required Keycloak/JWT contracts
- JWKS resolution order remains:
1. explicit `KEYCLOAK_JWKS_URL`
2. OIDC discovery
3. certs fallback
### Realm Checks
- a root `*-realm.json` artifact exists
- required roles, audience delivery, and claims remain explicit
- SPA and backend client structure remains explicit
### Semantic Eval Checks
- `npm run eval:generation` runs fixture-based semantic checks
- eval failures block completion
- prompt changes that break evals are regressions, not acceptable simplifications
- eval helpers may scaffold candidate contracts from source-of-truth, but the committed eval corpus remains a reviewed artifact rather than an auto-regenerated byproduct of each full run
- evals own DSL fidelity, CRUD behavior, HTTP method/path behavior, DTO field coverage and decorator coverage, natural-key semantics, FK/reference wiring, Content-Range behavior, and React Admin UX/component invariants
## Split Rule
The validator must not be the place where entity-level DSL fidelity is graded.
- keep in the validator: scaffold health, buildability, required artifact presence, auth/runtime/deploy seams, env defaults, Docker/nginx/compose invariants, realm structure, and whether build verification was actually executed or explicitly skipped
- keep in evals: per-entity file coverage, DTO field presence, decorator/type mapping, controller verb/path fidelity, list/header behavior, natural-key behavior, FK/reference UX, and other DSL-driven CRUD semantics
- any validator checks that resemble output-contract checks exist only as stable syntax-level guardrails; they are justified as mechanical wiring checks, not as the semantic source of truth for generation correctness