wulf-pulse/.planning/phases/03-dashboard-restyle/03-01-SUMMARY.md
lorentz 9658640c04 fix(04-01): restore phase 2/3 work lost by worktree soft-reset
The soft reset to 77073ba inadvertently staged deletions of all phase 2
and 3 artifacts. This commit restores them from their source commits so
subsequent task commits build on the complete prior-phase foundation:
- components/mobile/{BottomNav,HeaderBar,KpiCardMobile,MoreDrawer,NeedsAttentionStrip,WorkerStatusRow}
- app/mobile/layout.tsx, dashboard/page.tsx, analyzer/page.tsx
- app/api/mobile/dashboard/route.ts
- All .planning/** files from phases 01-04
- CLAUDE.md, app/layout.tsx, app/styles/brand.css, public/manifest.json
2026-05-03 18:01:14 -04:00

6.4 KiB

phase plan subsystem tags requires provides affects tech-stack key-files key-decisions patterns-established requirements-completed duration completed
03-dashboard-restyle 01 api, ui
mobile
dashboard
nextjs
postgres
tailwind
shadcn
lucide
phase provides
02-mobile-shell-more-drawer mobile layout shell (HeaderBar, BottomNav, MoreDrawer) that wraps all /mobile/* pages
GET /api/mobile/dashboard returning MobileDashboardResponse (kpis, needsAttention, workers)
KpiCardMobile component (phone-sized KPI card, tone-aware destructive border)
NeedsAttentionStrip component (horizontal-scroll strip of compact attention cards)
WorkerStatusRow component (3-cell worker/backup status row with status dot indicators)
03-02 (plan 02 wires these components into app/mobile/dashboard/page.tsx)
added patterns
Mobile API endpoint: single Promise.all with 6 parameterless queries, company_scope exclusion filter, manual snake→camel transform
Mobile component comment block: /* ComponentName — phase 03 (DASH-XX). */ header with purpose description
Tone-aware KPI card: TONE_BORDER record maps tone to Tailwind border class
Worker status derivation: down if fail_1h>0 and in_flight=0, warn if fail_1h>0, ok otherwise
created modified
components/mobile/KpiCardMobile.tsx
components/mobile/NeedsAttentionStrip.tsx
components/mobile/WorkerStatusRow.tsx
app/api/mobile/dashboard/route.ts
Reused sla_breaches integer from KPI query for overdue_tickets count in needsAttention — avoids a 7th query
Default export import (not named) for postgresClient matches app/api/dashboard/overview/route.ts reference route pattern
captions left undefined for now — plan 02 can add vs-yesterday deltas without an API change
Mobile endpoint pattern: requireAuth at top, single Promise.all, typed query generics, manual int parse with ?? '0' fallback
Mobile component pattern: 'use client'; /* Name — phase NN (REQ-NN). */ block, pure presentational, no fetch
DASH-01
DASH-02
DASH-03
18min 2026-05-03

Phase 3 Plan 1: Dashboard API + Presentational Components Summary

Mobile dashboard API reshaped to return kpis/needsAttention/workers in a single round-trip, plus three presentational components (KpiCardMobile, NeedsAttentionStrip, WorkerStatusRow) ready for plan 02 to wire into the page.

Performance

  • Duration: ~18 min
  • Started: 2026-05-03T00:00:00Z
  • Completed: 2026-05-03T00:18:00Z
  • Tasks: 2
  • Files modified: 4 (1 rewritten, 3 created)

Accomplishments

  • Rewrote app/api/mobile/dashboard/route.ts to return MobileDashboardResponse (4 KPIs, 3 Needs Attention items, 3 worker entries) in a single Promise.all of 6 parameterless queries
  • Exported 4 TypeScript interfaces (KpiResponse, AttentionResponse, WorkerResponse, MobileDashboardResponse) so plan 02 can import type them without re-exploring the codebase
  • Created KpiCardMobile — phone-sized KPI card with optional destructive left border for tone='attention' (SLA breaches)
  • Created NeedsAttentionStrip — horizontal-scroll snap strip of compact attention cards, renders null when empty
  • Created WorkerStatusRow — 3-cell status row with emerald/amber/destructive status dots, each a next/link to the corresponding admin page

Response Shape

export interface MobileDashboardResponse {
  kpis: KpiResponse[];         // 4 entries: open_total, opened_today, resolved_today, sla_breaches
  needsAttention: AttentionResponse[]; // 3 entries: overdue_tickets, failed_backups, stalled_workflows
  workers: WorkerResponse[];   // 3 entries: analyzer, rmm, backup_success_rate
}

Component Export Signatures

// KpiCardMobile.tsx
export type KpiTone = 'default' | 'attention';
export function KpiCardMobile({ label, value, caption, tone }: KpiCardMobileProps): JSX.Element

// NeedsAttentionStrip.tsx
export interface NeedsAttentionItem { id, label, count, href }
export function NeedsAttentionStrip({ items }: NeedsAttentionStripProps): JSX.Element | null

// WorkerStatusRow.tsx
export type WorkerStatus = 'ok' | 'warn' | 'down';
export interface WorkerStatusEntry { id, label, value, status, href }
export function WorkerStatusRow({ entries }: WorkerStatusRowProps): JSX.Element

Task Commits

  1. Task 1: Rewrite /api/mobile/dashboard to return kpis/needsAttention/workers shape - 24e20c7 (feat)
  2. Task 2: Add KpiCardMobile, NeedsAttentionStrip, WorkerStatusRow components - bfe9549 (feat)

Files Created/Modified

  • app/api/mobile/dashboard/route.ts — Completely rewritten; exports 4 interfaces + GET handler returning MobileDashboardResponse
  • components/mobile/KpiCardMobile.tsx — New; phone-sized KPI card with tone-aware destructive left border
  • components/mobile/NeedsAttentionStrip.tsx — New; horizontal-scroll attention strip with snap-x
  • components/mobile/WorkerStatusRow.tsx — New; 3-cell worker/backup status row with color-coded dots

Decisions Made

  • Reuse sla_breaches for overdue_tickets: The overdue_tickets count in needsAttention is the same value as sla_breaches in kpis — computed from the same KPI query row, avoiding a 7th query.
  • Default postgresClient import: Used import postgresClient from '@/lib/services/postgres-client' (default export) to match app/api/dashboard/overview/route.ts reference route, not the named export used in the old mobile route.
  • Captions deferred: caption fields on KpiResponse are left undefined for now; plan 02 can add vs-yesterday deltas without an API shape change.

Deviations from Plan

None - plan executed exactly as written.

Issues Encountered

None.

Known Stubs

None — all data flows are wired to live DB queries.

Threat Flags

No new security surface introduced. The /api/mobile/dashboard endpoint was already an existing route; it now enforces requireAuth() (T-03-01) and applies the company_scope exclusion on all ticket queries (T-03-02), both as specified in the plan's threat model.

Next Phase Readiness

  • Plan 02 (03-02) can immediately import MobileDashboardResponse, KpiCardMobile, NeedsAttentionStrip, and WorkerStatusRow — no codebase exploration needed
  • No blockers. app/mobile/dashboard/page.tsx untouched as required (reserved for plan 02)

Phase: 03-dashboard-restyle Completed: 2026-05-03