01 — Product Overview (Dashboard Module)
- 1. What the module is
- 2. Scope in / scope out
- 3. Caching model (target, per blueprint)
- 4. Realtime / WebSocket
- 5. Role gating (derived from default roles)
- 6. Platform & client scope notes
- 7. Goals (product)
- 8. Non-goals (per source)
Aggregated, cached operational KPIs ("widgets, statistics, and cached KPIs" —
studylyon-blueprint/04-Modules/Dashboard.md:3). Derived from the blueprint module doc,src/modules/dashboard/**,src/modules/rbac/**(permissions.constants.ts,role.schema.ts),src/infrastructure/redis/ redis-cache.service.ts,src/shared/cache/cache-service.ts,src/modules/ws/**, anddocs/IMPLEMENTATION_PLAN.md. Nothing invented; plan-only capability is marked(planned), client-only or roadmap-only(forward-looking), analytics(proposed).
1. What the module is
The Dashboard module serves pre-aggregated operational KPIs to the
authenticated client: how many active students, teachers and staff; today's
attendance summary and rate; pending invoices and total dues. Per the
blueprint, KPIs are served from Redis, never live-scanned on request
(Dashboard.md:49), rebuilt by a scheduled worker plus on relevant domain
events (Dashboard.md:50), and widget visibility is role-gated via RBAC
(Dashboard.md:52).
Two collections: dashboard_widgets (widget config) and cache-backed KPI
values (Dashboard.md:7). Domain events consumed: AttendanceMarked,
ResultPublished, PaymentRecorded, InvoiceGenerated — to invalidate /
rebuild the cache (Dashboard.md:34). Dependencies: Redis KPI store
(TTL 60 s — Dashboard.md:41), Reports module for underlying aggregates,
WebSocket push (Dashboard.md:43).
What exists in code today vs. the blueprint
| Capability | Code today | Source |
|---|---|---|
GET /api/v1/dashboard/overview | Implemented | dashboard.controller.ts:13-17 |
| KPI aggregation (students/teachers/staff/attendance/finance) | Implemented | dashboard.service.ts:18-71 |
dashboard.read, dashboard.widget.manage permissions | Defined, not enforced on the route | permissions.constants.ts:37-38; dashboard.controller.ts:8 (JwtAuthGuard only) |
| Redis-backed KPI serving (TTL 60 s) | Missing — service runs live count()/find() scans per request | dashboard.service.ts:24-38; no cache calls |
GET /attendance, GET /finance, GET /widgets, PATCH /widgets/:id | (planned) — blueprint only | Dashboard.md:24-27 |
| Cache rebuild worker + event invalidation | (planned) — no worker, no event handler | Dashboard.md:50, Dashboard.md:34 |
Widget config collection dashboard_widgets | (planned) — no schema in code | Dashboard.md:7 |
| Teacher / student / parent dashboard views | (planned) | IMPLEMENTATION_PLAN.md:232 |
| Coaching KPIs (batch fill, test scores) | (planned) (Phase 6) | IMPLEMENTATION_PLAN.md:645, :707 |
2. Scope in / scope out
| In scope | Out of scope (owned elsewhere) |
|---|---|
| KPI aggregation: students, teachers, staff, attendance, finance | Raw attendance marking → Attendance module |
Cached overview contract + tenant-scoped cache keys (sl:{tenantId}:…) | Invoice lifecycle → Fees module |
Role-gated visibility (blueprint rule Dashboard.md:52) | Report generation → Reports module |
WS-driven cache invalidation hints (existing WsBridge) | Realtime delivery → WsModule (ws.gateway.ts) |
Widget customization (planned) | Push notifications / QR features (forward-looking) |
3. Caching model (target, per blueprint)
- Cache key namespaced by tenant:
sl:{tenantId}:dashboard:{scope}— theRedisCacheServiceprefixes every key with the current tenant automatically (redis-cache.service.ts:16-19), falling back toplatform(redis-cache.service.ts:17). - TTL 60 s per blueprint (
Dashboard.md:41). - Invalidation triggers:
AttendanceMarked,ResultPublished,PaymentRecorded,InvoiceGenerated(Dashboard.md:34). - Gap:
DashboardService.getOverview()performs live repo scans on every request (dashboard.service.ts:24-38) and never touches the cache. The UI must be built against the blueprint contract, with the live-scan behaviour treated as a temporary implementation detail (see 14_QA_Checklist.md §3).
4. Realtime / WebSocket
The existing WsGateway authenticates via JWT and joins the client to
tenant:{tenantId} on connect (ws.gateway.ts:42-50); WsBridge broadcasts
every domain event to that room (ws-bridge.service.ts:16-22). The
dashboard client can therefore listen for the four KPI-affecting event types
and trigger a cache-bypassing refresh. A server push of fresh KPI payloads
over WS is (forward-looking) — today the events carry event metadata, not
re-aggregated values (ws-bridge.service.ts:17-21).
5. Role gating (derived from default roles)
dashboard.read (permissions.constants.ts:37) and dashboard.widget.manage
(permissions.constants.ts:38) are granted by default to org_admin only
(role.schema.ts:23 — permissions: ALL_PERMISSIONS). The other default
roles carry no dashboard permissions: teacher :31, staff :39, accountant
:47, parent :55, student :63 (empty). platform_admin is cross-tenant
with an empty explicit list (:15).
Consequence: today the dashboard renders for the org admin; every other
role sees nothing until the tenant assigns them a role that includes
dashboard.read, or the server ships role-specific views (planned)
(IMPLEMENTATION_PLAN.md:232). The screens below therefore assume a
permission-filtered widget set (blueprint Dashboard.md:52), and
role-restricted finance widgets are enforced at the data layer (planned).
6. Platform & client scope notes
- Native mobile apps are excluded from Phase 1 of the PRD ("Native mobile
apps (web-first)",
PRODUCT_REQUIREMENTS_DOCUMENT.md:144, as referenced indesign-docs/users/01_Product_Overview.md:183-189); the shared ledger flags the whole Flutter design set as(forward-looking)(00-shared/12 A1). All screens here target the web-first responsive client and are(forward-looking)by extension. - API is
v1, Bearer JWT, tenant from token only (00-shared/07 §1,§6); wire contract per 00-shared/07 §2-§3. - Period selectors for charts, push of "dues due today", QR access:
(forward-looking); analytics(proposed)(00-shared/12 A4 — SDK open).
7. Goals (product)
- Admin gets the day at a glance — active students, teachers, staff, today's attendance %, pending invoices and dues in one screen, from cache, within one request.
- Numbers stay fresh without hammering MongoDB — 60 s TTL + event-driven
invalidation (blueprint
Dashboard.md:49-50). - Role-appropriate visibility — each role sees only the widgets its
permissions allow (blueprint
Dashboard.md:52). - Widget customization for admins
(planned)— arrange / toggle widgets (dashboard.widget.manage,IMPLEMENTATION_PLAN.md:232).
8. Non-goals (per source)
- No live DB scanning on request — blueprint rule (
Dashboard.md:49). - No report generation here (Reports module owns aggregates).
- No attendance/finance CRUD from the dashboard (thin links to modules).
- No realtime KPI push channel today — only event hints
(forward-looking). - No coaching-specific KPIs until Phase 6 (
IMPLEMENTATION_PLAN.md:645).