From f95ee623f46ef3b9a5665ba8eaa61dfe9016978c Mon Sep 17 00:00:00 2001 From: Niek Otten Date: Tue, 21 Jul 2026 14:37:47 +0200 Subject: [PATCH] feat(domain): cancel the zaak via the ACL when a registration times out (refs #106) The expiry worker asks the ACL to cancel the zaak before advancing the aggregate to VERLOPEN, so a lapsed document term is reflected in ZGW and not only in the domain. Ordered ACL-first for redelivery safety; guarded so a redelivered job neither re-saves nor re-cancels. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../domain/Big.Application/ExpireRegistrationWorker.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/services/domain/Big.Application/ExpireRegistrationWorker.cs b/services/domain/Big.Application/ExpireRegistrationWorker.cs index a1acc28..b351355 100644 --- a/services/domain/Big.Application/ExpireRegistrationWorker.cs +++ b/services/domain/Big.Application/ExpireRegistrationWorker.cs @@ -31,6 +31,14 @@ public sealed class ExpireRegistrationWorker(IRegistrationStore store, IAclClien if (registration.Status is not (RegistrationStatus.Ingediend or RegistrationStatus.InBehandeling)) return; + // Cancel the ZGW zaak before advancing the aggregate (mirrors the approval path): if the ACL + // call fails it throws, the aggregate stays open, and the job is redelivered (§8.6) — rather + // than leaving the aggregate VERLOPEN while the zaak stays open. The status guard above stops a + // redelivered job from cancelling the zaak twice (a second resultaat would be a 400). A + // registration expired before its zaak was opened has nothing to cancel. + if (registration.ZaakUrl is not null) + await acl.CancelZaakAsync(registration.ZaakUrl, ct); + registration.Expire(); await store.SaveAsync(registration, ct); }