Files
toir-automatization/CLAUDE.md
2026-04-07 19:40:41 +03:00

477 lines
23 KiB
Markdown

# KIS-TOiR — Agent Operating Rules
Read this file at the start of every session before reading any other file.
---
## What this repository is
KIS-TOiR is a fullstack CRUD application (NestJS backend + React Admin frontend)
for equipment maintenance management (Техническое обслуживание и ремонт).
Generation is driven by a single authoritative source file:
- `domain/toir.api.dsl` — the complete API contract: enums, DTOs, endpoints, HTTP methods, pagination
---
## Source-of-truth hierarchy
### Tier 1 — authoritative (hand-authored; never overwritten by generation)
| File | Authoritative for |
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `domain/*.api.dsl` | Enums, DTO shapes per operation, nullability, HTTP verb+path per endpoint, endpoint names, pagination contracts. Single source of truth. Drives: NestJS modules + React Admin resources + Prisma schema. |
| `prompts/*.md` | Auth rules, runtime rules, framework scaffold rules, Prisma rules, validation rules, generation policy, naming conventions. |
| `AGENTS.md` (this file) | Agent workflow, mutation boundaries, verification contract. |
| `docs/completion-contract.md` | Operational definition of done, success tiers, failure modes, recovery rules. |
| `.codex/AGENTS.md` | Codex-specific agent governance supplement (Codex runtime only). |
| `.claude/CLAUDE.md` | Claude Code-specific agent governance supplement. **MANDATORY for Claude Code sessions.** Defines subagent registry, orchestration entry points, write-zone enforcement, MCP tool access. |
| `prompts/claude-orchestration-rules.md` | Claude Code orchestration and subagent delegation rules. **MANDATORY when orchestrating subagents.** Defines shallow delegation pattern, contract freeze, acceptance protocol, failure handling, write-zone boundaries. |
### Tier 2 — deterministic derivative (generated by script; never edited manually)
| File | Generated from | Command |
| ------------------ | ------------------ | ------------------------------ |
| `api-summary.json` | `domain/*.api.dsl` | `npm run generate:api-summary` |
### Tier 3 — LLM-generated artifacts (never edit manually after generation)
These outputs are end-state generation targets. During a repo-wide full
regeneration driven by `prompts/general-prompt.md`, they may be absent at the
start of the run and are recreated from Tier 1 sources plus official CLI
scaffolding.
| Zone | Generated from |
| -------------------------------- | ------------------------------------------------------ |
| `server/src/modules/<entity>/` | `domain/*.api.dsl` + `prompts/backend-rules.md` |
| `client/src/resources/<entity>/` | `domain/*.api.dsl` + `prompts/frontend-rules.md` |
| `server/src/app.module.ts` | Module registrations derived from api.dsl api blocks |
| `client/src/App.tsx` | Resource registrations derived from api.dsl api blocks |
| `server/prisma/schema.prisma` | `domain/*.api.dsl` + `prompts/prisma-rules.md` |
| `server/src/auth/` | `prompts/auth-rules.md` |
| `client/src/auth/` | `prompts/auth-rules.md` |
| `client/src/dataProvider.ts` | `prompts/auth-rules.md` |
| `toir-realm.json` | `prompts/auth-rules.md` |
| `docker-compose.yml` | `prompts/runtime-rules.md` |
| `server/Dockerfile` | `prompts/runtime-rules.md` |
| `client/Dockerfile` | `prompts/runtime-rules.md` |
| `client/nginx/default.conf` | `prompts/runtime-rules.md` |
| `server/docker-entrypoint.sh` | `prompts/runtime-rules.md` |
| `db-seed/Dockerfile` | `prompts/runtime-rules.md` |
| `db-seed/import.sh` | `prompts/runtime-rules.md` |
| `server/.env.example` | `prompts/runtime-rules.md` |
| `client/.env.example` | `prompts/runtime-rules.md` |
### Tier 4 — handwritten / framework-managed support files
- Framework scaffold and bootstrap helpers that remain manually maintained unless a repair task says otherwise:
`server/nest-cli.json`, `server/tsconfig*.json`, `client/vite.config.*`, etc.
### Runtime / Deploy Contract
- Tier 3 runtime/deploy outputs are first-class generation targets and must be regenerated from the companion rules when they drift.
- Tier 4 support files are framework-managed rather than hand-authored sources of truth.
- Runtime/deploy readiness is part of completion, not an optional follow-up.
## Approved Stack Version Policy
Future full-regeneration runs must normalize scaffolded package manifests and runtime inputs to the approved versions below. Do not use `latest`, caret ranges, or unreviewed major bumps when the repository regenerates or repairs the stack.
Runtime baseline:
- Node.js: prefer the Node 22 LTS line; minimum approved version is `22.12.0`
- Package manager: `npm` only, with committed `package-lock.json` files; do not switch the repo to `pnpm`, `yarn`, or `bun`
Backend generation 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` exactly, kept on the same version
- `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`
Frontend generation 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`
Policy rules:
- When official CLIs scaffold newer dependency sets, repair the scaffold and then pin it back to the approved versions above before generation continues.
- `prisma` and `@prisma/client` must always stay on the same exact version.
- Do not upgrade Prisma from v6 to v7 as part of routine regeneration; treat that as a separate explicit migration task with updated prompts, runtime checks, and verification.
---
## Forbidden mutations during any generation run
**NEVER write to `*.dsl` files.**
They are read-only inputs. To change the API contract or domain model, edit `domain/*.api.dsl`
as a separate explicit task.
**NEVER manually edit files under `server/src/modules/` or `client/src/resources/`.**
To change generated code: update `domain/*.api.dsl` and regenerate.
**NEVER edit `server/prisma/schema.prisma` directly.**
It is LLM-generated from `domain/*.api.dsl` following `prompts/prisma-rules.md`.
---
## Multi-agent orchestration model
Full-generation runs use a parent-orchestrated, bounded multi-agent model.
The parent agent is the orchestrator/integrator. It is not the default broad
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
- accepting or rejecting generator outputs
- final integration
- validation
- final handoff to reviewer
Specialized generation agents:
- `generator_prisma` — schema/model generation only
- `generator_nest_resources` — NestJS resource modules only
- `generator_react_admin_resources` — React Admin resource UI only
- `generator_data_access` — frontend data-access seam only
The old universal `generator` agent is removed from the active orchestration
model and must not be used for full-generation workflows.
### Delegation order
Use agents in this order:
1. `explorer` for repository discovery, execution-path inspection, scaffold checks, and local seam tracing
2. `docs_researcher` for official documentation verification and version-sensitive framework behavior
3. parent contract freeze and shared scaffold/auth/runtime planning
4. specialized generators after contract freeze, in parallel when safe:
- `generator_prisma`
- `generator_nest_resources`
- `generator_react_admin_resources`
- `generator_data_access`
5. parent integration and validation
6. `reviewer` only at the final review stage
If a runtime does not expose named subagents, keep the same separation of
responsibilities inside one agent and preserve the same handoff boundaries.
### Write-zone ownership
Parent-only write zones:
- shared scaffold and framework repair surfaces
- `server/src/auth/`
- `client/src/auth/`
- `toir-realm.json`
- `docker-compose.yml`
- `server/Dockerfile`
- `client/Dockerfile`
- `client/nginx/default.conf`
- `server/docker-entrypoint.sh`
- `db-seed/Dockerfile`
- `db-seed/import.sh`
- `server/.env.example`
- `client/.env.example`
- shared integration seams and final validation outputs explicitly delegated by prompts
Specialized generator write zones:
- `generator_prisma`
- `server/prisma/schema.prisma`
- optional machine-readable schema summary or structured handoff artifact when the parent explicitly requests it
- `generator_nest_resources`
- `server/src/modules/**`
- backend registration touchpoints only when explicitly delegated by the parent contract
- `generator_react_admin_resources`
- `client/src/resources/**`
- frontend resource registration touchpoints only when explicitly delegated by the parent contract
- `generator_data_access`
- `client/src/dataProvider.ts`
- narrowly delegated frontend integration seams only when explicitly delegated by the parent contract
Specialized generators must not redesign shared auth, runtime, deploy, scaffold,
or platform seams outside their delegated zones.
### Contract freeze (required before specialized generation)
Before launching specialized generators, the parent must produce a normalized
structured handoff from the DSL and prompt contracts. This contract freeze is a
required protocol owned by the parent; it does not replace `domain/*.api.dsl`.
The frozen contract must cover, where relevant:
- entities
- fields
- scalar and enum types
- ids and composite keys
- relations
- enums
- endpoint conventions
- route and path conventions
- naming rules
- auth surface expectations
- validator and eval compatibility constraints
- allowed write-zones per generator
Specialized generators start only after the parent freezes this contract and
delegates a bounded write-scope.
### Acceptance protocol for generator outputs
Parent acceptance is explicit, never implicit. A delegated output is accepted
only if all of the following are true:
- only allowed zones were modified
- the frozen contract is respected
- there are no unauthorized cross-layer edits
- the output is integration-ready
- relevant validation or 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
- reject explicitly if the output is still not usable after that pass
- use manual fallback only after explicit rejection, never as a silent completion of half-finished delegated work
### Role guidance
- `explorer`
- use first for codebase discovery, file/symbol tracing, scaffold inspection, and local evidence gathering
- `docs_researcher`
- use for official documentation verification, framework semantics, and version-sensitive claims
- `generator_prisma`
- launch after contract freeze when schema/model artifacts need generation or repair
- `generator_nest_resources`
- launch after contract freeze when backend resource modules need generation or repair
- `generator_react_admin_resources`
- launch after contract freeze when frontend resource views and registrations need generation or repair
- `generator_data_access`
- launch after contract freeze when React Admin to backend integration seams need generation or repair
- `reviewer`
- use only after parent integration and validation, as the final correctness/security/test-gap review gate
### Documentation-first rule for parent planning
Before the parent designs or repairs framework-sensitive shared seams, it must
review current official documentation rather than relying on memory alone.
Use Context7 first for:
- React Admin authProvider and dataProvider expectations
- NestJS modules, controllers, providers, guards, and auth attachment patterns
- Prisma schema and relation behavior
- Vite, Docker, and nginx behavior relevant to scaffold/runtime work
- Keycloak, OIDC, JWT, and JWKS integration guidance when available
Use external web research only for current, unstable, or missing documentation
details. Parent auth, data-access, and runtime planning must not be done purely
from memory when framework-specific guidance matters.
---
## Generation workflow (required sequence)
0. For a repo-wide full regeneration driven by `prompts/general-prompt.md`, start from the Tier 1/Tier 2 contract without pre-existing Tier 3 app/runtime outputs. In that mode, `server/`, `client/`, `db-seed/`, and root runtime artifacts such as `docker-compose.yml` and `toir-realm.json` are recreated; they are not prerequisites.
1. Read `AGENTS.md` and `prompts/general-prompt.md`.
2. Run discovery first with `explorer` and verify framework-sensitive behavior with `docs_researcher` before designing shared seams.
3. Read the active `api API.<EntityName>` block + its DTOs + its enums from `domain/toir.api.dsl` (entity-scoped — do not inject the full DSL as a blob).
4. Load the companion rule files required for the active stage:
- `prompts/prisma-rules.md`
- `prompts/backend-rules.md`
- `prompts/frontend-rules.md`
- `prompts/auth-rules.md`
- `prompts/runtime-rules.md`
- `prompts/validation-rules.md`
5. Freeze a normalized structured contract and bounded write-zones before launching any specialized generator.
6. Verify or repair framework scaffolds before domain generation:
- official Nest CLI for backend workspace creation/repair
- official Vite React TypeScript CLI for frontend workspace creation/repair
- official Prisma CLI when Prisma initialization or repair is required
7. Parent generates shared auth platform skeleton and deploy/runtime skeleton per `prompts/auth-rules.md` and `prompts/runtime-rules.md`.
8. Launch specialized generators after contract freeze, in parallel when safe:
- `generator_prisma` for `server/prisma/schema.prisma`
- `generator_nest_resources` for backend resource modules
- `generator_react_admin_resources` for frontend resource modules
- `generator_data_access` for `client/src/dataProvider.ts`
9. Accept or reject each delegated output using the acceptance protocol above. Only after acceptance may the parent integrate results.
10. Refresh `api-summary.json` only when validation/tooling requires the auxiliary freshness artifact: `npm run generate:api-summary`.
11. Run: `node tools/validate-generation.mjs --artifacts-only`
12. Run: `npm run eval:generation`
13. Fix all failures before considering the task complete.
14. Hand the final integrated result to `reviewer` before claiming completion.
**Context budget rule:** Before generating any DTO or component, quote the field
definitions from the DSL api block verbatim, then generate from those quotes. This
prevents training-data contamination. See `prompts/general-prompt.md`.
---
## Type mappings
| DSL type | Prisma type | TS DTO type | React Admin component |
| --------- | ----------------------------- | ----------- | ----------------------------- |
| `uuid` | `String @id @default(uuid())` | `string` | `TextInput` / `TextField` |
| `string` | `String` | `string` | `TextInput` / `TextField` |
| `text` | `String` | `string` | `TextInput` / `TextField` |
| `integer` | `Int` | `number` | `NumberInput` / `NumberField` |
| `number` | `Float` | `number` | `NumberInput` / `NumberField` |
| `decimal` | `Decimal` | `string` | `NumberInput` / `NumberField` |
| `date` | `DateTime` | `string` | `DateInput` / `DateField` |
| `boolean` | `Boolean` | `boolean` | (appropriate boolean input) |
| enum name | enum name | `string` | `SelectInput` / `SelectField` |
---
## Naming conventions
Resource name (plural, kebab-case):
- `Equipment``equipment` (irregular — stays as-is)
- `EquipmentType``equipment-types`
- `RepairOrder``repair-orders`
- General: PascalCase → kebab-case → append `s` (or `es` if ends in `s`; irregular cases explicit)
Default sort field (when not declared in api.dsl):
Priority: `inventoryNumber` > `number` > `code` > `name` > primary key
---
## Verification gate (two-stage)
### Stage 1 — Structural gate
```
node tools/validate-generation.mjs --artifacts-only
```
Checks: scaffold/build readiness, required runtime/deploy artifact presence, api-summary freshness, auth seam contracts, realm structure, env/runtime contract, Docker/nginx/compose invariants, and whether build verification ran or was explicitly skipped.
This gate validates the post-generation repository state. It is not a prerequisite for the clean-slate start of a full regeneration run.
Full structural verification (requires installed `node_modules`):
```
node tools/validate-generation.mjs
```
### Stage 2 — Eval harness (Rule 6)
```
npm run eval:generation
```
Fixture-based semantic checks from `tools/eval/fixtures/`. Checks: DSL fidelity, CRUD method/path behavior, DTO field coverage and decorators, natural-key semantics, FK/reference wiring, Content-Range behavior, and React Admin UX/component invariants.
Reviewed eval fixtures are the authoritative semantic gate. They may be scaffolded from source-of-truth as a helper, but a full regeneration run must not auto-rewrite the committed eval corpus as part of step 0.
See `tools/eval/README.md` for fixture authoring and eval-driven development workflow.
**Generation is incomplete unless both stages pass.**
---
## Proven-Good Runtime References
Existing runnable runtime/deploy artifacts are baseline behavior, not disposable examples.
- Preserve repository-proven behavior in `docker-compose.yml`, `server/Dockerfile`, `client/Dockerfile`, `client/nginx/default.conf`, `server/.env.example`, and `client/.env.example` unless the DSL, prompt contract, or an explicit task requires a change.
- When these artifacts are regenerated, preserve still-valid production behavior such as SPA routing, `/api` proxying, external Keycloak, PostgreSQL topology, and container startup flow.
- Do not claim runtime/deploy readiness from file presence alone; these artifacts remain part of completion and verification.
## Prisma Migration Policy
Current repository policy:
- `server/prisma/schema.prisma` is generated from the DSL and is the immediate database contract for generation runs.
- Committed Prisma migrations are preferred but not currently required for every schema change.
- The current repository state is accepted temporary technical debt: when `server/prisma/migrations/` is absent, local/runtime flows may fall back to `prisma db push`; when migrations exist, runtime must use `prisma migrate deploy`.
Target policy:
- Every DSL-driven schema change should produce a reviewed committed migration under `server/prisma/migrations/`.
- Production/runtime execution should rely on `prisma migrate deploy` only, with the `db push` fallback removed after migration discipline is established.
## Pre-commit hook
Install with `npm run install-hooks`. The hook runs **both** the structural gate and
the eval harness before every commit. Commits are blocked when either fails.
---
## Auth and runtime defaults
Full auth contract: `prompts/auth-rules.md`
Working defaults (do not regress to localhost):
- Keycloak base: `https://sso.greact.ru`
- Realm/client: `toir` / `toir-frontend` / `toir-backend`
- Production frontend: `https://toir-frontend.greact.ru`
- CORS: `http://localhost:5173,https://toir-frontend.greact.ru`
---
## OpenRouter configuration
```
OPENAI_API_KEY=<openrouter-key>
OPENAI_BASE_URL=https://openrouter.ai/api/v1
OPENAI_MODEL=<model-id>
```
These variables are used by `tools/api-format-to-openapi/convert.mjs --mode llm`.
---
## Reading order for generation tasks
**Critical zone (load first, never drop):**
1. `AGENTS.md` (this file) — project governance, mutation boundaries, tier hierarchy
2. `prompts/general-prompt.md` — master orchestration prompt: mission, stage ownership, delegation model, completion criteria
3. `domain/toir.api.dsl §API.<EntityName>` — active api block only, plus its referenced DTOs and enums
**Companion zone (load when the matching stage is active):**
4. `prompts/prisma-rules.md` — Prisma schema generation details
5. `prompts/backend-rules.md` — NestJS generation details
6. `prompts/frontend-rules.md` — React Admin generation details
7. `prompts/auth-rules.md` — auth seam and realm requirements
8. `prompts/runtime-rules.md` — scaffold, env, and bootstrap requirements
9. `prompts/validation-rules.md` — success gate requirements
**Auxiliary zone (never authoritative):**
10. `api-summary.json` — optional inventory/freshness artifact for validators and supporting tooling; do not use it instead of the DSL
**Reference only (do not load proactively):**
- `domain/dsl-spec.md` — DSL syntax reference; load only if DSL is ambiguous
- `docs/generation-playbook.md` — step-by-step workflow reference
- `docs/future-work.md` — deferred items (Rules 7 and 8)