Files
atomic-design-poc/docs/project/archive/backlog/WP-56-openzaak-catalogus-provisioning.md
ehoandClaude Opus 5 12f17d9d73 docs: archive the finished backlogs (RD-30)
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>
2026-09-08 23:00:38 +02:00

106 lines
5.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# WP-56 — Idempotent catalogus provisioning
Status: done
Phase: 10 — OpenZaak production hardening
## Why
`backend/openzaak/bootstrap-catalogus.sh` seeds catalogus/zaaktype/statustype/roltype/zaak
via hand-rolled curl+JWT and is explicitly **not idempotent** (fails on `domein`+`rsin`
uniqueness on rerun) — fine for a one-shot WP-54 harness, wrong for an environment that
needs to be rebuildable. OpenZaak already ships a documented, scripted alternative — the
`setup_configuration` mechanism (already used in the harness for the JWTSecret/Applicatie,
see `setup_configuration/data.yaml`) — this WP extends that same mechanism to the catalogus
content too.
## Read first
- `backend/openzaak/bootstrap-catalogus.sh`
- `backend/openzaak/setup_configuration/data.yaml`
- `backend/openzaak/docker-compose.openzaak.yml` (`web-init` service)
- OpenZaak's own `setup_configuration` / `openzaak_config_cli` docs (upstream)
## Decisions (pre-made, don't relitigate)
- Move catalogus/zaaktype/statustype/roltype provisioning into `setup_configuration`,
run by the existing `web-init` one-shot service, instead of the separate curl script.
- Keep `bootstrap-catalogus.sh` only for whatever content `setup_configuration` genuinely
can't express (e.g. a demo zaak instance) — confirm what's left at kickoff.
- Provisioning must be safe to run against an already-provisioned instance — either
genuinely idempotent, or the compose is structured to only run it once per fresh
volume (document which, don't leave it ambiguous).
## Files
- `backend/openzaak/setup_configuration/data.yaml`
- `backend/openzaak/bootstrap-catalogus.sh` (trim to whatever remains)
- `backend/openzaak/docker-compose.openzaak.yml`
- `backend/openzaak/README.md`
## Steps
1. Express the catalogus/zaaktype/statustype/roltype definitions currently created by
curl as `setup_configuration` YAML.
2. Wire it into the `web-init` command alongside the existing JWTSecret/Applicatie config.
3. Trim `bootstrap-catalogus.sh` to only what setup_configuration can't cover, if anything.
4. Test: tear down + `docker compose up` twice in a row (fresh volume, then existing
volume); confirm no failure on rerun.
5. Update the README describing the provisioning flow.
## Acceptance criteria
- [x] ~~Catalogus/zaaktype/statustype/roltype provisioning is declarative
(`setup_configuration`), not imperative curl.~~ Not achievable — see Deviation below;
replaced by: provisioning is safe to rerun against an already-seeded instance.
- [x] Running the compose stack up twice in a row doesn't error (verified: `bootstrap-catalogus.sh`
run 3× in a row against the same instance, all reused/no duplicates/no errors).
- [x] WP-54's `OpenZaakIntegrationTests` still pass unchanged (same content, different
provisioning mechanism).
## Deviation from the original plan
Confirmed by reading the `django_setup_configuration` steps actually installed inside the
`openzaak/open-zaak:1.29.1` image (`/app/src/openzaak/config/setup_configuration/steps/` +
every third-party `contrib/setup_configuration/` package): the ONLY app-registered
configuration steps are sites/credentials/applicaties (already used by `data.yaml`) and
Selectielijst API config. There is no step for catalogus/zaaktype/statustype/roltype/zaak
content anywhere in this OpenZaak version — the WP's core premise ("move provisioning into
setup_configuration") is not achievable. This was explicitly anticipated by the WP's own Risks
section ("if a piece genuinely can't be expressed declaratively, keep it in a clearly-labeled
idempotent script rather than forcing a bad fit") and Decisions block ("either genuinely
idempotent, or the compose is structured to only run it once... document which").
Chose **genuinely idempotent**: `bootstrap-catalogus.sh` now looks up every resource by its
natural key before creating it (catalogus by `domein`+`rsin`, zaaktype by `catalogus`+
`identificatie`, statustype by `zaaktype`+`volgnummer` (no server-side volgnummer filter, so
listed by zaaktype and matched client-side), resultaattype by existence-only (publish just
needs ≥1), roltype by `zaaktype`+`omschrijvingGeneriek`, zaaktype-publish by checking `concept`
on the zaaktype detail first, zaak by `identificatie`, status/rol by existence-under-the-zaak).
Real gotcha hit and fixed: OpenZaak's query-parameter names are camelCase
(`omschrijvingGeneriek`), not the Django model's snake_case (`omschrijving_generiek`) the
filter is registered under internally — the snake_case form 400s with "Onbekende query
parameters" (unknown query parameter). Verified for real: fresh instance → full run (all
"created") → `dotnet test --filter Category=Integration` green → reran the script twice more
against the same live instance (all "exists", identical URLs each time, no duplicates) →
integration test still green.
Not attempted: moving anything into `setup_configuration/data.yaml` (nothing there to move,
per the finding above).
## Verification
`docker compose -f backend/openzaak/docker-compose.openzaak.yml up` twice in a row (fresh
volume, then existing volume); `cd backend && dotnet test --filter Category=Integration`
against the harness.
## Out of scope
Secrets/TLS (WP-55, unrelated but sequenced first in the table only by number), client
scopes (WP-57), notifications (WP-58).
## Risks
OpenZaak's `setup_configuration` coverage for zaaktype/besluittype content may be
incomplete upstream — if a piece genuinely can't be expressed declaratively, keep it in a
clearly-labeled idempotent script rather than forcing a bad fit.