SafeWatch Modules¶
KPI Dashboards¶
Each role lands on their dashboard after login. Route is determined by role claim.
sys_admin (/safewatch/sysadmin):
- API error rate (4xx+5xx / total requests, last 24h) — from api_request_events
- Average response time by route (top 10 slowest) — from api_request_events
- Requests per hour (sparkline, last 24h) — from api_request_events
- Auth failure count (last 24h) — from auth_events where success = false
- Top error routes (table: route, count, avg duration) — from api_request_events
product (/safewatch/product):
- DAU / WAU / MAU (distinct user_ids in period) — from api_request_events
- Sessions uploaded per day (7d sparkline) — from session_events
- Coach queries per day (7d sparkline) — from ai_events
- Leaderboard submissions per day — from leaderboard_events
- Feature usage breakdown (pie: sessions vs coach vs leaderboard) — from all three tables
support (/safewatch/support):
- Recent registrations (last 10) — from auth_events where action = 'register'
- Recent auth failures (last 10, with failure_reason) — from auth_events
- Most active users today (top 10 by request count) — from api_request_events
- Quick user search by user_id → links to User Explorer
ceo (/safewatch/ceo):
- MAU (current month distinct users) — from api_request_events
- Total registered users (cumulative) — from auth_events where action = 'register'
- Conversion rate: registered → first session uploaded (users with ≥1 session_event / total registered)
- AI usage cost total (last 30d) — from ai_events.cost_usd sum
- Retention proxy D7: users who registered in the last 30d AND had at least one event ≥7 days after their registration date (D7 retained); same logic for D30
- Volume trend (sessions + coach queries + leaderboard, 30d bar chart)
- Billing KPIs (MRR, ARR, churn, paying users): shown as "— available when billing is integrated"
Event Explorer (/safewatch/events)¶
Filterable, paginated table of all events across all 5 tables.
Filters: - Table (all / api_requests / auth / sessions / ai / leaderboard) - User ID (text input) - Time range (TimeRangePicker component) - Status / action (contextual per table)
Columns: timestamp, table, user_id, action/route, key metadata (varies by table), status.
Pagination: 50 rows per page, server-side. Newest first.
User Explorer (/safewatch/users/{userId?})¶
Search by user_id → full chronological event timeline for that user across all 5 tables.
Timeline entries show: timestamp, event type (colour-coded by table), action/route, key fields.
If no user_id in URL: shows search box. On submit: navigates to /safewatch/users/{userId}.
Feature Analytics (/safewatch/features)¶
Three feature usage metrics, selectable time range (7d / 30d / 90d):
- Adoption: unique users who used each feature (sessions, coach, leaderboard) as % of MAU
- Volume: daily usage count per feature (stacked bar chart)
- Abandon rate: (for coach queries) requests where no subsequent event within 5 min — proxy for failed/abandoned queries
Data sources: session_events, ai_events, leaderboard_events.
Funnels (/safewatch/funnels)¶
Two pre-defined funnels (not configurable in this phase):
Onboarding funnel:
1. Registered (auth_events register)
2. First login (auth_events login_success, after register)
3. First session uploaded (session_events session_uploaded, first per user)
4. First coach query (ai_events coach_query, first per user)
5. First leaderboard submission (leaderboard_events lap_submitted, first per user)
Shows: count and % drop-off at each step. Time range: last 30d / 90d / all time.
Activation funnel: 1. Registered 2. Session uploaded within 7 days of registration 3. Coach query within 7 days of registration
Alerts Center (/safewatch/alerts)¶
Rule-based anomaly detection computed on each page load (no background job in this phase).
Alert rules (all thresholds configurable in appsettings):
- Error rate spike: 4xx+5xx > 5% of requests in last 1h (vs baseline last 7d)
- Auth failure spike: > 10 failures in any 5-minute window (last 1h)
- AI cost spike: total cost_usd in last 1h > $1.00
- No activity: 0 API requests in last 30 min (potential outage)
Each alert shows: severity (warning / critical), description, affected metric, timestamp of detection, and a link to the relevant Explorer page.
Global Search (/safewatch/search)¶
Single search box. Searches in parallel:
- Users: matches user_id prefix in any event table → links to User Explorer
- Events: full-text match on route (api_requests), action (auth/session/ai/leaderboard) — returns top 20 most recent matching events
- No free-text search into event metadata fields (too broad; filtered views are the correct tool)