Files
KIS-TOiR/generation/backend-generation.md

265 lines
6.8 KiB
Markdown

# Backend Generation Process
Backend generation follows a pipeline aligned with runtime, auth, and validation docs:
DSL
CLI scaffolding
backend code generation
auth generation
runtime infrastructure
database runtime
migration
seed
validation
Follow:
- `backend/architecture.md`
- `backend/runtime-rules.md`
- `backend/prisma-rules.md`
- `backend/prisma-service.md`
- `backend/database-runtime.md`
- `backend/seed-rules.md`
- `backend/service-rules.md`
- `auth/keycloak-architecture.md`
- `auth/backend-auth-rules.md`
- `auth/keycloak-realm-template-rules.md`
---
# Input Contract
Required input:
- `domain/*.dsl`
Optional extension input:
- `overrides/api-overrides.dsl`
Optional extension layout:
```text
overrides/
api-overrides.dsl
```
Rules:
- Parse `domain/*.dsl` as the only authoritative DSL input.
- Generate DTOs and REST API contracts automatically from the parsed domain model.
- The generator must work when `overrides/api-overrides.dsl` is absent.
- Optional overrides may refine derived API behavior but must not redefine entities, attributes, primary keys, foreign keys, relations, or enums.
- Supplemental DTO/API DSL inputs must not participate in backend parsing, dependency resolution, or backend generation decisions.
- Do not read standalone DTO or API DSL files.
---
# Step 1 — Parse Domain DSL
Read `domain/*.dsl` and extract:
- entities
- attributes, including the actual primary key attribute per entity
- enums
- foreign keys
All entities, attributes, primary keys, foreign keys, relations, and enums used by the backend pipeline must come from the parsed domain DSL.
If `overrides/api-overrides.dsl` exists, process it only after the domain model has been parsed and only as optional non-authoritative metadata.
The generator must treat auth as default runtime infrastructure, not as a DSL feature toggle.
---
# Step 2 — CLI scaffolding
Use official CLIs before generating backend code:
- NestJS project scaffold in `server/` (see `generation/scaffolding-rules.md`)
- install backend dependencies:
- `@prisma/client`
- `prisma`
- `@nestjs/config`
- `jose`
- seed runner when needed by the chosen package tooling
The generator must **not** use deprecated Keycloak-specific Node adapters such as `keycloak-connect`.
---
# Step 3 — Core backend code generation
Generate backend source artifacts:
1. **Prisma schema** (`server/prisma/schema.prisma`) from the domain DSL:
- attributes
- primary keys
- relations
- enums
2. **NestJS modules** per entity:
- module
- controller
- service
3. **DTO files**:
- `create-entity.dto.ts`
- `update-entity.dto.ts`
- `entity.response.dto.ts` (or equivalent)
4. **PrismaService**:
- implement `OnModuleInit`
- call `await this.$connect()` in `onModuleInit()`
- do not use a `beforeExit` hook
5. **Service update methods**:
- sanitize update payload before Prisma
- remove `id`, the entity primary key, and readonly attributes from `data`
- do not pass the raw request body directly to `prisma.*.update()`
6. **List/query sorting methods**:
- use only actual model field names in ORM `orderBy`
- if the API exposes synthetic `id` for React Admin but the real primary key is different, map incoming `_sort=id` to the real primary key field before building `orderBy`
- apply this rule to every entity with a non-`id` primary key
All backend DTOs and REST endpoints are derived artifacts. The generator must not require or parse separate DTO/API DSL documents.
Use mapping rules from `backend/prisma-rules.md`:
- DSL `decimal` -> DTO `string`
- DSL `date` -> DTO `string` (ISO)
---
# Step 4 — Backend auth generation
Generate auth infrastructure as part of the normal backend output. Auth must not be deferred to a manual post-step.
Required generated auth artifacts:
- `server/src/auth/auth.module.ts`
- JWT auth guard
- roles guard
- `@Public()` decorator
- `@Roles()` decorator
- typed authenticated principal interface
- typed auth-aware config validation in `server/src/config/`
JWT verification rules:
- verify JWTs with issuer, audience, and JWKS
- use a standards-based library such as `jose`
- resolve JWKS in this exact order:
1. explicit `KEYCLOAK_JWKS_URL`
2. OIDC discovery
3. `${issuer}/protocol/openid-connect/certs`
RBAC rules:
- extract authorization roles only from `realm_access.roles`
- do not infer roles from other claims
- apply CRUD defaults by HTTP method:
- `GET` -> `viewer`, `editor`, `admin`
- `POST`, `PATCH`, `PUT` -> `editor`, `admin`
- `DELETE` -> `admin`
- mark `/health` as public with `@Public()`
Controller generation rules:
- generated CRUD controllers must receive auth decorators by default
- path params must still use the actual entity primary key name (`:id`, `:code`, etc.)
- public routes must be explicit rather than implicit
---
# Step 5 — Runtime infrastructure
Generate backend runtime config files:
- `server/.env`
- `server/.env.example`
- `server/src/config/*` typed validation helpers
- `server/package.json` lifecycle:
- `"postinstall": "prisma generate"`
- `server/package.json` Prisma seed:
- `"prisma": { "seed": "ts-node prisma/seed.ts" }` (or `tsx` equivalent if that is the chosen project standard)
The generated backend env contract must include:
- `PORT`
- `DATABASE_URL`
- `CORS_ALLOWED_ORIGINS`
- `KEYCLOAK_ISSUER_URL`
- `KEYCLOAK_AUDIENCE`
- `KEYCLOAK_JWKS_URL` (optional)
Fail-fast config rule:
- backend startup must fail fast when required auth or database env vars are missing
- the generator must not silently fall back to production auth values in code
Commands that must be supported and documented:
- `npx prisma generate`
- `npx prisma migrate dev`
- `npx prisma db seed`
---
# Step 6 — Database runtime
Create `docker-compose.yml` at the **project root** with PostgreSQL only.
Minimum required compose characteristics:
- `services.postgres`
- `image: postgres:16`
- `ports: ["5432:5432"]`
Credentials and database name in compose must match `DATABASE_URL`.
Keycloak must remain an external runtime dependency and must not be added to `docker-compose.yml` in this repository.
---
# Step 7 — Migration
Apply schema to the development database:
```bash
cd server
npx prisma migrate dev
```
---
# Step 8 — Seed
Run development seed:
```bash
cd server
npx prisma db seed
```
Seed file location: `server/prisma/seed.ts`.
---
# Step 9 — Validation
Run runtime, auth, and contract checks from `generation/post-generation-validation.md`, including:
- docker-compose exists and DB container starts
- Prisma lifecycle commands succeed
- seed runs
- `/health` responds without auth
- protected routes reject unauthenticated requests with `401`
- authenticated users with insufficient role receive `403`
- React Admin-compatible API responses include `id` for every record
- natural-key entities translate React Admin `_sort=id` to the real primary key field