using Big.Domain; namespace Big.Application; /// A behandelaar's decision to approve a registration, in domain language. public sealed record ApproveRegistrationCommand(RegistrationId RegistrationId); /// /// The approve use case (S-09b): set the registration's zaak to its final status via the ACL (§8.1), /// then advance the aggregate to INGESCHREVEN. Idempotent — a redelivered or repeated approval of an /// already-approved registration is a no-op, so the ACL is not asked to set the status twice. The /// zaak status is the projection's source of truth (it flows back over NRC); the aggregate transition /// keeps the domain's own view consistent. /// public sealed class ApproveRegistration(IRegistrationStore store, IAclClient acl) { public async Task HandleAsync(ApproveRegistrationCommand command, CancellationToken ct = default) { ArgumentNullException.ThrowIfNull(command); var registration = await store.GetAsync(command.RegistrationId, ct) ?? throw new InvalidOperationException($"No registration {command.RegistrationId} to approve."); // A repeated approval is a no-op: don't set the zaak status a second time. if (registration.Status == RegistrationStatus.Ingeschreven) return; if (registration.ZaakUrl is null) throw new InvalidOperationException( $"Registration {command.RegistrationId} has no zaak yet; it cannot be approved."); await acl.ApproveZaakAsync(registration.ZaakUrl, ct); registration.Approve(); await store.SaveAsync(registration, ct); } }