namespace EventSubscriber.Application;
///
/// An inbound NRC (Open Notificaties) notification, as Open Notificaties POSTs it to an
/// abonnement callback. Only the fields the projection needs are modelled; the full ZGW
/// "Notificatie" resource also carries aanmaakdatum and kenmerken which the
/// minimal projection ignores (bsn is deferred — see ADR-0008). For a zaken/zaak/create
/// notification hoofdObject and resourceUrl are both the created zaak's URL.
///
public sealed record Notification(
string Kanaal,
string Resource,
string Actie,
Uri ResourceUrl,
Uri? HoofdObject = null)
{
/// A zaak being created — projected as INGEDIEND.
public bool IsZaakCreated =>
Kanaal == "zaken" && Resource == "zaak" && Actie == "create";
/// A status being set on a zaak — the approval, projected as INGESCHREVEN (S-09b). In the
/// walking skeleton the only status ever set after creation is the approval, and the subscriber may
/// not read OpenZaak (§8.1), so any status-create is taken as the approval.
public bool IsZaakStatusSet =>
Kanaal == "zaken" && Resource == "status" && Actie == "create";
/// The zaak UUID used as the projection key. For a status notification the resource URL is
/// the status, so the zaak comes from hoofdObject (which, for a zaak-create, equals the
/// resource URL) — see the NRC payload note.
public string ZaakId => (HoofdObject ?? ResourceUrl).Segments[^1].Trim('/');
///
/// A deterministic dedup key. Open Notificaties carries no notification id and may
/// redeliver, so the key is derived from the immutable notification content: two
/// deliveries of the same zaak-create collapse to one. (NRC may also deliver
/// out of order; the projector tolerates that — order does not change the outcome.)
///
public string IdempotencyKey => $"{Kanaal}:{Resource}:{Actie}:{ResourceUrl}";
}