From b30fa664d8c97519d075170db48925f981745a1a Mon Sep 17 00:00:00 2001 From: Niek Otten Date: Fri, 28 Aug 2026 13:40:01 +0200 Subject: [PATCH] feat(event-subscriber): accept partial_update as a register write (refs #153) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ACL upserts with PATCH, so every approval notification carries actie `partial_update`. Accepting it makes the INGEDIEND → INGESCHREVEN transition project. `update` stays accepted so a PUT-shaped write behaves the same; `destroy` deliberately does not — removing a registration from the public register is its own decision, not a side effect of this one. ADR-0030 records why the actie list is what it is. --- ...-0030-projection-sourced-from-the-register.md | 6 ++++++ .../EventSubscriber.Application/Notification.cs | 16 +++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/docs/architecture/adr-0030-projection-sourced-from-the-register.md b/docs/architecture/adr-0030-projection-sourced-from-the-register.md index 6bf0bb4..af3d9b6 100644 --- a/docs/architecture/adr-0030-projection-sourced-from-the-register.md +++ b/docs/architecture/adr-0030-projection-sourced-from-the-register.md @@ -34,6 +34,12 @@ notification points at. The projection is a cache of the register; ZGW is no lon as a kenmerk — so the record is read back through the ACL (`POST /register-records/read`). §8.1 applies to Objecten exactly as ADR-0028 established: the ACL is the only code that talks to it. +- The accepted acties are `create`, `update` and `partial_update`. The last one is not + defensive breadth: the ACL upserts with PATCH, and DRF routes a PATCH through the notifying + `update()` while naming the action `partial_update` — which is what Objecten publishes. So + every approval arrives as `partial_update`, and accepting only `create`/`update` drops the + one state change this slice exists to project. `destroy` is deliberately not accepted: + removing a registration from the public register is its own decision. - The record already carries `id`, `status` and `reference`, so the row is the record. The zaak-shaped surface goes: `IsZaakCreated`, `IsZaakStatusSet`, `ZaakUrl`, `ZaakId`, and `ToEntry`'s `Resource == "status"` inference are replaced by `IsRegisterRecordWritten` + diff --git a/services/event-subscriber/EventSubscriber.Application/Notification.cs b/services/event-subscriber/EventSubscriber.Application/Notification.cs index b04672a..5a069ef 100644 --- a/services/event-subscriber/EventSubscriber.Application/Notification.cs +++ b/services/event-subscriber/EventSubscriber.Application/Notification.cs @@ -18,10 +18,20 @@ public sealed record Notification( string Actie, Uri ResourceUrl) { - /// A register record written to Objecten — create on submit, update on - /// approval, since the ACL upserts the same object for a registration (§8.6). + /// + /// A register record written to Objecten — create on submit and partial_update on + /// approval, since the ACL upserts the same object for a registration (§8.6). + /// + /// + /// partial_update is what a PATCH actually reports: DRF routes it through the notifying + /// update() but names the action partial_update, and that is what Objecten puts in + /// the notification. update is accepted too, so a PUT-shaped write would project the same + /// way. destroy is deliberately not: removing a registration from the public register is + /// its own decision, not a side effect of this one. + /// public bool IsRegisterRecordWritten => - Kanaal == "objecten" && Resource == "object" && Actie is "create" or "update"; + Kanaal == "objecten" && Resource == "object" + && Actie is "create" or "update" or "partial_update"; /// The object holding the register record. For a resource: object notification /// Objecten sends the object as both hoofdObject and resourceUrl — the object is