test(domain): herregistratie inscription date + reminder-due rule (refs #18)

The Registration aggregate gains the herregistratie clock: Approve now records
the inscription moment, from which the herregistratie deadline and a
reminder-due rule are derived. Members are stubbed so the suite compiles and the
new assertions fail; the green commit implements them. Approve's signature gains
the inscription moment (callers now supply 'now' from an injected TimeProvider).

refs #18
This commit is contained in:
not
2026-07-23 11:51:11 +02:00
parent 5f8ab4dbcd
commit dc532dee00
9 changed files with 162 additions and 32 deletions
+37 -4
View File
@@ -92,11 +92,12 @@ public sealed class Registration
/// <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.
/// submitted or in-behandeling registration to <see cref="RegistrationStatus.Ingeschreven"/> and
/// records <paramref name="ingeschrevenOp"/> as the moment of inscription, which starts the
/// herregistratie clock (S-17). 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>
public void Approve()
public void Approve(DateTimeOffset ingeschrevenOp)
{
if (ZaakUrl is null)
throw new InvalidOperationException(
@@ -104,8 +105,40 @@ public sealed class Registration
RequireOpenForDecision(nameof(Approve));
Status = RegistrationStatus.Ingeschreven;
// RED stub: the inscription moment is not stored yet.
}
// --- Herregistratie (S-17) — RED stubs, implemented in the green commit ---------------------
/// <summary>How long a BIG inscription stays valid before herregistratie is required.</summary>
// ponytail: fixed 5-year term — a calibration knob, not a config surface. If a demo needs it
// per-catalogus, promote it to policy passed in from the beheer config (S-15).
public static readonly TimeSpan HerregistratieGeldigheid = TimeSpan.FromDays(365 * 5);
/// <summary>How long before the deadline the herregistratie reminder is sent (BIG: ~16 weeks).</summary>
// ponytail: fixed 16-week lead time — calibration knob; same promotion path as HerregistratieGeldigheid.
public static readonly TimeSpan Herinneringstermijn = TimeSpan.FromDays(16 * 7);
/// <summary>When the registration was entered in the register, once approved; the start of its
/// herregistratie clock. Null until it is <see cref="RegistrationStatus.Ingeschreven"/>.</summary>
public DateTimeOffset? IngeschrevenOp { get; private set; }
/// <summary>The date by which herregistratie must happen: inscription + validity. Null until
/// inscribed.</summary>
public DateTimeOffset? HerregistratieVoor => null; // RED stub
/// <summary>Whether the herregistratie reminder has been sent for this inscription (S-17).</summary>
public bool HerregistratieReminderVerstuurd { get; private set; }
/// <summary>Whether, as of <paramref name="asOf"/>, this registration is due a herregistratie
/// reminder: it is inscribed, the reminder window before its deadline has opened, and it has not
/// already been reminded.</summary>
public bool HerregistratieReminderDue(DateTimeOffset asOf) => false; // RED stub
/// <summary>Record that the herregistratie reminder has been sent. Idempotent — a re-sweep is a
/// no-op; only an inscribed registration can be reminded.</summary>
public void MarkHerregistratieReminderVerstuurd() { } // RED stub
/// <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