fix(infra): address Objecten by a dotted host so NRC accepts its notifications (refs #152)
CI / build (pull_request) Successful in 1m9s
CI / lint (pull_request) Successful in 1m24s
CI / unit (pull_request) Successful in 1m32s
CI / frontend (pull_request) Successful in 3m13s
CI / mutation (pull_request) Successful in 6m25s
CI / verify-stack (pull_request) Failing after 8m11s

The worker published and NRC answered 400 on every message:

  {"hoofdObject":["Voer een geldige URL in."],"resourceUrl":["Voer een geldige URL in."]}

NRC types both as DRF `URLField`, and Django's URLValidator refuses a single-label host.
Objecten fills them from the object `url` DRF built with `request.build_absolute_uri` —
the Host the *caller* used — so `SITE_DOMAIN` never entered into it. Dropped that env pair;
it was a wrong guess at the mechanism.

The fix is on the caller side: keep the `objecten.local` network alias and point every
writer whose writes must be notified at it — the ACL, the gateway integration tests, and
this slice's verify driver. Readers keep the plain service name.

ADR-0029 updated with the real mechanism and the ceiling it leaves: a new writer using
`objecten:8000` gets a 201 and silently no notification.
This commit is contained in:
not
2026-08-28 11:31:31 +02:00
parent 448896206f
commit d76abf2df2
5 changed files with 50 additions and 34 deletions
+8 -8
View File
@@ -341,7 +341,8 @@ services:
# Objecten holds the register, OpenZaak holds the process (S-19a, ADR-0028). Both APIs take a
# static token, not a ZGW JWT. The objecttype URL is assigned at seed time, so the ACL resolves
# it by name — lazily, on the first approval, so no depends_on is needed here.
Acl__Objecten__BaseUrl: http://objecten:8000/
# Dotted host on purpose — see the `objecten.local` alias below (ADR-0029).
Acl__Objecten__BaseUrl: http://objecten.local:8000/
Acl__Objecten__Token: ${OBJECTEN_TOKEN:-1234567890abcdef1234567890abcdef12345678}
Acl__Objecten__ObjecttypenBaseUrl: http://objecttypen:8000/
Acl__Objecten__ObjecttypenToken: ${OBJECTTYPEN_TOKEN:-0123456789abcdef0123456789abcdef01234567}
@@ -691,13 +692,6 @@ services:
CACHE_AXES: objecten-redis:6379/0
DISABLE_2FA: "true"
OTEL_SDK_DISABLED: "true"
# NRC validates hoofdObject/resourceUrl with Django's URLValidator, which rejects a
# single-label host — so notifications built from `objecten:8000` are refused with
# "Voer een geldige URL in." SITE_DOMAIN fixes the host Objecten puts in its notifications
# (objects.utils.get_domain), and the `objecten.local` network alias below keeps that host
# resolvable in-network so a subscriber can actually fetch the record it points at (S-19b-2).
SITE_DOMAIN: objecten.local:8000
IS_HTTPS: "no"
CELERY_BROKER_URL: redis://objecten-redis:6379/1
CELERY_RESULT_BACKEND: redis://objecten-redis:6379/1
# Publish register-record events to NRC on the `objecten` kanaal (S-19b-1, ADR-0029). The NRC
@@ -735,6 +729,12 @@ services:
condition: service_completed_successfully
networks:
cg:
# Objecten reflects the *request* Host into the `url` it returns, and
# notifications_api_common publishes that url as the notification's hoofdObject /
# resourceUrl — which NRC types as a URLField, and Django's URLValidator rejects a
# single-label host ("Voer een geldige URL in."). So every caller whose writes must be
# notified addresses Objecten by this dotted alias instead of `objecten` (ADR-0029).
# Reads are unaffected and still use the plain service name.
aliases:
- objecten.local