docs(notification-outbox): fix naming consistency and status-lifecycle clarity
This commit is contained in:
@@ -29,7 +29,7 @@ Site script: Notify.To("list").Send(subject, body)
|
|||||||
│ generate NotificationId (GUID) locally; return it to the script immediately
|
│ generate NotificationId (GUID) locally; return it to the script immediately
|
||||||
▼
|
▼
|
||||||
Site Store-and-Forward Engine (notification category, target = central)
|
Site Store-and-Forward Engine (notification category, target = central)
|
||||||
│ durably forwards to central via the Communication Layer (ClusterClient);
|
│ durably forwards to central via Central–Site Communication (ClusterClient);
|
||||||
│ buffers/retries if central is unreachable
|
│ buffers/retries if central is unreachable
|
||||||
▼
|
▼
|
||||||
Central ingest: insert-if-not-exists on NotificationId → Notifications table (Pending)
|
Central ingest: insert-if-not-exists on NotificationId → Notifications table (Pending)
|
||||||
@@ -58,7 +58,7 @@ The table is type-agnostic so it can record any notification type the system sup
|
|||||||
| `ListName` | Target notification list. |
|
| `ListName` | Target notification list. |
|
||||||
| `Subject`, `Body` | Plain-text content. |
|
| `Subject`, `Body` | Plain-text content. |
|
||||||
| `TypeData` | JSON — extensibility hook for future per-type fields. |
|
| `TypeData` | JSON — extensibility hook for future per-type fields. |
|
||||||
| `Status` | `Pending` → `Retrying` → `Delivered` / `Parked` / `Discarded`. |
|
| `Status` | Lifecycle state — one of `Pending`, `Retrying`, `Delivered`, `Parked`, `Discarded`. See Status Lifecycle below. |
|
||||||
| `RetryCount` | Delivery attempts so far. |
|
| `RetryCount` | Delivery attempts so far. |
|
||||||
| `LastError` | Detail of the most recent failure. |
|
| `LastError` | Detail of the most recent failure. |
|
||||||
| `ResolvedTargets` | Who the notification actually went to — snapshotted by central at delivery time, for audit. |
|
| `ResolvedTargets` | Who the notification actually went to — snapshotted by central at delivery time, for audit. |
|
||||||
@@ -84,11 +84,11 @@ Delivery retry reuses the central SMTP configuration's max-retry-count and fixed
|
|||||||
|
|
||||||
### Retention
|
### Retention
|
||||||
|
|
||||||
Terminal rows (`Delivered`, `Parked`, `Discarded`) are removed by a **daily purge job** after a configurable window (default ~1 year). This preserves a strong audit trail while bounding table growth. Non-terminal rows are never purged.
|
Terminal rows (`Delivered`, `Parked`, `Discarded`) are removed by a **daily purge job** after a configurable window (default 365 days). This preserves a strong audit trail while bounding table growth. Non-terminal rows are never purged.
|
||||||
|
|
||||||
## Ingest & Idempotency
|
## Ingest & Idempotency
|
||||||
|
|
||||||
The site→central handoff is **at-least-once**. Central ingests an inbound notification submission with an **insert-if-not-exists** on `NotificationId`, then acks the site; the site S&F engine clears the message only on that ack. Because central acks only after the row is persisted (ack-after-persist), a lost ack causes the site to resend, and the GUID `NotificationId` idempotency key makes the resend harmless — the duplicate insert is a no-op.
|
The site→central handoff is **at-least-once**. Central ingests an inbound notification submission with an insert-if-not-exists on `NotificationId`, then acks the site; the site S&F engine clears the message only on that ack. Because central acks only after the row is persisted (ack-after-persist), a lost ack causes the site to resend, and the GUID `NotificationId` idempotency key makes the resend harmless — the duplicate insert is a no-op.
|
||||||
|
|
||||||
A rare central failover mid-delivery could re-send one already-`Delivered` notification. This is an accepted trade-off, consistent with the duplicate-delivery trade-off the Store-and-Forward Engine already accepts.
|
A rare central failover mid-delivery could re-send one already-`Delivered` notification. This is an accepted trade-off, consistent with the duplicate-delivery trade-off the Store-and-Forward Engine already accepts.
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ KPIs are central-computed from the `Notifications` table — global, with a per-
|
|||||||
- **Delivered (last interval)** — count of `Delivered` since the previous sample.
|
- **Delivered (last interval)** — count of `Delivered` since the previous sample.
|
||||||
- **Oldest pending age** — age of the oldest non-terminal notification.
|
- **Oldest pending age** — age of the oldest non-terminal notification.
|
||||||
|
|
||||||
KPIs are point-in-time, computed on demand from the table. The ~1-year row retention answers historical questions directly, so no separate time-series store is added.
|
KPIs are point-in-time, computed on demand from the table. The configurable row retention (default 365 days) answers historical questions directly, so no separate time-series store is added.
|
||||||
|
|
||||||
### Stuck Detection
|
### Stuck Detection
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ The component is configured via `NotificationOutboxOptions`, bound from an `apps
|
|||||||
|
|
||||||
- **Dispatch interval** — how often the dispatcher loop polls for due rows.
|
- **Dispatch interval** — how often the dispatcher loop polls for due rows.
|
||||||
- **Stuck-age threshold** — age beyond which a non-terminal notification is counted as stuck (default 10 minutes).
|
- **Stuck-age threshold** — age beyond which a non-terminal notification is counted as stuck (default 10 minutes).
|
||||||
- **Terminal-row retention window** — age after which terminal rows are removed by the daily purge job (default ~1 year).
|
- **Terminal-row retention window** — age after which terminal rows are removed by the daily purge job (default 365 days).
|
||||||
|
|
||||||
Delivery max-retry-count and retry interval are not part of `NotificationOutboxOptions` — they are reused from the central SMTP configuration.
|
Delivery max-retry-count and retry interval are not part of `NotificationOutboxOptions` — they are reused from the central SMTP configuration.
|
||||||
|
|
||||||
@@ -160,7 +160,7 @@ Delivery max-retry-count and retry interval are not part of `NotificationOutboxO
|
|||||||
|
|
||||||
## Interactions
|
## Interactions
|
||||||
|
|
||||||
- **Site Store-and-Forward Engine**: Forwards notifications to central via the Communication Layer; the outbox ingests them and acks once persisted.
|
- **Site Store-and-Forward Engine**: Forwards notifications to central via Central–Site Communication; the outbox ingests them and acks once persisted.
|
||||||
- **Notification Service**: Supplies delivery adapters and resolves notification lists at delivery time.
|
- **Notification Service**: Supplies delivery adapters and resolves notification lists at delivery time.
|
||||||
- **Central UI**: Queries the `Notifications` table for the Notification Outbox page and issues operator Retry/Discard actions on parked notifications.
|
- **Central UI**: Queries the `Notifications` table for the Notification Outbox page and issues operator Retry/Discard actions on parked notifications.
|
||||||
- **Health Monitoring**: Polls the outbox for KPI tiles on the health dashboard.
|
- **Health Monitoring**: Polls the outbox for KPI tiles on the health dashboard.
|
||||||
|
|||||||
Reference in New Issue
Block a user