Files
scadalink-design/docs/plans/2026-05-19-notifications-nav-group-design.md
2026-05-19 05:01:58 -04:00

6.4 KiB

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.razorComponents/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 == falseErrorMessage); 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.