Analytics — Code Map
API
apps/api/src/analytics/analytics.module.ts— registers legacyAnalyticsServiceand TKN-24AnalyticsReportsService.apps/api/src/analytics/analytics.controller.ts— existing/new routes,requireMembership+analytics:view, query validation, legacytoCsv, and export dispatch.apps/api/src/analytics/analytics.service.ts— legacy aggregations on the shared vocabulary,INTERVAL_MONTHS,MEMBERSHIP_ENDED_AT, and summary interfaces.apps/api/src/analytics/analytics-reports.service.ts— dashboard KPIs, attendance/weighted capacity, signed per-currency revenue, and lifecycle cohorts.apps/api/src/analytics/analytics-report-csv.ts— stable report headers, BOM/CRLF, escaping and text-formula protection; does not replace legacy CSV formatting.apps/api/src/payments/services/receipts.sql.ts—RECEIPT_AT,SIGNED_RECEIPT_CENTS,MONEY_MOVED: canonical actual-receipts definition.apps/api/src/memberships/member-status-predicates.ts— the member vocabulary as alias-aware SQL (MEMBERSHIPS_MforFROM memberships m):memberStatusCondition(shared with the roster filter),rosterMemberCondition,trainingMemberCondition(active member),atRiskMemberCondition(itshasDebtConditionreadsoutstandingRowCondition),newMemberCondition(current-window KPI),joinedInWindowCondition(joined history). See the definitions table.apps/api/src/payments/services/revenue-metrics.sql.ts— the money vocabulary:RECURRING_PLAN(MRR, forecasted recurring, active subscriptions, plan distribution, presale committed, recurring-charges list),sumOutstanding/outstandingRowCondition,sumPacksSold.apps/api/src/analytics/participation-filter.driver.tswithparticipation-filter.int.spec.ts,analytics-vocabulary.int.spec.tsandactive-member-plan.int.spec.ts— real-Postgres guards thatguardian_onlychanges no figure, the at-risk card equals its list, the active member is exactly the roster’s Training ∪ Leaving, outstanding is one figure, packs stay out of recurring revenue and net their refunds, and the active-member count’s plan stays belowjit_above_cost.apps/api/src/analytics/analytics.service.driver.ts,analytics.service.unit.spec.ts,analytics.service.int.spec.ts,analytics.controller.unit.spec.ts— legacy regression coverage in the same directory.apps/api/src/analytics/analytics-reports.controller.driver.tsandanalytics-reports.controller.unit.spec.ts— new controller authorization, validation, and CSV contracts.apps/api/src/analytics/analytics-reports.driver.tsandanalytics-reports.int.spec.ts— deterministic real-Postgres reporting fixtures and projections.
Shared reporting contracts
libs/shared/src/lib/schemas/analytics.schema.ts— date/filter/cohort schemas, seven unchangedBASIC_REPORT_EXPORT_TABSidentifiers, and thedashboardQuerySchemaweek-start query. Basic export identifiers are projections, not web area names.
Agent surface
apps/api/src/ai/agent/tools/leaves/analytics.tools.ts— twelveanalytics.*tool actions, each delegating to a service method.libs/shared/src/lib/agent-schemas/analytics.ts— Zod schemas for the agent tool inputs.
Web
apps/web/src/app/[lang]/(protected)/dashboard/analytics/page.tsx— one report page, three areas, not per-projection routes.apps/web/src/components/analytics/reports-screen.tsx— URL-driven available-area/filter hydration, replace-default/push-edit history, relevant-schema guard, and one report dataset fetch per selected area;report-results.tsx/report-display.tsxretain the seven basic projections and shared formatting/states.apps/web/src/components/analytics/use-reports-access.ts— theanalytics:viewgate shared by the sidebar entry, workspace and snapshot.apps/web/src/components/analytics/report-request.ts—REPORT_AREAS,REPORT_PROJECTIONS, and one dataset/CSV serializer.report-presets.tsderives the quick date ranges from the org-local date.report-charts.tsxdraws the class ranking bars, the monthly net columns, and the cohort cell wash;report-highlights.tsxopens each area with its KPI tiles, the attendance mix bar, the daily attendance area, the busiest-hours grid, the payment-method mix, the active-subscriber trend and the joined/left bars. Every chart sits above the table that is its accessible twin.apps/web/e2e/specs/owner-reports.spec.tswithe2e/drivers/reports-driver.ts— browser walk of the page: KPIs, areas, quick ranges, CSV download, cohorts.apps/web/src/components/analytics/report-export.tsx— matching per-projection CSV downloads, disabled while invalid/unavailable/fetching.apps/web/src/components/analytics/studio-kpi-snapshot.tsx— five-KPI snapshot mounted only inside the reports workspace, with its independent dashboard query.apps/web/src/components/analytics/reports-screen.driver.tsxandreports-screen.int.spec.tsx— three areas/seven projections, shared requests, direct URLs/defaults/history, invalid-filter recovery, exports, tenant isolation, and localized rendering contracts.apps/web/src/components/overview/sidebar-nav.tsx— Reports entry, gated onanalytics:view.apps/web/src/components/overview/v2/overview-v2.tsx— existing overview panels only; no report snapshot/link.overview-v2.int.spec.tsxguards absence of associated report dashboard requests.apps/web/src/components/overview/v2/revenue-panel.tsx— net receipts,mrr + committedprojection, and the packs-sold line under the collected headline.apps/web/src/components/overview/v2/growth-panel.tsx— existingmembers/growthpanel.
Accounting audit boundary
apps/api/src/payments/services/receipts.sql.tssupplies existing canonical receipt expressions, not a new accounting model. Report revenue preserves separate currencies.apps/api/src/payments/services/payment-analytics.service.ts— legacy scalar summaries and prior-month/yesterday/monthly-trend window audit deferrals.apps/api/src/analytics/analytics.service.ts— legacy scalar money contracts and list-price plan distribution versus chargeable current MRR remain unchanged.- Admin cross-org raw completed/createdAt aggregation and a historical paid-retention ledger are outside this change. See the explicit deferrals; shared SQL does not make every money API interchangeable.
Schema dependencies
libs/db/src/lib/schema/payments.ts—subscriptions,payment_transactions.libs/db/src/lib/schema/memberships.ts—memberships.libs/db/src/lib/schema/users.ts—users.libs/db/src/lib/schema/scheduling.ts—class_sessions,bookings,class_types.libs/db/src/lib/schema/workouts.ts—workouts,workout_assignments,personal_records.libs/db/src/lib/schema/invitations.ts—invitations.libs/db/src/lib/schema/organizations.ts—organizations.libs/db/src/lib/schema/conversations.ts— message creation/actor and conversation org/lead scope for unresolved outbound; current unread-inbound state for ActionCenter parity, not historical delivery reconstruction.
Space context (TKN-460)
analytics.controller.tsresolves the optionalspaceIdthroughSpaceScopeService(apps/api/src/locations/space-scope.service.ts) after theanalytics:viewgate.dashboardscopesclassesThisWeekandattendance;attendance/reportscopes session figures and visitors whileactiveMembers/withoutVisitstay business-wide;classes/popular,classes/utilizationand the matching exports filter onclass_sessions.location_id. Without the parameter, or with the org’sspacesflag off, responses are unchanged. See space-context/code-map.md.