docs: archive the finished backlogs (RD-30)

Two backlog trees are complete: `docs/project/backlog/` (75 files, every
WP done) and `docs/project/refactor-backlog-setup/` (the arc before it).
Move both under `docs/project/archive/` with `git mv`, so history stays
intact through `git log --follow`. `SHOWCASE-ROADMAP.md` moves with them,
because it points at the now-archived backlog README.

Add `docs/project/archive/README.md`. It states that these trees are
historical and names the two directories that are still live.

Repoint every inbound reference named in RD-30's Files table: CLAUDE.md,
the root README, both backend READMEs, `LetterHtml.cs`, `a11y.mdx`, the
`document-feature` and `new-ssp` skills, and the readable-codebase PLAN,
README, and RD-19 ticket. Fix two upward-relative links inside the moved
WP files (WP-68, WP-69) that gained a directory level and would otherwise
break. Repoint `.prettierignore`'s two agent-prompt exclusions to their
new path, so prettier keeps leaving those files' exact wording alone.

Mark RD-30 done and check off its acceptance criteria; flip its README
row to done.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
eho
2026-09-08 23:00:38 +02:00
co-authored by Claude Opus 5
parent 097e8468e0
commit 12f17d9d73
161 changed files with 154 additions and 24 deletions
@@ -0,0 +1,79 @@
# WP-03 — Boundaries I: contracts purity + ApiClient confinement
Status: done (f9b76e7)
Phase: 0 — enforcement & gates
## Why
`contracts/` is the FE⇄BE wire seam and must import **nothing** (CLAUDE.md §1,
ADR-0001) — but `registratie/contracts/dashboard-view.dto.ts` imports domain types, and
`change-request-form.component.ts` injects `ApiClient` straight into UI. Neither rule is
lint-enforced. Rule + fixes land together so this WP ends green.
## Read first
- `CLAUDE.md` §1 + §4 (layers, BFF-lite)
- `eslint.config.mjs` (existing zone style to extend)
- `src/app/registratie/contracts/dashboard-view.dto.ts`
- `src/app/registratie/infrastructure/dashboard-view.adapter.ts`
- `src/app/registratie/ui/change-request-form/change-request-form.component.ts` (~line 53)
- `src/app/registratie/application/submit-change-request.ts`
- `src/app/shared/infrastructure/role.ts` and `src/app/brief/ui/letter-composer/letter-composer.component.ts` (line 2)
## Decisions (pre-made, don't relitigate)
- Wire DTOs express enums as plain string-literal unions **inlined in the DTO file**
they describe the wire, not the domain. The adapter's `parse*` maps them to domain types.
- The `Role` **type** moves out of infrastructure (to `shared/domain` or
`shared/application` — pick where its current consumers point most naturally); the
role-reading mechanism (`role.interceptor.ts` etc.) stays infrastructure.
## Files
- `eslint.config.mjs` — two new restrictions
- `src/app/registratie/contracts/dashboard-view.dto.ts` — remove domain imports
- `src/app/registratie/infrastructure/dashboard-view.adapter.ts` — absorb the mapping
- `src/app/registratie/ui/change-request-form/change-request-form.component.ts` — stop
injecting `ApiClient`; the component calls the application command, which owns the
client dependency (move the `inject` into `submit-change-request.ts` or a thin
registratie adapter, matching how other commands get the client)
- `src/app/shared/infrastructure/role.ts` + new home for the `Role` type + the
`letter-composer.component.ts` / `brief.store.ts` import sites
## Steps
1. Rewrite `dashboard-view.dto.ts` as pure wire shapes (no imports at all); update the
adapter's `parse*`/`toDomain` to map wire → domain; run the adapter spec.
2. Move the `Role` type; update import sites (mechanical; lint will find them).
3. Refactor change-request-form: UI keeps dispatching to the machine; the submit command
receives/owns the `ApiClient` (pattern: other `submit-*.ts` commands).
4. Add eslint zones:
- `src/app/**/contracts/**` may import nothing from `@angular/*`, any `@*` context
alias, or relative app code.
- `@shared/infrastructure/api-client` importable only from `**/infrastructure/**`
(+ the app config/provider and the generated file itself).
5. Lint the repo; there must be zero new disables.
## Acceptance criteria
- [x] `dashboard-view.dto.ts` has no import statements.
- [x] No value import of `@shared/infrastructure/api-client` outside `infrastructure/`
(the only remaining non-infra reference is draft-sync's type-only DTO import,
allowed by `allowTypeImports`). ApiClient confinement is lint-enforced.
- [x] Both eslint rules active; planted violations fail lint (contracts→domain,
UI→ApiClient value); type-only DTO import still passes.
- [x] Change-request flow works — verified end-to-end in the running app (submit →
command → adapter → backend → reference `BIG-2026-…`, success alert); specs green.
## Verification
GREEN + `npm run test-storybook:ci`. Manual smoke: `npm start` → Gegevens wijzigen →
submit a change request.
## Out of scope
The `ui ↛ infrastructure` rule for adapter injections in wizards — that's WP-04.
## Risks
Role-type move ripples through brief imports — mechanical; run tests before/after.