Table of Contents
15 — Coach dashboard and practice analytics
Technical reference. For task-based help, see the corresponding user guide.
Documentation status: complete for the current implementation
Reviewed: 2026-07-21
Primary users: coaches
Surfaces: coach admin portal, mobile coach workspace and platform API
Purpose
The coach dashboard combines the live caseload with practice-level counts and profile insights. It helps a coach answer three different questions without exposing former-family records:
- Who is on my current list and needs attention now?
- How many families were active or started in a chosen period?
- What broad profile and sleep/logging patterns exist across the practice?
The mobile and admin clients do not currently expose the same depth. Both use the same trusted roster and analytics endpoint, but mobile emphasises live family operations while the coach portal presents date-controlled practice cards and profile charts.
User outcomes
| Surface | Outcome |
|---|---|
| Mobile coach workspace | See current families, support status, today's sleep, a running sleep timer, recent/unseen activity, alert state and fast family actions. |
| Mobile family picker | Search, filter and sort the roster; compare active/current/supported/all-time summary counts; open session prep, view-as or messaging. |
| Coach portal dashboard | Compare Current, Active, New and Worked with counts; inspect calculation copy and eligible family detail; view profile and age-cohort charts. |
| Platform API | Produce assignment-window-bounded aggregates for counts, attention, engagement, sleep and profile insights without restoring former-family detail access. |
Entry points
| Surface | Route/area | Function |
|---|---|---|
| Mobile | /coach | Operational dashboard and assigned-family cards. |
| Mobile | /coach/families | Full family picker and practice summary. |
| Coach portal | Dashboard home | Practice-health cards and profile analytics. |
| Platform | GET /coach/dashboard-analytics | Date-window analytics contract. |
What is visible today
Mobile dashboard
The mobile dashboard is primarily operational. A family card can show:
- family and baby names, support status and team label;
- unread family-activity count when that rollout-gated feature is enabled;
- total attributed sleep today and any currently running sleep timer;
- support-period summary and remaining time;
- configure dates, pause/resume support, mute/unmute activity alerts and revoke actions; and
- entry to family view-as, session prep and chat when those features are eligible.
The family picker adds search, team-label filter, sortable columns and a period selector for This month, Last month, All time or a custom inclusive date range. Its summary distinguishes:
| Mobile metric | Calculation |
|---|---|
| Active now | Current families whose support is running now; paused, not-started and former families are excluded. |
| Current | Families on the current list, including active, paused and not-started support. Expired support is handled separately; revoked families are excluded. |
| Supported in period | Current families whose support interval overlaps the selected period. |
| Supported all time | An anonymized aggregate from platform analytics; past families are not listed or opened. |
Coach portal analytics
The portal defaults to Past 30 days and also supports a calendar month, all time, or a custom range.
| Card | Calculation | Family detail |
|---|---|---|
| Current | Today's normal current client list: active, paused and not-started support. The date selector does not change it. | Current accessible names can be shown. |
| Active | Distinct families whose support was active at any point in the selected half-open window. | Only families still current can appear by name. |
| New | Families whose effective support start falls within the selected window. | Only families still current can appear by name. |
| Worked with | Distinct families across all assignments for this coach. | Count is historical; former-family names are intentionally suppressed. |
Every metric card opens a dialog with How it is calculated, contextual notes and the family details that remain authorized.
The visible profile section provides independently selectable Current and All scope for:
- child gender (boy, girl, other and unknown in the contract; the chart currently plots boy/girl);
- co-sleeping (with, without and unknown);
- feeding method (breastfed, bottle-fed, mixed and unknown); and
- age cohorts: under 6 months, 6–12 months, 12–24 months and 24 months plus.
Age is anchored at baby-profile creation, not recalculated as the baby ages through the dashboard. Cohort sleep averages are calculated only with available logged sleep data.
Date and inclusion rules
sinceis inclusive anduntilis exclusive. A portal custom end date is converted to midnight on the following UTC day.- If both are supplied,
untilmust be later thansince. - An assignment is in a selected range when its effective support interval overlaps that range.
- Activity is counted only inside the coach's assignment/support window for that family. Logs before assignment or after effective end cannot influence that coach's result.
- Babies and profile data are scoped to families the coach worked with; personally identifying detail is filtered again before response.
- “Last seven days” service calculations use completed UTC-day windows where specified. The portal's selected range and the fixed operational lookbacks are separate concepts.
- Counts are distinct by family where the metric is family-based; repeated assignments do not create a readable former-family roster.
Sparse-data and privacy rules
There are two distinct safeguards:
- Historical-detail suppression: all-time/current-vs-all aggregates may include ended relationships, but all detail arrays are filtered to family identifiers that are still current. The API can say “12 families worked with” without returning the names of former families.
- Age-cohort minimum sample: a cohort must contain at least three families before its average night wakings, average nap count or family detail is returned. Below that threshold the family count remains visible,
hasEnoughSampleis false and averages are null.
These safeguards are enforced in the platform response. Hiding a modal or chart in the client is not the privacy boundary.
Additional platform-calculated analytics
The shared response currently contains more calculated sections than CoachDashboardAnalyticsPanel renders. They are part of the platform contract and may support future presentation, but they should not be described to users as visible portal cards today.
| Contract section | Current calculation |
|---|---|
| Attention | For current families: no activity in 7 days, no sleep in 7 days, setup incomplete because no baby exists, or average sleep duration down by at least 30 minutes between the previous and recent 7-day windows. The decline signal needs at least two usable sleeps in each window. |
| Logging consistency | Across the last 7 completed UTC days: percent logging on every day, rounded logs per family/week, families with at least one sleep + feed + nappy log, and “quiet” families with fewer than 3 logs. |
| Family engagement | Current families active today, active in 7 days, onboarded in 7 days, and ending support within the next 14 days. |
| Sleep improvement | First-versus-recent 7-day night waking, longest-night, total-night-sleep and bedtime-consistency aggregates when sufficient sleep intervals exist. Missing data remains null rather than zero. |
| Coach impact | Completed-support start/end waking comparison; families improving or plateauing week over week; average change in night sleep since assignment; first full night, fewer wakes and longer naps. Thresholds include an 8-hour full night, 1 fewer wake, 30 more night minutes or 15 more nap minutes where applicable. |
| Age cohorts | Family count plus average night wakings and nap count for four profile-age bands, subject to the three-family threshold. |
| Feeding/sleep correlation | Nights with/without feeds and wakes, last feed-to-bed gap within a 6-hour lookback, and longest-night stretch grouped by breastfed, bottle-fed or mixed signals. |
| Demographics | Child gender, co-sleeping and observed feeding method, each available for current or all-family aggregate scope. |
These are descriptive operational signals derived from logged data. They are not clinical diagnoses, causal claims or proof of coach effectiveness.
Platform API contract
| Method and path | Query | Result |
|---|---|---|
GET /coach/dashboard-analytics | Optional ISO since and until; until is exclusive. | generatedAt, normalized window, top-line metrics, detail arrays, operational analytics and scopes.current / scopes.all. |
GET /coach/families | scope is accepted; current production roster semantics are detailed in Feature 16. | Live family/invitation data used as the operational fallback and Current count. |
Authorization and privacy rules
- The endpoint requires a coach actor and selects only assignments owned by that coach in organizations where the coach has active membership.
- Tenant and assignment constraints are applied before aggregation; the client never sends a trusted organization or coach identifier.
- Activities outside the assignment/support interval are excluded even if the row still exists in the platform database.
- Former-family aggregate contribution does not restore access to former names, email addresses, babies or activity records.
- Family detail can include name, email and baby names only for currently visible families and only inside the coach response.
- Coach-private note bodies are not inputs to dashboard analytics.
- Null means insufficient/no usable data; clients must not render null averages as zero performance.
Loading and failure states
| State | Expected behavior |
|---|---|
| Initial portal query | Show metric placeholders while the selected range loads. |
| Range changed | Clear stale analytics and load the new window. |
| API failure | Show an error; top-line current/all-time fallbacks may use already authorized roster values. |
| Empty practice | Show zero/no-profile states without inventing averages. |
| Sparse cohort | Show family count but suppress the average/detail until the minimum sample is met. |
| Mobile refresh timeout | Keep the user in the coach workspace, explain the timeout and allow refresh. |
Acceptance checklist
- Current, Active, New and Worked with remain semantically distinct when the date range changes.
- A custom portal end date includes that day by sending the following UTC midnight as
until. - Mobile summary and family cards derive from the authorized live roster, not an all-time name list.
- All-time aggregate counts can include former families while former identifiers/details remain absent.
- Age-cohort averages/details are null/empty below three families.
- Assignment-window filtering prevents pre-assignment and post-end activity from affecting results.
- Null/insufficient metrics are shown as no data, not zero improvement.
- Metric explanation dialogs identify both the calculation and the eligible families behind current detail.
Source evidence
Coach portal
admin-web/src/routes/CoachDashboardAnalyticsPanel.tsxadmin-web/src/routes/AdminDashboard.tsx
Mobile web
mobile-web/src/routes/CoachDashboard.tsxmobile-web/src/components/CoachFamilyPicker.tsx
Platform and contracts
platform/apps/api/src/routes/coach-routes.tsplatform/apps/api/src/services/coach-dashboard-analytics-service.tsplatform/apps/api/src/services/prisma-invite-flow-service.tsplatform/packages/shared/src/coach.ts
