docs(plans): design for Notifications nav group

This commit is contained in:
Joseph Doherty
2026-05-19 05:01:58 -04:00
parent 17861efa51
commit 113f00a6fa

View File

@@ -0,0 +1,143 @@
# Notifications Nav Group — Design
**Date:** 2026-05-19
**Goal:** Consolidate all notification-related Central UI pages into a dedicated
**Notifications** left-menu section, split the combined Outbox page into a report
and a KPIs page, give Notification Lists a proper home, and add a per-source-site
KPI breakdown.
## Background
Notification-related UI is currently scattered:
| Page | Route | Nav section | Policy |
|---|---|---|---|
| SMTP Configuration | `/admin/smtp` | Admin | RequireAdmin |
| Notification Outbox (KPI tiles **+** filterable table) | `/monitoring/notification-outbox` | Monitoring | RequireDeployment |
| Notification Lists | `/design/notification-lists/...` (form only) | none — table embedded in the External Systems page | RequireDesign |
The Outbox page mixes KPI tiles and the filterable `Notifications`-table report on
one page. Notification Lists has no list page of its own — its table is bolted
onto `ExternalSystems.razor`. KPI infrastructure
(`NotificationKpiRequest`/`Response`, `INotificationOutboxRepository.ComputeKpisAsync`)
is global-only, despite CLAUDE.md stating KPIs are "global + per-source-site".
## Architecture
A new **Notifications** left-menu section consolidates these pages. Routes move
to a consistent `/notifications/*` prefix. The combined Outbox page is split into
two. Notification Lists gets a dedicated page. A bounded backend addition supplies
per-source-site KPIs. No actor topology, persistence, or message-evolution rules
change beyond the additive KPI contracts.
## 1. Nav menu
New `Notifications` section in `NavMenu.razor`, placed **between Deployment and
Monitoring**. Final section order: Dashboard, Admin, Design, Deployment,
Notifications, Monitoring, Audit Log.
| Menu item | Route | Policy |
|---|---|---|
| SMTP Configuration | `/notifications/smtp` | RequireAdmin |
| Notification Lists | `/notifications/lists` | RequireDesign |
| Notification Report | `/notifications/report` | RequireDeployment |
| Notification KPIs | `/notifications/kpis` | RequireDeployment |
Each item is wrapped in its own per-item `AuthorizeView` policy (same pattern the
Monitoring section already uses for its mixed-role items). The section header is a
plain `div` — every authenticated user holds at least one of Admin/Design/Deployment,
so the header always has ≥1 visible child and cannot be orphaned.
SMTP Configuration is **removed** from the Admin section; Notification Outbox is
**removed** from the Monitoring section.
## 2. SMTP Configuration
Move `Components/Pages/Admin/SmtpConfiguration.razor`
`Components/Pages/Notifications/SmtpConfiguration.razor`. Route `/admin/smtp`
`/notifications/smtp`. Page content, `RequireAdmin` policy, and the
`SmtpConfiguration` namespace alias are unchanged.
## 3. Notification Lists (new page)
New `Components/Pages/Notifications/NotificationLists.razor`
(`/notifications/lists`, RequireDesign): a `DataTable` of notification lists with
Add and per-row Edit actions, plus an empty state — extracted verbatim from the
notification-lists block currently in `ExternalSystems.razor`.
- `NotificationListForm.razor` routes move:
`/design/notification-lists/create``/notifications/lists/create`,
`/design/notification-lists/{Id:int}/edit``/notifications/lists/{Id:int}/edit`.
Its "Back" navigation targets `/notifications/lists`.
- The notification-lists section is **removed** from `ExternalSystems.razor`,
leaving that page purely external systems. The three `/design/notification-lists/...`
navigate-links in `ExternalSystems.razor` are removed with it.
## 4. Notification Report
New `Components/Pages/Notifications/NotificationReport.razor`
(`/notifications/report`, RequireDeployment), split from the existing
`Monitoring/NotificationOutbox.razor`. Retains the full filter bar, the paginated
`Notifications`-table query (`NotificationOutboxQueryRequest`), and the per-row
Retry/Discard actions. The **KPI tile row is removed** from this page.
`Components/Pages/Monitoring/NotificationOutbox.razor` and its Monitoring nav entry
are **deleted**.
## 5. Notification KPIs
New `Components/Pages/Notifications/NotificationKpis.razor`
(`/notifications/kpis`, RequireDeployment) with a manual Refresh button. Two parts:
1. **Global tiles** — the existing 5: Queue Depth, Stuck, Parked, Delivered Last
Interval, Oldest Pending Age.
2. **Per-source-site breakdown table** — one row per site with the same five
metrics, so operators can see which site is backing up.
### Backend addition for per-site KPIs
Bounded, additive, follows the existing global-KPI pattern:
- `INotificationOutboxRepository.ComputePerSiteKpisAsync(...)` → returns a
per-site collection (a new `SiteNotificationKpiSnapshot` record carrying the
source site id plus the five metrics). Implemented in
`NotificationOutboxRepository`.
- New message pair in `Messages/Notification/NotificationOutboxQueries.cs`:
`PerSiteNotificationKpiRequest` / `PerSiteNotificationKpiResponse` (additive —
honors message-evolution rules).
- A handler in `NotificationOutboxActor` for the new request, mirroring the
existing `NotificationKpiRequest` handler.
- A `CommunicationService.GetPerSiteNotificationKpisAsync(...)` method mirroring
`GetNotificationKpisAsync`.
Per CLAUDE.md, KPIs remain point-in-time computed from the `Notifications` table —
no time-series store, no historical charts (YAGNI).
## 6. Health dashboard
`Monitoring/Health.razor` keeps its KPI tile row unchanged. A "View details →"
link is added from that tile row to `/notifications/kpis`.
## Error handling
Unchanged from the current Outbox page: KPI/query faults surface as an inline
warning alert (`Success == false``ErrorMessage`); the site-name lookup degrades
gracefully to raw site ids. Per-site KPI faults are reported the same way.
## Testing
- bUnit component tests for `NotificationLists`, `NotificationReport`,
`NotificationKpis`, and the moved `SmtpConfiguration` page.
- A `NavMenu` test asserting the Notifications section renders and that per-item
visibility honors Admin/Design/Deployment roles.
- Repository tests for `ComputePerSiteKpisAsync`.
- Actor test for the `PerSiteNotificationKpiRequest` handler.
- `CommunicationService` test for `GetPerSiteNotificationKpisAsync`.
## Out of scope
- Historical/trend KPI charts (no time-series store).
- Any change to notification delivery, store-and-forward, or the `Notifications`
table schema.
- Renaming the Notification Outbox **component** (#21) — only the UI page names change.