feat(domain): take a registration into behandeling; generalise decisions (refs #13)

Adds InBehandeling + Afgewezen statuses and TakeIntoBehandeling(). Generalises the
behandelaar decision: Approve() (requires a zaak) and new Reject() both act on an
INGEDIEND or IN_BEHANDELING registration, moving it to Ingeschreven/Afgewezen.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-14 17:18:18 +02:00
parent 23125ef492
commit 09000d8e64
2 changed files with 54 additions and 12 deletions

View File

@@ -66,10 +66,28 @@ public sealed class Registration
} }
/// <summary> /// <summary>
/// Approve the registration — the behandelaar's decision to enter it in the register. Advances /// A behandelaar picks the registration up for beoordeling. Advances
/// <see cref="RegistrationStatus.Ingediend"/> → <see cref="RegistrationStatus.Ingeschreven"/>. /// <see cref="RegistrationStatus.Ingediend"/> → <see cref="RegistrationStatus.InBehandeling"/>.
/// Requires an opened zaak (the approval sets that zaak's status via the ACL), and only a /// Re-taking one already <see cref="RegistrationStatus.InBehandeling"/> is a no-op (the same or
/// submitted registration can be approved: re-approving is rejected as an invalid transition. /// another behandelaar re-opens it); a decided registration can no longer be taken into behandeling.
/// </summary>
public void TakeIntoBehandeling()
{
if (Status == RegistrationStatus.InBehandeling)
return;
if (Status != RegistrationStatus.Ingediend)
throw new InvalidOperationException(
$"Registration {Id} is {Status}; only an INGEDIEND registration can be taken into behandeling.");
Status = RegistrationStatus.InBehandeling;
}
/// <summary>
/// Approve the registration — the behandelaar's decision to enter it in the register. Advances a
/// submitted or in-behandeling registration to <see cref="RegistrationStatus.Ingeschreven"/>.
/// Requires an opened zaak (the approval sets that zaak's status via the ACL); a registration that
/// has already been decided cannot be approved again.
/// </summary> /// </summary>
public void Approve() public void Approve()
{ {
@@ -77,10 +95,27 @@ public sealed class Registration
throw new InvalidOperationException( throw new InvalidOperationException(
$"Registration {Id} has no zaak yet; it cannot be approved before its zaak is opened."); $"Registration {Id} has no zaak yet; it cannot be approved before its zaak is opened.");
if (Status != RegistrationStatus.Ingediend) RequireOpenForDecision(nameof(Approve));
throw new InvalidOperationException(
$"Registration {Id} is {Status}; only an INGEDIEND registration can be approved.");
Status = RegistrationStatus.Ingeschreven; Status = RegistrationStatus.Ingeschreven;
} }
/// <summary>
/// Reject the registration — the behandelaar's decision not to enter it in the register. Advances a
/// submitted or in-behandeling registration to <see cref="RegistrationStatus.Afgewezen"/>. Unlike
/// approval this needs no zaak: a registration can be rejected before or after its zaak is opened.
/// A registration that has already been decided cannot be rejected again.
/// </summary>
public void Reject()
{
RequireOpenForDecision(nameof(Reject));
Status = RegistrationStatus.Afgewezen;
}
// A decision is only valid while the registration is still open (INGEDIEND or IN_BEHANDELING).
private void RequireOpenForDecision(string decision)
{
if (Status is not (RegistrationStatus.Ingediend or RegistrationStatus.InBehandeling))
throw new InvalidOperationException(
$"Registration {Id} is {Status}; only an INGEDIEND or IN_BEHANDELING registration can be decided ({decision}).");
}
} }

View File

@@ -1,13 +1,20 @@
namespace Big.Domain; namespace Big.Domain;
/// <summary>The lifecycle states a <see cref="Registration"/> moves through. The walking /// <summary>The lifecycle states a <see cref="Registration"/> moves through. Submission starts in
/// skeleton knows <see cref="Ingediend"/> and the terminal <see cref="Ingeschreven"/>; withdrawal, /// <see cref="Ingediend"/>; a behandelaar takes it <see cref="InBehandeling"/> and decides it into one
/// beoordeling and herregistratie states arrive in their own slices (Iteration 2+).</summary> /// of the terminal states <see cref="Ingeschreven"/> (approved) or <see cref="Afgewezen"/> (rejected).
/// Withdrawal and herregistratie states arrive in their own slices (S-11+).</summary>
public enum RegistrationStatus public enum RegistrationStatus
{ {
/// <summary>Submitted by the zorgprofessional; the registratie process has been started.</summary> /// <summary>Submitted by the zorgprofessional; the registratie process has been started.</summary>
Ingediend, Ingediend,
/// <summary>Approved: entered in the register. Terminal in the walking skeleton (S-09b).</summary> /// <summary>Picked up by a behandelaar for beoordeling (S-12).</summary>
InBehandeling,
/// <summary>Approved: entered in the register. Terminal.</summary>
Ingeschreven, Ingeschreven,
/// <summary>Rejected by the behandelaar. Terminal.</summary>
Afgewezen,
} }