Local aanvraag/document writes and their paired ZGW writes aren't transactional; a ZGW failure after the local write succeeds used to diverge silently. ZgwHttpClient now retries transport-shaped failures (not 500, which can follow a partial commit on the non-idempotent statussen/rollen POSTs), and a ZGW failure that survives retry sets Aanvraag.ZgwError plus a zgw:divergence audit row instead of failing or diverging quietly. No outbox/reconcile job: three request-triggered write paths don't justify a persisted queue that would also need to carry citizen PII for the JWT audit claims. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2.9 KiB
WP-66 — Wire the decision into OpenZaak
Status: todo Phase: 11 — Behandelportal
Why
WP-65's decision currently only updates local state (LocalZaakSource). For the
behandelportal to actually function against a real register, the recorded decision needs
to also write a besluit/status transition to ZGW — extending the write capability that
already partially exists (CreateStatusRequest, CreateRolRequest in
OpenZaakZaakSource.cs) rather than building a new ZGW client from scratch.
Read first
backend/src/BigRegister.Api/Zgw/OpenZaakZaakSource.cs(existing write records)- ZGW's Besluiten API (referenced in
openzaak-integration.mdif covered, or the ZGW standard docs) for besluit creation - WP-50 (the first ZGW write slice, for the pattern to follow)
Decisions (pre-made, don't relitigate)
- Extend
IZaakSource/OpenZaakZaakSourcewith a besluit/status-transition write, following the same pattern WP-50 established for create-zaak (a records + mapper addition, not a new abstraction). - Gated by
Zgw:Enabledlike every other ZGW write — the behandelportal keeps working againstLocalZaakSourcewhen it's off. - Best done after Phase 10's WP-60 (write-divergence resilience) lands, since this is exactly the second write pair that resilience work should already cover — but not strictly blocked on it if Phase 10 is still in progress (call out the residual risk explicitly if shipped first).
Files
Zgw/OpenZaakZaakSource.cs (besluit/status write), Data/IZaakSource.cs (new write
method), tests.
Steps
- Add the besluit/status-transition write to
OpenZaakZaakSource, mirroring WP-50's create-zaak pattern. - Wire WP-65's decision command to call it when
Zgw:Enabled=true. - Integration test against the WP-54 harness (extend
OpenZaakIntegrationTests).
Acceptance criteria
- A recorded decision writes a real besluit/status transition to OpenZaak when
Zgw:Enabled=true. - Behandelportal still works unchanged against
LocalZaakSourcewhenZgw:Enabled=false. OpenZaakIntegrationTestscovers the new write.
Verification
cd backend && dotnet test --filter Category=Integration against the (ideally
Phase-10-hardened) OpenZaak harness; manual smoke with Zgw:Enabled=true.
Out of scope
Any further behandelportal screens beyond beoordeling.
Risks
WP-60 (write-divergence resilience) has landed: bounded retry lives in ZgwHttpClient, so
this write pair inherits it automatically. It does not get the flagging half for free —
call RecordZgwDivergence (or the equivalent for whichever endpoint hosts the besluit write) on
this path's catch too, the same way Program.cs's submit endpoint does for create-zaak/document
writes, or this becomes the "second, currently-unprotected write pair" WP-60's own scope note
anticipated.
Depends on: WP-65.