Cross-cutting · Product analytics & error monitoring
A vendor-agnostic analytics facade that records page views and ~88 named product events (exports, imports, AI filter use, segment saves, status changes, logins), plus Sentry for error monitoring and
ember-metricspage tracking.
| Area | Cross-cutting |
| Routes | (every route) |
| Centre modules | always available |
| Staff levels | all |
| Models | — |
| UI label | (analytics) |
| Coverage | 3 use cases · 1 happy · 3 failure |
Known issues (1)
- 🟠 Medium — AI filter sends prompt text to Sentry
How it works
The service picks a provider from config.analytics (provider, apiKey, enabled, debug) and falls back to a no-op provider, wrapping every call so tracking can never break the UI. Every event is enriched with center_id and the current route. The codebase is notably privacy-aware: the AI filter sends only prompt length, the CLI only the command name, exports only filter and column counts. Sentry receives the user on login (sentrySetUser) and explicit captureException calls (e.g. the AI filter’s mapping failures — which, in contrast to the analytics policy, include the prompt).
Use cases
Why someone opens this (3)
- Measuring adoption of features such as the AI filter or segment builder.
- Seeing which list screens are filtered and exported most.
- Diagnosing front-end errors per user in Sentry.
Path map
flowchart LR F(["Product analytics and error monitoring"]):::feat F --> H1["Event tracked"]:::ok F -.-> X1["Analytics not configured"]:::bad F -.-> X2["Provider throws"]:::bad F -.-> X3["PII in error reports"]:::bad classDef feat fill:#8c5a3c,stroke:#8c5a3c,color:#ffffff,font-weight:bold classDef ok fill:#e3f1ea,stroke:#0d6b42,color:#0d4a2e classDef bad fill:#f7e6e2,stroke:#9a2d1c,color:#6e1f13
Happy paths
Event tracked
- A user saves a customer; the controller calls
analytics.track(CRM_USER_SAVED, {...}).- The facade adds
center_idand route and forwards to the configured provider.
Failure paths
Analytics not configured
Cause —
enabledfalse or no API key.What happens — The no-op provider is used; nothing is recorded and nothing breaks.
Provider throws
Cause — Vendor SDK error.
What happens — Guarded inside
_call; the UI is unaffected.
PII in error reports
Cause —
captureExceptionwith free text.What happens — Not filtered — the AI filter sends its prompt to Sentry.
QA checklist
Tick these off while regression-testing this feature. The boxes are plain Markdown, so progress is visible in git diffs.
- ✅ Event tracked
- ⛔ Analytics not configured
- ⛔ Provider throws
- ⛔ PII in error reports
Implementation
app/services/analytics.jsapp/utils/analytics/providersapp/enums/analytics-events.jsapp/routes/application.jsapp/services/auth.js
Related
- Same area — CSV import engine · Data export engine (email delivery) · Filter & segment builder component · File upload, gallery & image modal · Multi-language content authoring · Realtime updates (Pusher) · Role & module permission layer · Error presentation & API error mapping
Generated from doc/feature-inventory.json · id xc-product-analytics · commit 276788ca6