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>
2.5 KiB
2.5 KiB
WP-49 — OpenZaak zaken read seam (slice 1)
Status: done Phase: 9 — OpenZaak / ZGW integration
Why
The POC serves cases from local SQLite. To grow toward production it must be able to source them from a real ZGW backend (OpenZaak) without changing the frontend (BFF-lite, ADR-0001). The backend had no data-access abstraction to swap behind, no outbound HTTP, and no JWT. This is the first thin vertical slice: read-only zaken.
Read first
Decisions (pre-made, don't relitigate)
- OpenZaak's anti-corruption layer lives in the BFF, never the browser.
- Source selected by config (
Zgw:Enabled, default false) → POC still runs offline. - Each source maps into the existing
ApplicationSummaryDto→ no api-client drift, no FE change. - Fresh HS256 JWT per call (no refresh flow). Hand-rolled (no new NuGet).
IZaakSourceis sync (matches the endpoint + local store); OpenZaak source does sync-over-async.
Files
Data/IZaakSource.cs,Data/LocalZaakSource.csZgw/{ZgwOptions,ZgwTokenProvider,ZgwZaakMapper,OpenZaakZaakSource}.csProgram.cs(DI + resolveIZaakSourcein/admin/cases),appsettings.json(Zgwsection)- tests:
ZgwTokenProviderTests,ZgwZaakMapperTests,OpenZaakZaakSourceTests
Steps
- Extract the cases read into
IZaakSource;LocalZaakSourcedelegates toApplicationStore. - Build the
Zgw/client (options, JWT minter, ZGW→DTO mapper, paginating HTTP source). - Wire DI by config; refactor
/admin/casesto resolveIZaakSource. - Unit-test the minter, mapper, and source (fixtures + stub
HttpMessageHandler).
Acceptance criteria
/admin/casesserves identical DTOs viaLocalZaakSource(default, offline).OpenZaakZaakSourcefollows pagination, resolves+caches zaaktype labels, sends a Bearer token.- JWT verifies (HS256) with the required claims.
dotnet testgreen (142);npm run cigreen with no api-client drift (FE untouched).
Verification
cd backend && dotnet test; npm run ci; manual: /beheer/zaken still lists cases with Zgw:Enabled=false.
Out of scope
Create-zaak (WP-50), Documenten/DRC (WP-51), Notificaties (WP-52), real inbound OIDC/JWT, OpenZaak in docker-compose.
Risks
Sync-over-async blocks a thread under load if OpenZaak becomes the default → make the read path async then (noted at the call site).