Skip to content

feat(subscriptions,ui): delivery instrumentation — 24-hour counts and first-try success rate - #588

Merged
smunini merged 1 commit into
mainfrom
feat/586-delivery-stats
Aug 19, 2026
Merged

feat(subscriptions,ui): delivery instrumentation — 24-hour counts and first-try success rate#588
smunini merged 1 commit into
mainfrom
feat/586-delivery-stats

Conversation

@angela-helios

Copy link
Copy Markdown
Contributor

Closes #586 — the second half of #580's operator page.

Stacked on #585 (base feat/580-subscriptions-ui): GitHub retargets to main when it merges, activating the Development link; the diff shrinks to just this feature then.

What the engine gains

A rolling ring of delivery counters per subscription (delivery_stats.rs): 48 half-hour, epoch-aligned buckets — deliberately the same shape as the dashboard's DashboardWindow::LastDay, so both surfaces bucket time identically. Outcomes are recorded at the single dispatch funnel every channel already runs through (dispatch_with_retry): success carries whether it landed on the first attempt; permanent errors, exhausted retries, and dispatch errors record as failures. Cost per delivery: one mutex-guarded bump.

In-memory by design. The window resets with the process, like the rest of the engine's volatile state, and the module docs say so. A durable delivery log (queryable across restarts) is separate, storage-backed work — deliberately out of scope.

What the page fills in

  • The fourth card becomes DELIVERED IN 24 H, with the first-try success rate as its qualifier — absent when nothing was delivered, never a fabricated 100%.
  • The table gains the design's LAST 24 HRS column between STATUS and SENT.
  • Strings in en/es/de.

Verification

  • Ring unit tests: accumulation, 24-hour age-out, slot reuse when a half-hour cycles around, removal.
  • The UI test's injected provider drives the card sum (4,493) and the rate (96.2%) through the real render.
  • Live end-to-end: five Encounters through two delivering channels put 10 on the card with the rate rendered — read back through the provider from the actual dispatch path.
  • Full hermetic suite: 140 passed.

… first-try rate

The engine gains the missing half of #580 (#586): a rolling ring of 48
half-hour, epoch-aligned buckets per subscription — the same shape as the
dashboard's day window — bumped at the single dispatch funnel every channel
already runs through. Success records whether it landed on the first attempt;
permanent errors and exhausted retries record as failures. In-memory by
design: the window resets with the process like the rest of the engine's
state, and the module says so.

The operator page fills in what shipped absent: the fourth card becomes
DELIVERED IN 24 H with the first-try rate as its qualifier (absent when
nothing was delivered — never a fabricated 100%), and the table gains the
design's LAST 24 HRS column. Strings in en/es/de.

Verified live: five Encounters through two delivering channels put 10 on the
card with the rate rendered, read back through the provider from the real
dispatch path.
@angela-helios
angela-helios requested a review from smunini August 19, 2026 19:28
Base automatically changed from feat/580-subscriptions-ui to main August 19, 2026 21:42
@smunini
smunini merged commit 5e7bc63 into main Aug 19, 2026
3 checks passed
@smunini
smunini deleted the feat/586-delivery-stats branch August 19, 2026 21:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

subscriptions: delivery instrumentation — per-window counts and first-try success rate

2 participants