Counting the `versions` URLs assumed a contiguous, all-published list. Read the
objecttype's versions collection instead and take the highest one whose status
is `published`, so a draft version — whose schema is still being shaped — is
never written against.
ApproveZaakAsync now does two writes: the ZGW eindstatus (the process) and the
register record in Objecten (the register). The record is keyed on the zaak
UUID — the same key the read projection rows carry — and its reference is the
zaak's identificatie, so nothing personal crosses into the world-readable
register (ADR-0027).
ObjectenGateway resolves the objecttype by name (its URL and version are
assigned at seed time, as with ADR-0021), searches for an existing object by
data attribute, then POSTs or PATCHes. Resolution is lazy, so the ACL needs no
depends_on on Objecten and does not crash-loop when it boots first.
Ports and failing tests for the Objecten hop, ahead of the implementation:
- IRegisterRecordGateway + RegisterRecord — the Application-side port; the
record mirrors the objecttype schema registered in S-18c (ADR-0027).
- AclService takes the port but does not yet call it, so the approval test
fails on an empty upsert list.
- ObjectenGateway is a shell throwing NotImplementedException; its tests pin
the contract: resolve the objecttype by name, search by data attribute,
POST when absent / PATCH when present, static Token auth per API, the CRS
headers the geo API requires, and a surfaced error body.
Also splits S-19 (#20) into #149/#150 in BACKLOG.md — the approval-side write
and the projection re-sourcing are independently deployable (CLAUDE.md §13).