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>
3.0 KiB
WP-52 — OpenZaak Notificaties (NRC) live status
Status: done (c4dd846 endpoint, tests/docs/config finished this session)
Phase: 9 — OpenZaak / ZGW integration
Why
With cases in OpenZaak, case status changes in the backoffice, not in this app. Production "live" status needs the Notificaties API (NRC): subscribe to zaak events and update on webhook, rather than polling. Last slice of the ZGW integration arc.
Read first
- openzaak-integration.md
- WP-49/50/51 (the read/write/document slices this builds on)
Decisions (pre-made, don't relitigate)
- The BFF exposes a webhook endpoint that NRC calls; it validates an Authorization header the BFF issued, then invalidates any cached case data / notifies the FE.
- Subscription (
abonnementon thezakenkanaal) is provisioning/config, not runtime code. - FE update mechanism reuses the existing RemoteData reload — no new FE contract.
Files
- A new BFF webhook endpoint (
POST /zgw/notificaties) + Authorization validation. ZgwOptions:NrcBaseUrl+ the webhook shared secret.
Steps
- Add the webhook endpoint (auth-checked, no PII logged — reuse the audit seam).
- On a zaak event, invalidate cache / push an update to the FE.
- Document the
abonnementprovisioning (out-of-band, one-time).
Acceptance criteria
- A posted NRC event (correct auth) is accepted (204); a bad-auth post is rejected (401).
- No PII in the webhook logs (only kanaal/hoofdObject-URL/decision/role/correlationId).
- Tests cover auth accept/reject (
NotificatieTests.cs).
Verification
dotnet test (151/151 green, incl. 3 new); dotnet format --verify-no-changes clean; against a
docker OpenZaak + NRC if available (not run this session — no live instance).
Out of scope
Full event fan-out / real-time push infra beyond a simple cache-invalidation + reload. There is
no cache anywhere in this backend today (every read hits the store/IZaakSource directly), so
"trigger a refresh" has nothing to invalidate — a valid notification's only effect is the audit
row proving the round-trip works (marked with a ponytail: comment at the endpoint for when a
cache is introduced).
Risks
Webhook must be reachable from NRC in prod (network/ingress) — a deployment concern, not code.
Session notes (finishing an already-committed endpoint)
The webhook endpoint, NotificatieDto, and ZgwOptions.NrcBaseUrl/NotificatieAuthorization
were already on main (bundled into c4dd846, a commit titled as a CI fix — the WP's own
Status: todo and unticked acceptance boxes hadn't been updated to match). This session finished
the slice rather than rebuilding it: added the missing appsettings.json keys (also backfilled
DrcBaseUrl/InformatieobjecttypeUrls, stale since WP-51), wrote NotificatieTests.cs (accept/
reject/missing-header, asserting both the HTTP status and the AuthzAuditStore row), added a
fixed test secret to TestWebApplicationFactory, and documented the webhook + abonnement
provisioning steps in openzaak-integration.md.