feat(zgw): docker OpenZaak integration-test harness (WP-54)
Opt-in docker-compose (postgres+redis+OpenZaak, no celery/nginx) + bootstrap-catalogus.sh seed a real OpenZaak instance; OpenZaakIntegrationTests (Category=Integration, excluded from default dotnet test/CI) proves the ZGW seam against it for the first time. That live run caught a real bug: ZgwHttpClient never sent Content-Crs/Accept-Crs headers, so every write would 412 against a spec-compliant OpenZaak — fixed alongside the harness. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -101,7 +101,11 @@ confidentiality level would matter for production but isn't needed to prove the
|
||||
`user_representation`). No refresh flow — OpenZaak expires tokens 1h past `iat`, so per-call
|
||||
minting is the recommended pattern. Hand-rolled (no `Microsoft.IdentityModel.*` dependency).
|
||||
- `ZgwHttpClient.cs` — shared GET/POST-with-bearer-JWT plumbing used by both
|
||||
`OpenZaakZaakSource` and `OpenZaakDocumentSource`.
|
||||
`OpenZaakZaakSource` and `OpenZaakDocumentSource`. Every request also carries
|
||||
`Accept-Crs`/`Content-Crs: EPSG:4326` — every ZGW call must declare a coordinate reference
|
||||
system even when no geometry is involved, or a real OpenZaak 412s ("Content-Crs header
|
||||
ontbreekt"). This was missing until WP-54's live harness caught it — the stub-handler tests
|
||||
never modelled the header, so it had shipped silently since WP-49/50.
|
||||
- `ZgwZaakMapper.cs` — the anti-corruption map: ZGW Zaak → `ApplicationSummaryDto`. This is
|
||||
where **URL identity** becomes the trailing uuid and the **zaaktype URL** is resolved to a
|
||||
human label (the cross-service join).
|
||||
@@ -204,6 +208,22 @@ FE or the contract. Watch the **sync-over-async** `ponytail:` note in `OpenZaakZ
|
||||
its `OpenZaakDocumentSource` sibling) — make the read/write paths async if OpenZaak becomes the
|
||||
default.
|
||||
|
||||
## Run against real OpenZaak (WP-54)
|
||||
|
||||
Everything above was, until WP-54, only proven against fixtures + a stub `HttpMessageHandler` —
|
||||
no live OpenZaak. `backend/openzaak/` is a **separate**, opt-in docker-compose harness (never
|
||||
merged into the root `docker-compose.yml`, which stays FE+BFF-only) that brings up a real
|
||||
OpenZaak, seeds a minimal catalogus/zaaktype/zaak via a bootstrap script, and backs one
|
||||
xunit test (`OpenZaakIntegrationTests.cs`, tagged `Category=Integration`) that points the BFF at
|
||||
it with `Zgw:Enabled=true`. See `backend/openzaak/README.md` for the exact commands; the test is
|
||||
excluded from the default `dotnet test` run and from CI (`--filter Category!=Integration`) since
|
||||
it only passes with the harness up.
|
||||
|
||||
This is also where the `Content-Crs`/`Accept-Crs` header gap above was found: a real OpenZaak
|
||||
enforces ZGW's geo-header requirement in a way no stub-based test could catch, since a stub
|
||||
never rejects an unexpected (or missing) header. That is the harness's whole point — proving
|
||||
the seam against real protocol behaviour, not just the shapes we already assumed.
|
||||
|
||||
## Config
|
||||
|
||||
```jsonc
|
||||
@@ -270,15 +290,16 @@ Caveat: `IZaakSource` covers the cases **read (admin + citizen-scoped) + create*
|
||||
(WP-49/50/53), `IDocumentSource` covers **upload + zaak-link** (WP-51), the inbound
|
||||
`POST /zgw/notificaties` webhook (WP-52) closes the read/write/document/notify arc, and WP-53
|
||||
threaded a real per-request `CallerIdentity` through all of it (ownership + the ZGW audit
|
||||
claims). Other BFF endpoints (reference data like `SeedData`'s BRP/DUO mimics) still read static
|
||||
stores directly — ACL-ready (the DTO seam exists) but not yet swappable, and not part of this
|
||||
arc. What's left is **WP-54**: a docker OpenZaak harness + opt-in integration test — today
|
||||
everything is fixture/mock-tested against no live instance.
|
||||
claims), and WP-54 added a docker OpenZaak harness + opt-in integration test proving the seam
|
||||
against a live instance (and, in doing so, caught the missing `Content-Crs`/`Accept-Crs`
|
||||
headers noted above). Other BFF endpoints (reference data like `SeedData`'s BRP/DUO mimics)
|
||||
still read static stores directly — ACL-ready (the DTO seam exists) but not yet swappable, and
|
||||
not part of this arc. That closes the phase-9 OpenZaak/ZGW arc (WP-49..54).
|
||||
|
||||
## See also
|
||||
|
||||
- [ADR-0005 — OpenZaak behind the BFF](architecture/0005-openzaak-behind-bff.md) — the decision.
|
||||
- [ADR-0001 — BFF-lite + decision DTOs](architecture/0001-bff-lite-decision-dtos.md) — why the FE doesn't change.
|
||||
- [WP-49](../project/backlog/WP-49-openzaak-zaken-read-seam.md) (this), WP-50/51 (CRUD arc so far), WP-52 (notificaties), WP-53 (identity seam + citizen-scoping), WP-54 (integration harness, open).
|
||||
- `backend/src/BigRegister.Api/Zgw/` — the client; `Data/IZaakSource.cs`/`Data/IDocumentSource.cs` — the seams.
|
||||
- [WP-49](../project/backlog/WP-49-openzaak-zaken-read-seam.md) (this), WP-50/51 (CRUD arc so far), WP-52 (notificaties), WP-53 (identity seam + citizen-scoping), [WP-54](../project/backlog/WP-54-openzaak-integration-harness.md) (integration harness).
|
||||
- `backend/src/BigRegister.Api/Zgw/` — the client; `Data/IZaakSource.cs`/`Data/IDocumentSource.cs` — the seams; `backend/openzaak/` — the live-OpenZaak test harness (WP-54).
|
||||
- [ZGW standard (VNG)](https://vng-realisatie.github.io/gemma-zaken/) · [OpenZaak auth docs](https://open-zaak.readthedocs.io/en/stable/client-development/authentication.html).
|
||||
|
||||
Reference in New Issue
Block a user