(llm-first): context budget, validation, and eval harness, orchestration general-prompt
This commit is contained in:
@@ -1,88 +1,147 @@
|
||||
# Backend Rules
|
||||
|
||||
The backend remains derived from `domain/*.dsl` inside the existing LLM-first pipeline. No compiler platform or generator engine is introduced.
|
||||
<!-- prompt-version: 2.0 -->
|
||||
<!-- applies-to: server/src/modules/, server/src/app.module.ts -->
|
||||
<!-- validated-by: tools/validate-generation.mjs §validateApiDslCoverage §validateNaturalKeyChecks -->
|
||||
|
||||
## Backend scaffold baseline
|
||||
Use this document during the **Backend** stage defined in `prompts/general-prompt.md`.
|
||||
|
||||
- Start backend initialization from the official NestJS CLI workspace, not from manually created files.
|
||||
- The backend must remain compatible with standard Nest workspace tooling such as `nest build` and `nest start`.
|
||||
- Preserve the core Nest workspace files generated by the CLI, especially:
|
||||
## Purpose
|
||||
|
||||
Generate NestJS CRUD artifacts that match the DSL contract exactly and remain compatible with a standard NestJS workspace.
|
||||
|
||||
## 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`
|
||||
- For domain resources, prefer official Nest CLI generation patterns for modules/controllers/services/resources and then adapt the generated code to Prisma and auth requirements.
|
||||
- Do not delete required Nest workspace files just because the LLM can inline a smaller custom structure.
|
||||
- If the workspace is degraded, repair it before generating domain code.
|
||||
|
||||
## Forbidden backend generation patterns
|
||||
Forbidden patterns:
|
||||
|
||||
- Do not bootstrap `server/` by hand-writing a pseudo-Nest project from memory.
|
||||
- Do not remove `tsconfig.json`, `tsconfig.build.json`, or `nest-cli.json` after generation.
|
||||
- Do not replace standard Nest package scripts with ad hoc commands that break `nest build` or `nest start`.
|
||||
- Do not continue CRUD generation on top of a degraded backend workspace without repairing the workspace first.
|
||||
- hand-written pseudo-Nest scaffolds
|
||||
- deleting required Nest config files after generation
|
||||
- replacing normal Nest build/start behavior with ad hoc scripts
|
||||
|
||||
## Domain-derived output
|
||||
|
||||
- `domain/*.dsl` is the source of truth for entities, fields, primary keys, foreign keys, and enums.
|
||||
- `domain-summary.json` is a derived artifact used to stabilize LLM generation and validation. It must never replace the DSL as the source of truth.
|
||||
- Each entity becomes:
|
||||
- a Prisma model
|
||||
- a NestJS module
|
||||
- a controller
|
||||
- a service
|
||||
- create/update DTOs
|
||||
|
||||
## DTO and Prisma mapping
|
||||
|
||||
- `decimal` -> Prisma `Decimal`, DTO/API `string`
|
||||
- `date` -> Prisma `DateTime`, DTO/API `string`
|
||||
- Enums remain string-valued in DTO/API contracts
|
||||
|
||||
## CRUD and natural-key invariants
|
||||
## 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 entities whose primary key is not `id`, the backend must map the real key to `id`.
|
||||
- Natural-key list/sort logic must never build ORM `orderBy` against a fake physical `id`.
|
||||
- For natural-key entities, map the real primary key to `id` in responses and sort translation.
|
||||
|
||||
## Service invariants
|
||||
## DTO Contract
|
||||
|
||||
- Never pass raw update DTOs into Prisma update `data`.
|
||||
- Remove `id`, the real primary key, and readonly fields from update payloads before calling Prisma.
|
||||
- Keep PrismaService lightweight:
|
||||
- `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.
|
||||
- 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 use `beforeExit`
|
||||
- do not add `beforeExit`
|
||||
|
||||
## Filtering contract
|
||||
List endpoint requirements:
|
||||
|
||||
- List endpoints must support React Admin query parameters:
|
||||
- `_start`, `_end`, `_sort`, `_order`
|
||||
- arbitrary field filters from query string
|
||||
- `q` for reference autocomplete search
|
||||
- String/text search filters may use `contains` with case-insensitive mode.
|
||||
- Foreign key filters must use exact-match semantics (no `contains` for FK scalar keys).
|
||||
- Enum filters must support both single and repeated query params:
|
||||
- `status=Draft`
|
||||
- `status=Draft&status=Approved`
|
||||
- Repeated enum params must map to Prisma `{ in: [...] }`.
|
||||
- Sorting must use real model scalar fields only; natural-key entities must not fallback to fake physical `id`.
|
||||
- accept React Admin query params: `_start`, `_end`, `_sort`, `_order`, `q`
|
||||
- set `Content-Range`
|
||||
- set `Access-Control-Expose-Headers: Content-Range`
|
||||
|
||||
## Reproducibility invariants
|
||||
Filtering rules:
|
||||
|
||||
- A freshly generated backend must be bootstrappable with ordinary Nest + Prisma commands from `prompts/runtime-rules.md`.
|
||||
- Missing TypeScript or Nest workspace config is a generation failure, not an acceptable simplification.
|
||||
- The baseline backend should fail only on missing runtime dependencies or env values, not because the Nest workspace itself is incomplete.
|
||||
- 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
|
||||
|
||||
## Recovery rule if backend workspace degraded
|
||||
Decimal and date handling:
|
||||
|
||||
- If required Nest scaffold files are missing or broken, restore the official workspace baseline before editing Prisma models, modules, controllers, services, or DTOs.
|
||||
- Treat workspace repair as higher priority than feature generation, because generated domain code on top of a broken workspace is invalid baseline output.
|
||||
- `decimal` writes: `new Prisma.Decimal(value)`
|
||||
- `decimal` reads: `.toString()`
|
||||
- `date` writes: `new Date(value)`
|
||||
- `date` reads: `.toISOString()`
|
||||
|
||||
## Backend auth defaults
|
||||
## Natural-Key Rules
|
||||
|
||||
- `GET` -> `viewer | editor | admin`
|
||||
- `POST`, `PATCH`, `PUT` -> `editor | admin`
|
||||
- `DELETE` -> `admin`
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user