The ACL was handed a pinned zaaktype URL (Acl__Defaults__ZaaktypeUrl) + informatieobjecttype URL. OpenZaak assigns those UUIDs at creation, so every stack had to seed the catalogus and then capture + inject the resulting URLs out of band (CI's run-domain-check.sh; the local local-seed→acl.env bootstrap from ADR-0020). Brittle, and a stale/placeholder URL failed opaquely (OpenZaak 400).
Now the ACL resolves them itself from OpenZaak's Catalogi API by stable business key:
No stack captures/injects a server-assigned URL any more — docker-compose.yml/.local.yml, run-domain-check.sh and local-seed all drop it; the local acl.env shrinks to a single line.
One thing S-27 can't remove (confirmed empirically during this work): OpenZaak validates the zaaktype field on zaak-create with Django's URLValidator and rejects a single-label host (http://openzaak:8000/… → zaaktype: bad-url). So the ACL's base URL must still point at a URL-valid host (a container IP); that base-URL injection from ADR-0020 stays (local acl.env now carries only it; CI keeps ACL_OPENZAAK_BASEURL). ADR-0021 records this.
docker compose up reaches green health — verified: fresh make local + make verify-local green with no zaaktype-URL injection; acl.env is base-URL-only.
Docs — ADR-0021 + demo-script S-27 note.
ADR added (ADR-0021).
Demo note appended.
Verification done locally
50 unit tests pass (resolver resolve/cache/retry-on-failure; gateway match/miss/blank-key; all AclService paths).
6 ACL integration tests pass against a live seeded OpenZaak — incl. resolving the zaaktype + Diploma iot by business key, and a clear error for an unknown identificatie.
Fresh make local + make verify-local: full flow (submit → werkbak → openbaar) green; acl.env = Acl__OpenZaak__BaseUrl only.
make lint clean; ACL mutation ratchet run locally (see checks).
Notes for reviewers
IZaakGateway gains two resolve methods; AclService depends on the new IZaaktypeCatalog (singleton, so the cache persists).
Supersedes the pinned-URL mechanism; ADR-0021 documents that ADR-0020's seed-env/entrypoint shim are simplified (base-URL only), not deleted, because of the URLValidator constraint above.
## What & why
The ACL was handed a **pinned zaaktype URL** (`Acl__Defaults__ZaaktypeUrl`) + informatieobjecttype URL. OpenZaak assigns those UUIDs at creation, so every stack had to seed the catalogus and then capture + inject the resulting URLs out of band (CI's `run-domain-check.sh`; the local `local-seed`→`acl.env` bootstrap from ADR-0020). Brittle, and a stale/placeholder URL failed opaquely (OpenZaak 400).
Now **the ACL resolves them itself** from OpenZaak's Catalogi API by stable business key:
- config `ZaaktypeIdentificatie` (`BIG-REGISTRATIE`) / `InformatieobjecttypeOmschrijving` (`Diploma`);
- a `CachedZaaktypeCatalog` resolves **lazily on first use** and caches (success only, so a pre-publish miss is retried — no startup ordering coupling);
- a clear "No published … found" error replaces the opaque placeholder 400.
Design in **ADR-0021** (proposed in #117).
Closes #113
Closes #117
## Consequences (the payoff)
No stack captures/injects a server-assigned URL any more — `docker-compose.yml`/`.local.yml`, `run-domain-check.sh` and `local-seed` all drop it; the local `acl.env` shrinks to a single line.
**One thing S-27 can't remove** (confirmed empirically during this work): OpenZaak validates the `zaaktype` field on zaak-create with Django's URLValidator and **rejects a single-label host** (`http://openzaak:8000/…` → `zaaktype: bad-url`). So the ACL's **base URL** must still point at a URL-valid host (a container IP); that base-URL injection from ADR-0020 stays (local `acl.env` now carries only it; CI keeps `ACL_OPENZAAK_BASEURL`). ADR-0021 records this.
## Definition of Done
- [x] Linked issues (#113 slice, #117 adr-proposal).
- [x] TDD — resolver + gateway-lookup unit tests, updated `AclService` tests (50 unit tests green).
- [x] Implementation makes them pass; refactor of both compose stacks + verify scripts follows.
- [x] Conventional Commits referencing #113.
- [ ] CI green — see below.
- [x] `docker compose up` reaches green health — verified: fresh `make local` + `make verify-local` green with **no zaaktype-URL injection**; `acl.env` is base-URL-only.
- [x] Docs — ADR-0021 + demo-script S-27 note.
- [x] ADR added (ADR-0021).
- [x] Demo note appended.
## Verification done locally
- **50 unit tests** pass (resolver resolve/cache/retry-on-failure; gateway match/miss/blank-key; all `AclService` paths).
- **6 ACL integration tests** pass against a live seeded OpenZaak — incl. resolving the zaaktype + Diploma iot by business key, and a clear error for an unknown identificatie.
- **Fresh `make local` + `make verify-local`**: full flow (submit → werkbak → openbaar) green; `acl.env` = `Acl__OpenZaak__BaseUrl` only.
- `make lint` clean; ACL mutation ratchet run locally (see checks).
## Notes for reviewers
- `IZaakGateway` gains two resolve methods; `AclService` depends on the new `IZaaktypeCatalog` (singleton, so the cache persists).
- Supersedes the pinned-URL mechanism; ADR-0021 documents that ADR-0020's `seed-env`/entrypoint shim are **simplified** (base-URL only), not deleted, because of the URLValidator constraint above.
The ACL now discovers its BIG zaaktype (by identificatie) and diploma
informatieobjecttype (by omschrijving) from OpenZaak's Catalogi API, instead of
being handed server-assigned URLs in config. A CachedZaaktypeCatalog resolves
lazily on first use and caches (success only, so a pre-publish miss is retried);
AclDefaults now carries ZaaktypeIdentificatie/InformatieobjecttypeOmschrijving.
Clear errors replace the opaque placeholder-URL 400. Unit tests cover the
resolver (resolve/cache/retry-on-failure) and the gateway lookups (match/miss).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Assert the gateway resolves the published BIG-REGISTRATIE zaaktype + Diploma
informatieobjecttype against a real seeded OpenZaak, and that an unknown
identificatie throws a clear error.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The ACL now discovers those URLs itself (S-27), so no stack captures/injects them:
docker-compose.yml/.local.yml carry ZaaktypeIdentificatie/InformatieobjecttypeOmschrijving
instead of placeholder URLs, run-domain-check.sh + local-seed stop emitting the URLs, and
the local acl.env shrinks to the OpenZaak base URL. That base URL injection stays: OpenZaak
rejects a single-label host on zaak-create (confirmed), so the ACL is still pointed at the
container IP. ADR-0021 + demo-script note.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Kills the survivors the new resolution code introduced: null Results (no "results"
in the response) must throw "none found" not NRE; a non-success catalogi response
must surface an error naming the resource. ACL mutation score 93.89% (break 90%).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The acceptance InMemoryZaakGateway now implements IZaakGateway's new
Resolve{Zaaktype,Informatieobjecttype}UrlAsync, and the "een zaak openen" step
configures the ACL by identificatie + points the fake's resolved zaaktype at the
scenario URL — the Release build (which compiles tests/acceptance) failed without
this. All 17 acceptance + 54 ACL unit tests green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
not
merged commit 5de8c1e292 into main2026-07-22 14:49:27 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
What & why
The ACL was handed a pinned zaaktype URL (
Acl__Defaults__ZaaktypeUrl) + informatieobjecttype URL. OpenZaak assigns those UUIDs at creation, so every stack had to seed the catalogus and then capture + inject the resulting URLs out of band (CI'srun-domain-check.sh; the locallocal-seed→acl.envbootstrap from ADR-0020). Brittle, and a stale/placeholder URL failed opaquely (OpenZaak 400).Now the ACL resolves them itself from OpenZaak's Catalogi API by stable business key:
ZaaktypeIdentificatie(BIG-REGISTRATIE) /InformatieobjecttypeOmschrijving(Diploma);CachedZaaktypeCatalogresolves lazily on first use and caches (success only, so a pre-publish miss is retried — no startup ordering coupling);Design in ADR-0021 (proposed in #117).
Closes #113
Closes #117
Consequences (the payoff)
No stack captures/injects a server-assigned URL any more —
docker-compose.yml/.local.yml,run-domain-check.shandlocal-seedall drop it; the localacl.envshrinks to a single line.One thing S-27 can't remove (confirmed empirically during this work): OpenZaak validates the
zaaktypefield on zaak-create with Django's URLValidator and rejects a single-label host (http://openzaak:8000/…→zaaktype: bad-url). So the ACL's base URL must still point at a URL-valid host (a container IP); that base-URL injection from ADR-0020 stays (localacl.envnow carries only it; CI keepsACL_OPENZAAK_BASEURL). ADR-0021 records this.Definition of Done
AclServicetests (50 unit tests green).docker compose upreaches green health — verified: freshmake local+make verify-localgreen with no zaaktype-URL injection;acl.envis base-URL-only.Verification done locally
AclServicepaths).make local+make verify-local: full flow (submit → werkbak → openbaar) green;acl.env=Acl__OpenZaak__BaseUrlonly.make lintclean; ACL mutation ratchet run locally (see checks).Notes for reviewers
IZaakGatewaygains two resolve methods;AclServicedepends on the newIZaaktypeCatalog(singleton, so the cache persists).seed-env/entrypoint shim are simplified (base-URL only), not deleted, because of the URLValidator constraint above.The acceptance InMemoryZaakGateway now implements IZaakGateway's new Resolve{Zaaktype,Informatieobjecttype}UrlAsync, and the "een zaak openen" step configures the ACL by identificatie + points the fake's resolved zaaktype at the scenario URL — the Release build (which compiles tests/acceptance) failed without this. All 17 acceptance + 54 ACL unit tests green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>