Files
atomic-design-poc/.claude/skills/new-feature/SKILL.md
Edwin van den Houdt cf44bda0ce
Some checks failed
CI / frontend (push) Successful in 2m16s
CI / storybook-a11y (push) Successful in 4m6s
CI / backend (push) Failing after 48s
CI / api-client-drift (push) Successful in 1m32s
docs(skills): extract house recipes as Claude Code skills for SSP templating
8 template-generic skills in .claude/skills/ (new-feature, new-context,
value-object, form-machine, bff-endpoint, mutation-command, ui-component,
new-ssp), condensed from CLAUDE.md/ARCHITECTURE/fp-tea/ADRs and pointing at
this repo's worked examples. CLAUDE.md gains a pointer.

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

2.3 KiB

name, description
name description
new-feature 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)

npm run lint && npm run check:tokens && npm test && npm run build
cd backend && dotnet test   # if the backend changed