---
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
```
