Files
Edwin van den Houdt e82309786d style: format frontend, docs and skills with prettier; add .prettierignore
One-time prettier --write so the new format:check CI gate starts green.
.prettierignore excludes generated (api-client.ts, documentation.json),
vendored (public/cibg-huisstijl), and backend (dotnet format owns it).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 13:39:31 +02:00

47 lines
2.3 KiB
Markdown

---
name: new-feature
description: Add a feature (screen, flow, capability) to this Angular SSP following the house pipeline — domain first, then infrastructure, application, UI last. Use whenever building anything user-facing that has business rules or data.
---
# New feature (the pipeline)
Every feature is built inward-out. Never start with the component.
## Steps
1. **Domain** (`<context>/domain/`, pure TS, no Angular imports — lint-enforced)
- Data types + pure rules. Forms/wizards get a `*.machine.ts` → use the **form-machine** skill.
- Raw input that must be valid → branded value object → use the **value-object** skill.
- Co-locate a `.spec.ts`; test the pure functions directly, no TestBed.
- Server-owned rules stay here only as reference impl + test, marked server-owned; the FE renders the server's decision (ADR-0001).
2. **Infrastructure** (`<context>/infrastructure/`, the only layer that touches HTTP)
- Read → screen-shaped endpoint + adapter → use the **bff-endpoint** skill.
- Write → command adapter returning `Result` → use the **mutation-command** skill.
3. **Application** (`<context>/application/`)
- Shared cross-page state → `providedIn: 'root'` store exposing `RemoteData` signals.
- Page-local flow state → `createStore(initial, reduce)` from `@shared/application/store`, held in the component.
- Side effects live in commands (`submit-*.ts`), never in the reducer.
4. **UI last** (`<context>/ui/`)
- A page is **composition of existing blocks**`<app-page-shell>`, `<app-async>`, atoms/molecules from `shared/ui`. Adding a new building block is the exception → **ui-component** skill.
- Templates dispatch messages, never mutate. Async data always renders through `<app-async>`.
- All copy via `$localize` with stable `@@context.key` ids.
- Route: lazy `loadComponent` under the `ShellComponent` parent in `app.routes.ts`, `canActivate: [authGuard]` when protected.
## Worked example
The intake wizard slice, end to end:
- `src/app/herregistratie/domain/intake.machine.ts` (+ spec)
- `src/app/herregistratie/infrastructure/`
- `src/app/herregistratie/ui/` (wizard component + page)
## Verify (GREEN gate)
```bash
npm run lint && npm run check:tokens && npm test && npm run build
cd backend && dotnet test # if the backend changed
```