docs(alerting): UI map + admin-guide walkthrough for Plan 03
.claude/rules/ui.md now maps every Plan 03 UI surface. Admin guide gains an inbox/rules/silences walkthrough so ops teams can start in the UI without reading the spec. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -34,6 +34,28 @@ The UI has 4 main tabs: **Exchanges**, **Dashboard**, **Runtime**, **Deployments
|
|||||||
- `ui/src/hooks/useInfiniteStream.ts` — tanstack `useInfiniteQuery` wrapper with top-gated auto-refetch, flattened `items[]`, and `refresh()` invalidator
|
- `ui/src/hooks/useInfiniteStream.ts` — tanstack `useInfiniteQuery` wrapper with top-gated auto-refetch, flattened `items[]`, and `refresh()` invalidator
|
||||||
- `ui/src/components/InfiniteScrollArea.tsx` — scrollable container with IntersectionObserver top/bottom sentinels. Streaming log/event views use this + `useInfiniteStream`. Bounded views (LogTab, StartupLogPanel) keep `useLogs`/`useStartupLogs`
|
- `ui/src/components/InfiniteScrollArea.tsx` — scrollable container with IntersectionObserver top/bottom sentinels. Streaming log/event views use this + `useInfiniteStream`. Bounded views (LogTab, StartupLogPanel) keep `useLogs`/`useStartupLogs`
|
||||||
|
|
||||||
|
## Alerts
|
||||||
|
|
||||||
|
- **Sidebar section** (`buildAlertsTreeNodes` in `ui/src/components/sidebar-utils.ts`) — Inbox, All, Rules, Silences, History.
|
||||||
|
- **Routes** in `ui/src/router.tsx`: `/alerts`, `/alerts/inbox`, `/alerts/all`, `/alerts/history`, `/alerts/rules`, `/alerts/rules/new`, `/alerts/rules/:id`, `/alerts/silences`.
|
||||||
|
- **Pages** under `ui/src/pages/Alerts/`:
|
||||||
|
- `InboxPage.tsx` — user-targeted FIRING/ACK'd alerts with bulk-read.
|
||||||
|
- `AllAlertsPage.tsx` — env-wide list with state-chip filter.
|
||||||
|
- `HistoryPage.tsx` — RESOLVED alerts.
|
||||||
|
- `RulesListPage.tsx` — CRUD + enable/disable toggle + env-promotion dropdown (pure UI prefill, no new endpoint).
|
||||||
|
- `RuleEditor/RuleEditorWizard.tsx` — 5-step wizard (Scope / Condition / Trigger / Notify / Review). `form-state.ts` is the single source of truth (`initialForm` / `toRequest` / `validateStep`). Six condition-form subcomponents under `RuleEditor/condition-forms/`.
|
||||||
|
- `SilencesPage.tsx` — matcher-based create + end-early.
|
||||||
|
- `AlertRow.tsx` shared list row; `alerts-page.module.css` shared styling.
|
||||||
|
- **Components**:
|
||||||
|
- `NotificationBell.tsx` — polls `/alerts/unread-count` every 30 s (paused when tab hidden via TanStack Query `refetchIntervalInBackground: false`).
|
||||||
|
- `AlertStateChip.tsx`, `SeverityBadge.tsx` — shared state/severity indicators.
|
||||||
|
- `MustacheEditor/` — CodeMirror 6 editor with variable autocomplete + inline linter. Shared between rule title/message, webhook body/header overrides, and (future) Admin Outbound Connection editor (reduced-context mode for URL).
|
||||||
|
- `MustacheEditor/alert-variables.ts` — variable registry aligned with `NotificationContextBuilder.java`. Add new leaves here whenever the backend context grows.
|
||||||
|
- **API queries** under `ui/src/api/queries/`: `alerts.ts`, `alertRules.ts`, `alertSilences.ts`, `alertNotifications.ts`, `alertMeta.ts`. All env-scoped via `useSelectedEnv` from `alertMeta`.
|
||||||
|
- **CMD-K**: `buildAlertSearchData` in `LayoutShell.tsx` registers `alert` and `alertRule` result categories. Badges convey severity + state. Palette navigates directly to the deep-link path — no sidebar-reveal state for alerts.
|
||||||
|
- **Sidebar accordion**: entering `/alerts/*` collapses Applications + Admin + Starred (mirrors Admin accordion).
|
||||||
|
- **Top-nav**: `<NotificationBell />` is the first child of `<TopBar>`, sitting alongside `SearchTrigger` + status `ButtonGroup` + `TimeRangeDropdown` + `AutoRefreshToggle`.
|
||||||
|
|
||||||
## UI Styling
|
## UI Styling
|
||||||
|
|
||||||
- Always use `@cameleer/design-system` CSS variables for colors (`var(--amber)`, `var(--error)`, `var(--success)`, etc.) — never hardcode hex values. This applies to CSS modules, inline styles, and SVG `fill`/`stroke` attributes. SVG presentation attributes resolve `var()` correctly. All colors use CSS variables (no hardcoded hex).
|
- Always use `@cameleer/design-system` CSS variables for colors (`var(--amber)`, `var(--error)`, `var(--success)`, etc.) — never hardcode hex values. This applies to CSS modules, inline styles, and SVG `fill`/`stroke` attributes. SVG presentation attributes resolve `var()` correctly. All colors use CSS variables (no hardcoded hex).
|
||||||
|
|||||||
@@ -307,3 +307,54 @@ Check `GET /api/v1/environments/{envSlug}/alerts/{id}/notifications` for respons
|
|||||||
### ClickHouse projections
|
### ClickHouse projections
|
||||||
|
|
||||||
The `LOG_PATTERN` and `EXCHANGE_MATCH` evaluators use ClickHouse projections (`logs_by_level`, `executions_by_status`). On fresh ClickHouse containers (e.g. Testcontainers), projections may not be active immediately — the evaluator falls back to a full table scan with the same WHERE clause, so correctness is preserved but latency may increase on first evaluation. In production ClickHouse, projections are applied to new data immediately and to existing data after `OPTIMIZE TABLE … FINAL`.
|
The `LOG_PATTERN` and `EXCHANGE_MATCH` evaluators use ClickHouse projections (`logs_by_level`, `executions_by_status`). On fresh ClickHouse containers (e.g. Testcontainers), projections may not be active immediately — the evaluator falls back to a full table scan with the same WHERE clause, so correctness is preserved but latency may increase on first evaluation. In production ClickHouse, projections are applied to new data immediately and to existing data after `OPTIMIZE TABLE … FINAL`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## UI walkthrough
|
||||||
|
|
||||||
|
The alerting UI is accessible to any authenticated VIEWER+; writing actions (create rule, silence, ack) require OPERATOR+ per backend RBAC.
|
||||||
|
|
||||||
|
### Sidebar
|
||||||
|
|
||||||
|
A dedicated **Alerts** section between Applications and Admin:
|
||||||
|
|
||||||
|
- **Inbox** — open alerts targeted at you (state FIRING or ACKNOWLEDGED). Mark individual rows as read by clicking the title, or "Mark all read" via the toolbar. Firing rows have an amber left border.
|
||||||
|
- **All** — every open alert in the environment with state-chip filter (Open / Firing / Acked / All).
|
||||||
|
- **Rules** — the rule catalogue. Toggle the Enabled switch to disable a rule without deleting it. Delete prompts for confirmation; fired instances survive via `rule_snapshot`.
|
||||||
|
- **Silences** — active + scheduled silences. Create one by filling any combination of `ruleId` and `appSlug`, duration (hours), optional reason.
|
||||||
|
- **History** — RESOLVED alerts within the retention window (default 90 days).
|
||||||
|
|
||||||
|
### Notification bell
|
||||||
|
|
||||||
|
A bell icon in the top bar polls `/alerts/unread-count` every 30 seconds (paused when the tab is hidden). Clicking it navigates to the inbox.
|
||||||
|
|
||||||
|
### Rule editor (5-step wizard)
|
||||||
|
|
||||||
|
1. **Scope** — name, severity, and radio between environment-wide, single-app, single-route, or single-agent.
|
||||||
|
2. **Condition** — one of six condition kinds (ROUTE_METRIC, EXCHANGE_MATCH, AGENT_STATE, DEPLOYMENT_STATE, LOG_PATTERN, JVM_METRIC) with a form tailored to each.
|
||||||
|
3. **Trigger** — evaluation interval (≥5s), for-duration before firing (0 = fire immediately), re-notify cadence (minutes). Test-evaluate button when editing an existing rule.
|
||||||
|
4. **Notify** — notification title + message templates (Mustache with autocomplete), target users/groups/roles, webhook bindings (filtered to outbound connections allowed in the current env).
|
||||||
|
5. **Review** — summary card, enable toggle, save.
|
||||||
|
|
||||||
|
### Mustache autocomplete
|
||||||
|
|
||||||
|
Every template-editable field uses a shared CodeMirror 6 editor with variable autocomplete:
|
||||||
|
|
||||||
|
- Type `{{` to open the variable picker.
|
||||||
|
- Variables filter by condition kind (e.g. `route.*` is only shown when a route-scoped condition is selected).
|
||||||
|
- Unknown references get an amber underline at save time ("not available for this rule kind — will render as literal").
|
||||||
|
- The canonical variable list lives in `ui/src/components/MustacheEditor/alert-variables.ts` and mirrors the backend `NotificationContextBuilder`.
|
||||||
|
|
||||||
|
### Env promotion
|
||||||
|
|
||||||
|
Rules are environment-scoped. To replicate a rule in another env, open the source env's rule list and pick a target env from the **Promote to ▾** dropdown. The editor opens pre-filled with the source rule's values, with client-side warnings:
|
||||||
|
|
||||||
|
- Agent IDs are env-specific and get cleared.
|
||||||
|
- Apps that don't exist in the target env flag an "update before saving" hint.
|
||||||
|
- Outbound connections not allowed in the target env flag an "remove or pick another" hint.
|
||||||
|
|
||||||
|
No new REST endpoint — promotion is pure UI-driven create.
|
||||||
|
|
||||||
|
### CMD-K
|
||||||
|
|
||||||
|
The command palette (`Ctrl/Cmd + K`) surfaces open alerts and alert rules alongside existing apps/routes/exchanges. Select an alert to jump to its inbox detail; select a rule to open its editor.
|
||||||
|
|||||||
Reference in New Issue
Block a user