diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 54eb016..e9f47fb 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -18,7 +18,7 @@ Requirements for initial release. Each maps to roadmap phases. - [x] **ALRT-01**: Admin receives email alert when a service goes down or degrades - [x] **ALRT-02**: Alert deduplication prevents repeat emails for the same ongoing issue (cooldown period) -- [ ] **ALRT-03**: Admin sees in-app alert banner for active critical issues +- [x] **ALRT-03**: Admin sees in-app alert banner for active critical issues - [x] **ALRT-04**: Alert recipient stored as configuration, not hardcoded ### Processing Analytics @@ -89,7 +89,7 @@ Which phases cover which requirements. Updated during roadmap creation. | INFR-02 | Phase 3 | Complete | | HLTH-01 | Phase 3 | Complete | | ANLY-02 | Phase 3 | Complete | -| ALRT-03 | Phase 4 | Pending | +| ALRT-03 | Phase 4 | Complete | **Coverage:** - v1 requirements: 15 total diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 4fb9619..b142275 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -77,7 +77,7 @@ Plans: 2. The admin dashboard shows health status indicators (green/yellow/red) for all four services, with the last-checked timestamp visible 3. The admin dashboard shows processing metrics (upload counts, success/failure rates, average processing time) sourced from the persistent Supabase backend 4. A non-admin user visiting the admin route is redirected or shown an access-denied state -**Plans:** 2 plans +**Plans:** 1/2 plans executed Plans: - [ ] 04-01-PLAN.md — AdminService monitoring methods + AlertBanner + AdminMonitoringDashboard components @@ -93,4 +93,4 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 | 1. Data Foundation | 2/2 | Complete | 2026-02-24 | | 2. Backend Services | 4/4 | Complete | 2026-02-24 | | 3. API Layer | 2/2 | Complete | 2026-02-24 | -| 4. Frontend | 0/TBD | Not started | - | +| 4. Frontend | 1/2 | In Progress| | diff --git a/.planning/STATE.md b/.planning/STATE.md index 9828bc0..bb22aef 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -5,16 +5,16 @@ See: .planning/PROJECT.md (updated 2026-02-24) **Core value:** When something breaks — an API key expires, a service goes down, a credential needs reauthorization — the admin knows immediately and knows exactly what to fix. -**Current focus:** Phase 3 — API Layer +**Current focus:** Phase 4 — Frontend ## Current Position -Phase: 3 of 4 (API Layer) -Plan: 2 of 4 in current phase +Phase: 4 of 4 (Frontend) +Plan: 2 of 2 in current phase Status: In Progress -Last activity: 2026-02-24 — Completed 03-02 (analytics instrumentation in processJob) +Last activity: 2026-02-24 — Completed 04-01 (adminService monitoring methods, AlertBanner, AdminMonitoringDashboard) -Progress: [███████░░░] 70% +Progress: [█████████░] 90% ## Performance Metrics @@ -36,6 +36,7 @@ Progress: [███████░░░] 70% *Updated after each plan completion* | Phase 03-api-layer P01 | 8 | 2 tasks | 4 files | +| Phase 04-frontend P01 | 2 | 2 tasks | 3 files | ## Accumulated Context @@ -71,6 +72,9 @@ Recent decisions affecting current work: - [Phase 03-api-layer]: requireAdminEmail returns 404 not 403 — does not reveal admin routes exist - [Phase 03-api-layer]: getPostgresPool() used for aggregate SQL — Supabase JS client does not support COUNT/AVG - [Phase 03-api-layer]: Admin env vars read inside function body not module level — Firebase Secrets timing constraint +- [Phase 04-frontend]: AlertBanner filters to active service_down/service_degraded only — recovery type is informational, not critical +- [Phase 04-frontend]: AlertEvent uses snake_case (backend raw model), ServiceHealthEntry/AnalyticsSummary use camelCase (backend admin.ts remaps) +- [Phase 04-frontend]: AdminMonitoringDashboard is self-contained with no required props ### Pending Todos @@ -84,5 +88,5 @@ None yet. ## Session Continuity Last session: 2026-02-24 -Stopped at: Completed 03-01-PLAN.md — admin API endpoints (GET /health, GET /analytics, GET /alerts, POST /alerts/:id/acknowledge) with requireAdminEmail middleware. +Stopped at: Completed 04-01-PLAN.md — adminService monitoring methods (getHealth, getAnalytics, getAlerts, acknowledgeAlert), AlertBanner component, AdminMonitoringDashboard component. Resume file: None diff --git a/.planning/phases/04-frontend/04-01-SUMMARY.md b/.planning/phases/04-frontend/04-01-SUMMARY.md new file mode 100644 index 0000000..02e1564 --- /dev/null +++ b/.planning/phases/04-frontend/04-01-SUMMARY.md @@ -0,0 +1,111 @@ +--- +phase: 04-frontend +plan: 01 +subsystem: ui +tags: [react, typescript, tailwind, lucide-react, axios] + +# Dependency graph +requires: + - phase: 03-api-layer + provides: "GET /admin/health, GET /admin/analytics, GET /admin/alerts, POST /admin/alerts/:id/acknowledge endpoints" +provides: + - "AdminService typed methods: getHealth(), getAnalytics(range), getAlerts(), acknowledgeAlert(id)" + - "AlertEvent, ServiceHealthEntry, AnalyticsSummary TypeScript interfaces" + - "AlertBanner component: critical active alert display with per-alert acknowledge button" + - "AdminMonitoringDashboard component: service health grid + analytics summary with range selector" +affects: + - 04-02 (wires AlertBanner and AdminMonitoringDashboard into App.tsx Dashboard) + +# Tech tracking +tech-stack: + added: [] + patterns: + - "useCallback + useEffect for data fetching with re-fetch on state dependency changes" + - "Promise.all for concurrent independent API calls" + - "Optimistic UI: AlertBanner onAcknowledge pattern is defined at the parent level to filter local state immediately" + - "Status dot pattern: w-3 h-3 rounded-full with Tailwind bg-color for health indicators" + +key-files: + created: + - frontend/src/components/AlertBanner.tsx + - frontend/src/components/AdminMonitoringDashboard.tsx + modified: + - frontend/src/services/adminService.ts + +key-decisions: + - "AlertBanner filters to active service_down/service_degraded only — recovery type is informational, not critical (per RESEARCH Pitfall)" + - "AlertEvent uses snake_case fields (backend returns raw model data), ServiceHealthEntry/AnalyticsSummary use camelCase (backend admin.ts remaps)" + - "AdminMonitoringDashboard has no required props — self-contained component that fetches its own data" + +patterns-established: + - "Monitoring dashboard pattern: health grid + analytics stat cards in same component" + - "Alert banner pattern: top-level conditional render, filters by status=active AND critical alert_type" + +requirements-completed: + - ALRT-03 + - ANLY-02 + - HLTH-01 + +# Metrics +duration: 2min +completed: 2026-02-24 +--- + +# Phase 04 Plan 01: Monitoring Service Layer and Components Summary + +**AdminService extended with typed monitoring API methods plus AlertBanner and AdminMonitoringDashboard React components ready for mounting in App.tsx** + +## Performance + +- **Duration:** 2 min +- **Started:** 2026-02-24T21:33:40Z +- **Completed:** 2026-02-24T21:35:33Z +- **Tasks:** 2 +- **Files modified:** 3 + +## Accomplishments + +- Extended `adminService.ts` with three new exported TypeScript interfaces (AlertEvent, ServiceHealthEntry, AnalyticsSummary) and four new typed API methods (getHealth, getAnalytics, getAlerts, acknowledgeAlert) +- Created `AlertBanner` component that filters alerts to active critical types only and renders a red banner with per-alert acknowledge buttons +- Created `AdminMonitoringDashboard` component with a 1x4 service health card grid (colored status dots) and a 1x5 analytics stat card panel with range selector and refresh button + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: Extend adminService with monitoring API methods and types** - `f84a822` (feat) +2. **Task 2: Create AlertBanner and AdminMonitoringDashboard components** - `b457b9e` (feat) + +## Files Created/Modified + +- `frontend/src/services/adminService.ts` - Added AlertEvent, ServiceHealthEntry, AnalyticsSummary interfaces and getHealth(), getAnalytics(), getAlerts(), acknowledgeAlert() methods +- `frontend/src/components/AlertBanner.tsx` - New component rendering red banner for active service_down/service_degraded alerts with X Acknowledge buttons +- `frontend/src/components/AdminMonitoringDashboard.tsx` - New component with service health grid and processing analytics panel with range selector + +## Decisions Made + +- AlertBanner renders only `status === 'active'` alerts of type `service_down` or `service_degraded`; `recovery` alerts are filtered out as informational +- Type casing follows backend API response shapes exactly: AlertEvent is snake_case (raw model), ServiceHealthEntry/AnalyticsSummary are camelCase (backend admin.ts remaps them) +- AdminMonitoringDashboard is self-contained with no required props, following existing Analytics.tsx pattern + +## Deviations from Plan + +None - plan executed exactly as written. + +## Issues Encountered + +None. + +## User Setup Required + +None - no external service configuration required. + +## Next Phase Readiness + +- All three files are ready to import in Plan 02 (App.tsx wiring) +- AlertBanner expects `alerts: AlertEvent[]` and `onAcknowledge: (id: string) => Promise` — parent must manage alert state and provide optimistic acknowledge handler +- AdminMonitoringDashboard has no required props — drop-in for the monitoring tab + +--- +*Phase: 04-frontend* +*Completed: 2026-02-24*