Telemetry
How platform telemetry flows through the system — what gets tracked, where it goes, and how features integrate with the telemetry layer.
For schemas, APIs, and implementation details, see ../telemetry/. For infrastructure monitoring (Datadog, UptimeRobot), see external-providers.md.
What Telemetry Covers
Telemetry is the platform's own data collection layer. It answers questions about users, compliance, and product health — not server performance.
| Domain | What's Tracked | Storage | Retention |
|---|---|---|---|
| Audit | Every authenticated action (HIPAA compliance) | Telemetry PostgreSQL | 6-7 years |
| Security | Attack detection, suspicious activity | Telemetry PostgreSQL | 3 years |
| Privacy | CCPA "Do Not Sell" IP exclusions | Telemetry PostgreSQL | Active |
| Video Performance | TTFB, buffering, bitrate, load times, dropped frames | ClickHouse | 2 years |
| Product Analytics | Page views, feature usage, click events | ClickHouse | 2 years |
| Pose Tracking | MediaPipe body landmarks during exercises | ClickHouse | 6 months |
| Error Tracking | App/video/network errors with device context | ClickHouse | 1 year |
| API Metrics | Response times, error rates per endpoint | ClickHouse | 1 year |
How Features Integrate
Appointments → Audit
Every appointment action (create, cancel, join video) generates an audit log entry.
Specialist creates appointment
→ API handler succeeds
→ Middleware logs to audit.audit_logs (Telemetry PG)
→ Actor hash, action, resource_type, resource_id, statusNo feature code needed — the audit middleware captures this automatically on every authenticated request.
Exercise Library → Video Performance + Analytics
When a patient watches an exercise video, the frontend sends events to the telemetry API.
Patient opens exercise video
→ session_start event (TTFB, load time, connection info)
→ heartbeat every 10s (buffering, bitrate, quality, dropped frames)
→ buffering_start/end (per-stall detail)
→ quality_change (ABR switches)
→ milestone (25%, 50%, 75%, 95% watched)
→ session_end (final stats, completion status)
All → POST /v1/media/events → ClickHouse media_sessions + media_buffering_eventsSee ../telemetry/media-events.md for the full event specification.
Treatment Plans → Session Tracking + Pose + Analytics
Treatment plan sessions combine multiple telemetry streams:
Patient starts guided session
│
├── Exercise video plays → media events (same as above)
│
├── MediaPipe pose detection (optional)
│ → POST /v1/pose/frames (batched every 1-2s)
│ → ClickHouse pose_tracking_frames
│
├── Session completion
│ → POST /v1/analytics/track {event: "treatment_plan.session_completed"}
│ → ClickHouse analytics_events
│
└── All actions audited automatically
→ Telemetry PG audit.audit_logsForms → Audit (Automatic)
Form submissions (especially those containing PHI) are automatically audited:
Patient submits intake form
→ form.submit action logged with resource_id = form instance ID
→ Fields accessed tracked in metadata (no field values — just field names)Automations → Analytics Events
Automation executions generate analytics events for tracking automation effectiveness:
Automation "send_email" fires for appointment.first_booked
→ POST /v1/analytics/track {event: "automation.executed", properties: {rule_id, trigger, action}}Staff Actions → Staff Metrics
Staff performance analytics are derived from audit log data, not submitted separately. The audit worker aggregates staff actions into the ClickHouse staff_metrics table:
Specialist completes appointment, signs forms, reviews treatment plans
→ Audit middleware captures each action (automatic)
→ Audit worker aggregates into staff_metrics (ClickHouse, ~2K events/day)
→ Available via Telemetry dashboard: response times, completion rates, patient throughputStaff metrics use hashed actor IDs (same as all Telemetry data). No separate consent model is needed — staff actions are tracked under legitimate interest (operational analytics for the organization).
Consent Model
All telemetry is gated by the user's consent level. Events are dropped (not stored) if the user hasn't consented to that level.
| Level | Name | What's Allowed | Features Affected |
|---|---|---|---|
| 0 | Excluded | Nothing (CCPA opt-out IP) | All telemetry disabled |
| 1 | Essential | Audit logs, security events, error tracking | Audit, security, error reports |
| 2 | Analytics | + Product analytics, media sessions, pose tracking | Video dashboard, analytics, pose |
| 3 | Full | + Marketing, behavioral analysis | (Future: marketing analytics) |
How it works:
- Frontend sends consent state with each request
- Telemetry middleware checks consent level
- Events below the user's consent level are accepted (202) but silently dropped
- CCPA exclusion check: if IP matches a MaxMind "Do Not Sell" range → forced to level 0
Data Flow Summary
┌─────────────────────────────────────────────────────────────────────┐
│ Frontend │
│ │
│ Video Player ──→ media events (session_start, heartbeat, etc.) │
│ Pose Camera ───→ pose frames (batched) │
│ App Actions ───→ analytics events (page views, clicks) │
│ Errors ────────→ error reports │
│ │
└──────────────────────────┬──────────────────────────────────────────┘
│
POST /v1/media/events
POST /v1/analytics/track
POST /v1/pose/frames
POST /v1/errors/report
│
┌──────────────────────────┼──────────────────────────────────────────┐
│ Core API │
│ │ │
│ ┌───────────┴───────────┐ │
│ │ Telemetry Middleware │ │
│ │ 1. Check consent │ │
│ │ 2. Hash PII │ │
│ │ 3. Enrich geo/device │ │
│ │ 4. Check CCPA │ │
│ └───────────┬───────────┘ │
│ │ │
│ ┌───────────┼───────────┐ │
│ ▼ ▼ ▼ │
│ Redis Queue Redis Queue Direct Write │
│ (analytics) (audit) (if sync) │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ │
│ │analytics │ │ audit │ │
│ │ worker │ │ worker │ │
│ └────┬─────┘ └────┬─────┘ │
│ │ │ │
└─────────────┼────────────┼───────────────────────────────────────────┘
│ │
▼ ▼
┌──────────┐ ┌──────────┐
│ClickHouse│ │Telemetry │
│ │ │PostgreSQL│
│analytics │ │ │
│media │ │audit_logs│
│errors │ │security │
│pose │ │privacy │
│api_metrix│ │staff │
└──────────┘ └──────────┘Feature Integration Checklist
When adding a new feature, consider what telemetry data it generates:
| Question | If Yes | Action |
|---|---|---|
| Does it handle authenticated requests? | Automatic | Audit middleware covers it — no code needed |
| Does it play media/video? | Frontend work | Send media events to POST /v1/media/events |
| Does it have user interactions worth tracking? | Frontend work | Send analytics events to POST /v1/analytics/track |
| Does it use the camera/pose detection? | Frontend work | Send pose frames to POST /v1/pose/frames |
| Can it produce errors the user sees? | Frontend work | Send error reports to POST /v1/errors/report |
| Does it need its own dashboard? | ClickHouse | Add materialized views for aggregation |
Key Docs
| Doc | What It Covers |
|---|---|
| ../telemetry/README.md | Architecture, database selection rationale, privacy model |
| ../telemetry/clickhouse-schema.sql | ClickHouse tables (7) and materialized views (5) |
| ../telemetry/postgres-schema.sql | Audit, security, privacy PostgreSQL tables (6) |
| ../telemetry/api.md | All 18 telemetry API endpoints |
| ../telemetry/media-events.md | Video event specification, frontend integration code |
| ../telemetry/migration.md | Migration guide from standalone Vitals project |
| external-providers.md | MaxMind (geo/privacy), infrastructure monitoring |