Commit Graph

17 Commits

Author SHA1 Message Date
Joseph Doherty
ae7329034f fix(auditlog): populate the Actor column on outbound and central rows
Per the Audit Log Actor-column spec, Actor should carry the calling script
identity on outbound rows (ApiCall, DbWrite, NotifySend) and a system identity
on central-dispatch rows (NotifyDeliver). The original emission code hard-coded
Actor=null at all four sites, so only Inbound API rows (API key name) ever
filled it. Stamp the script identity and 'system' respectively.
2026-05-21 09:50:55 -04:00
Joseph Doherty
194cae2fbf feat(notif): NotificationDetailRequest query for full notification detail 2026-05-21 02:47:43 -04:00
Joseph Doherty
6de377a39e feat(notif): emit NotifyDeliver(terminal) on terminal transitions (#23 M4)
M4 Bundle B (B3) — NotificationOutboxActor emits a second NotifyDeliver
audit row carrying the terminal AuditStatus whenever a notification
transitions to a terminal state (Delivered, Parked, Discarded).

- Dispatcher: after the B2 Attempted row, a Delivered or Parked row is
  emitted when the post-outcome status is terminal. Discarded is never
  produced by the dispatcher — only by the manual discard path.
- Missing-adapter park: now emits both Attempted and terminal Parked,
  both carrying the same explanatory error.
- Manual discard (DiscardAsync): after the row update, emits a terminal
  Discarded NotifyDeliver row with no error message (operator-driven
  cancellation, not a delivery error).
- MapNotificationStatusToAuditStatus + IsTerminal helpers added; terminal
  emission shares BuildNotifyDeliverEvent with the B2 Attempted path so
  the two rows carry identical correlation/provenance fields.

Audit failure NEVER aborts the user-facing action: every emission is
wrapped in try/catch (defensive — the CentralAuditWriter itself swallows).
2026-05-20 16:12:44 -04:00
Joseph Doherty
1dfd67a90d feat(notif): emit NotifyDeliver(Attempted) per dispatcher attempt (#23 M4)
M4 Bundle B (B2) — NotificationOutboxActor's dispatcher loop emits a single
AuditChannel.Notification / AuditKind.NotifyDeliver row with AuditStatus.Attempted
for every delivery attempt (success, transient failure, permanent failure,
and the missing-adapter park).

- BuildNotifyDeliverEvent helper populates correlation id (parsed from the
  string NotificationId — sites generate Guid.NewGuid().ToString("N"),
  non-Guid ids fall through as null), list-name target, source site/instance/script
  provenance, and Actor=null (central dispatch has no authenticated end-user).
- Attempt duration is measured around the adapter call and recorded as
  DurationMs so KPIs can compute per-attempt latency.
- Emission is fire-and-forget (the writer swallows internally) and wrapped
  in try/catch — audit failure NEVER aborts the user-facing dispatch.

Terminal-state emission lands separately in B3.
2026-05-20 16:08:06 -04:00
Joseph Doherty
b31747a632 feat(notif): NotificationOutboxActor + CentralAuditWriter wired (#23 M4)
M4 Bundle B (B1) — add the central-only ICentralAuditWriter implementation
and inject it into NotificationOutboxActor so subsequent tasks (B2/B3) can
route attempt + terminal lifecycle events through the direct-write audit path.

- CentralAuditWriter: thin wrapper around IAuditLogRepository.InsertIfNotExistsAsync;
  scope-per-call (matches AuditLogIngestActor / NotificationOutboxActor pattern);
  stamps IngestedAtUtc; swallows all internal failures (alog.md §13).
- Registered as a singleton in AddAuditLog.
- NotificationOutboxActor ctor takes ICentralAuditWriter (validated non-null).
- Host wiring resolves the writer once from the root provider and passes it
  into the singleton's Props.Create call.
- Existing TestKit fixtures updated with a NoOpCentralAuditWriter helper so
  tests that don't exercise audit emission still compile and pass.
2026-05-20 16:04:01 -04:00
Joseph Doherty
1629a72093 feat(notification-outbox): actor handler for per-site KPI requests 2026-05-19 05:37:14 -04:00
Joseph Doherty
703cb2d392 feat(notification-outbox): add AddNotificationOutbox DI registration 2026-05-19 02:07:29 -04:00
Joseph Doherty
41358c1cee feat(notification-outbox): add daily terminal-row purge 2026-05-19 01:58:19 -04:00
Joseph Doherty
77a05a8960 fix(notification-outbox): give KPI response a failure shape; log status-query faults 2026-05-19 01:55:46 -04:00
Joseph Doherty
82e3eb0e93 feat(notification-outbox): add query, retry, discard, and KPI handlers 2026-05-19 01:50:20 -04:00
Joseph Doherty
ab3721a2e8 fix(notification-outbox): clear dispatch in-flight flag on a faulted pass 2026-05-19 01:45:09 -04:00
Joseph Doherty
c41f43c87f feat(notification-outbox): add dispatcher loop to NotificationOutboxActor 2026-05-19 01:42:28 -04:00
Joseph Doherty
4dc9f9e159 feat(notification-outbox): add NotificationOutboxActor ingest 2026-05-19 01:36:13 -04:00
Joseph Doherty
04e00d56c6 test(notification-outbox): cover Email adapter permanent/cancellation arms, align error casing 2026-05-19 01:32:54 -04:00
Joseph Doherty
b8dece0e70 feat(notification-outbox): add Email notification delivery adapter 2026-05-19 01:26:33 -04:00
Joseph Doherty
8d52890245 feat(notification-outbox): add NotificationOutboxOptions and delivery adapter abstraction 2026-05-19 01:20:49 -04:00
Joseph Doherty
fb589bf1da feat(notification-outbox): scaffold ScadaLink.NotificationOutbox project 2026-05-19 01:16:58 -04:00