feat(admin): analytics dashboard (DAU/MAU/messages/rooms/signups) (LC-97) #159

Merged
nrupard merged 1 commit from feat/lc-97-admin-analytics into main 2026-05-20 16:28:33 +02:00
Owner

Summary

Adds an admin analytics dashboard at /admin/analytics (LC-97). Daily metrics are pre-aggregated into a new analytics_daily table (chat.db) by a background aggregator, so the dashboard renders from a handful of indexed reads instead of scanning the messages table on every page load.

What's included

  • Metrics: messages per day, DAU, MAU (rolling 30d), active rooms, new signups. DAU/MAU = distinct message senders, derivable from history so a fresh install backfills its full history on first startup. Counts only; no per-user activity is stored or shown. Soft-deleted and system messages excluded.
  • Background aggregator (spawn_analytics_aggregator): backfills every day since the install's earliest activity at startup, then ticks hourly to keep today fresh.
  • On-demand recompute: "Recompute today" button.
  • Charts: server-side inline SVG line charts (area fill + axis labels). Zero chart JS; stays fully server-rendered.
  • Retention triangle: weekly signup cohorts vs. percent still posting each subsequent week, computed on demand (auth.db cohorts joined to chat.db activity), bounded to the most recent 8 cohorts.
  • Date range filter: 7 / 30 / 90 days.
  • Nav: "Analytics" link added to the admin layout.

Scope notes

  • Standalone build writes only the global rollup. analytics_daily carries scope_kind/scope_id so a future SaaS build can add per-enclave breakdowns without a migration.
  • Bot exclusion from DAU/MAU is a no-op today because LC-73 bot flagging is not yet in the schema. The DAU/MAU definition is ready to add a bot filter once that column lands.

Tests

server/tests/routes_analytics.rs: recompute counts (messages/DAU/active rooms), soft-delete + system-message exclusion, signup metric via backfill, dashboard render (200 + SVG + retention), recompute redirect (303), and the non-admin (403) / anonymous (303) auth gate. Migration 0035_analytics_daily.sql added to the hand-rolled migration lists in the affected test harnesses. just check, just test, and just check-server-saas all green.

🤖 Generated with Claude Code

## Summary Adds an admin analytics dashboard at `/admin/analytics` (LC-97). Daily metrics are pre-aggregated into a new `analytics_daily` table (chat.db) by a background aggregator, so the dashboard renders from a handful of indexed reads instead of scanning the messages table on every page load. ## What's included - **Metrics**: messages per day, DAU, MAU (rolling 30d), active rooms, new signups. DAU/MAU = distinct message senders, derivable from history so a fresh install backfills its full history on first startup. Counts only; no per-user activity is stored or shown. Soft-deleted and system messages excluded. - **Background aggregator** (`spawn_analytics_aggregator`): backfills every day since the install's earliest activity at startup, then ticks hourly to keep today fresh. - **On-demand recompute**: "Recompute today" button. - **Charts**: server-side inline SVG line charts (area fill + axis labels). Zero chart JS; stays fully server-rendered. - **Retention triangle**: weekly signup cohorts vs. percent still posting each subsequent week, computed on demand (auth.db cohorts joined to chat.db activity), bounded to the most recent 8 cohorts. - **Date range filter**: 7 / 30 / 90 days. - **Nav**: "Analytics" link added to the admin layout. ## Scope notes - Standalone build writes only the global rollup. `analytics_daily` carries `scope_kind`/`scope_id` so a future SaaS build can add per-enclave breakdowns without a migration. - Bot exclusion from DAU/MAU is a no-op today because LC-73 bot flagging is not yet in the schema. The DAU/MAU definition is ready to add a bot filter once that column lands. ## Tests `server/tests/routes_analytics.rs`: recompute counts (messages/DAU/active rooms), soft-delete + system-message exclusion, signup metric via backfill, dashboard render (200 + SVG + retention), recompute redirect (303), and the non-admin (403) / anonymous (303) auth gate. Migration `0035_analytics_daily.sql` added to the hand-rolled migration lists in the affected test harnesses. `just check`, `just test`, and `just check-server-saas` all green. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(admin): analytics dashboard with DAU/MAU/messages/rooms/signups + retention (LC-97)
Some checks failed
Check / clippy + fmt + tests (pull_request) Failing after 21s
d6d3922545
Add an admin analytics dashboard at /admin/analytics. Metrics are pre-aggregated daily into a new `analytics_daily` table (chat.db) by a background aggregator, so the dashboard renders from a handful of indexed reads instead of scanning the messages table on every page load.

Metrics: messages per day, daily active users (DAU), monthly active users (MAU, rolling 30d), active rooms, and new signups. DAU/MAU are defined as distinct message senders, which is derivable from historical data so a fresh install backfills its entire history on first startup. Only counts are stored or rendered; no per-user activity is exposed. Soft-deleted and system messages are excluded.

The aggregator backfills every day since the install's earliest activity at startup, then ticks hourly to keep the current day fresh. Admins can force a recompute of today's metrics from the dashboard.

Charts are rendered server-side as inline SVG (line charts with area fill and axis labels), so the page ships zero chart JS and stays fully server-rendered like the rest of the app. A retention triangle (weekly signup cohorts vs. percent still posting in each subsequent week) is computed on demand from auth.db cohort membership joined to chat.db message activity, bounded to the most recent 8 cohorts.

Scope: the standalone build writes only the global rollup. The `analytics_daily` schema carries scope_kind/scope_id columns so a future SaaS build can store per-enclave breakdowns without a migration. Bot exclusion from DAU/MAU is a no-op today because LC-73 bot flagging is not yet in the schema.

Tests: server/tests/routes_analytics.rs covers the recompute counts, soft-delete/system exclusion, signup metric, dashboard render, recompute redirect, and the admin/anonymous auth gate. Migration 0035 added to the hand-rolled migration lists in the affected test harnesses.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
nrupard deleted branch feat/lc-97-admin-analytics 2026-05-20 16:28:34 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/lets-chat!159
No description provided.