refactor(event-subscriber): drop the hoofdObject fallback (refs #153)
CI / build (pull_request) Successful in 1m11s
CI / lint (pull_request) Successful in 1m25s
CI / unit (pull_request) Successful in 1m27s
CI / frontend (pull_request) Successful in 3m5s
CI / mutation (pull_request) Successful in 6m7s
CI / verify-stack (pull_request) Failing after 11m42s

For a `resource: object` notification Objecten sends the object as both hoofdObject and
resourceUrl — the object *is* the main resource — so `HoofdObject ?? ResourceUrl` was a
branch that can never take its left side and that no test could distinguish. It came across
from the zaken path, where hoofdObject genuinely differed (the zaak behind a status).

Tests unchanged and green.
This commit is contained in:
not
2026-08-28 12:38:27 +02:00
parent 88a601123b
commit b496ac9477
4 changed files with 12 additions and 11 deletions
@@ -84,11 +84,12 @@ app.MapPost("/admin/rebuild", async (NotificationProjector projector, Cancellati
await app.RunAsync(); await app.RunAsync();
/// <summary>The NRC notification body, as Open Notificaties POSTs it. Only the fields the /// <summary>The NRC notification body, as Open Notificaties POSTs it. Only the fields the projector
/// projection needs are bound; <c>aanmaakdatum</c>/<c>kenmerken</c> are ignored for the minimal slice.</summary> /// needs are bound; <c>aanmaakdatum</c>, <c>kenmerken</c> and <c>hoofdObject</c> are ignored for a
public sealed record NotificationDto(string Kanaal, string Resource, string Actie, Uri ResourceUrl, Uri? HoofdObject = null) /// register write hoofdObject is the same object as resourceUrl (ADR-0030).</summary>
public sealed record NotificationDto(string Kanaal, string Resource, string Actie, Uri ResourceUrl)
{ {
public Notification ToNotification() => new(Kanaal, Resource, Actie, ResourceUrl, HoofdObject); public Notification ToNotification() => new(Kanaal, Resource, Actie, ResourceUrl);
} }
public partial class Program public partial class Program
@@ -16,15 +16,15 @@ public sealed record Notification(
string Kanaal, string Kanaal,
string Resource, string Resource,
string Actie, string Actie,
Uri ResourceUrl, Uri ResourceUrl)
Uri? HoofdObject = null)
{ {
/// <summary>A register record written to Objecten — <c>create</c> on submit, <c>update</c> on /// <summary>A register record written to Objecten — <c>create</c> on submit, <c>update</c> on
/// approval, since the ACL upserts the same object for a registration (§8.6).</summary> /// approval, since the ACL upserts the same object for a registration (§8.6).</summary>
public bool IsRegisterRecordWritten => public bool IsRegisterRecordWritten =>
Kanaal == "objecten" && Resource == "object" && Actie is "create" or "update"; Kanaal == "objecten" && Resource == "object" && Actie is "create" or "update";
/// <summary>The object holding the register record. Objecten sets both fields to the object; /// <summary>The object holding the register record. For a <c>resource: object</c> notification
/// <c>hoofdObject</c> is the main resource by definition, so prefer it.</summary> /// Objecten sends the object as both <c>hoofdObject</c> and <c>resourceUrl</c> — the object is
public Uri ObjectUrl => HoofdObject ?? ResourceUrl; /// the main resource — so the notification's own <c>hoofdObject</c> is not modelled.</summary>
public Uri ObjectUrl => ResourceUrl;
} }
@@ -22,7 +22,7 @@ public sealed class NotificationProjectorTests
private Notification RecordWritten(string actie = "create", string url = ObjectUrl, string status = RegistrationStatus.Ingediend, string zaakId = ZaakId) private Notification RecordWritten(string actie = "create", string url = ObjectUrl, string status = RegistrationStatus.Ingediend, string zaakId = ZaakId)
{ {
_acl.Records[url] = new RegisterRecord(zaakId, status, "REG-2026-0001"); _acl.Records[url] = new RegisterRecord(zaakId, status, "REG-2026-0001");
return new Notification("objecten", "object", actie, new Uri(url), new Uri(url)); return new Notification("objecten", "object", actie, new Uri(url));
} }
[Fact] [Fact]
@@ -28,7 +28,7 @@ public sealed class RegisterProjectieBijwerkenSteps
// The ACL upserts one object per registration, so submit and approval share an object URL. // The ACL upserts one object per registration, so submit and approval share an object URL.
var objectUrl = ObjectBase + id; var objectUrl = ObjectBase + id;
_register.Records[objectUrl] = new RegisterRecord(id, status, "REG-" + id); _register.Records[objectUrl] = new RegisterRecord(id, status, "REG-" + id);
_notification = new Notification("objecten", "object", "create", new Uri(objectUrl), new Uri(objectUrl)); _notification = new Notification("objecten", "object", "create", new Uri(objectUrl));
} }
[Given("the register notification is delivered to the event subscriber")] [Given("the register notification is delivered to the event subscriber")]