Analytics

Analytics turns stored app, waitlist, content, billing, usage, and credit records into dashboard charts.

On this page

Where to look

AreaMaintainer reference
Routes
Implementation referencesrc/app/(dashboard)/analytics/platform, /analytics/revenue
Range APIs
Implementation referencesrc/app/api/analytics/platform/range/route.ts, src/app/api/analytics/revenue/range/route.ts
Server
Implementation referencesrc/features/analytics/server/platform, revenue, billing, activity, services
Shared
Implementation referencesrc/features/analytics/shared/charts, ranges, billing, events
UI
Implementation referencesrc/features/analytics/ui/platform, revenue, charts, controls
Data sourcesanalytics_events, waitlist_signups, billing_usage_events, billing_credit_transactions, billing_orders, billing_invoices
Implementation reference3 areas

These Product code locations explain how the documented behavior is implemented. Expand them when you are ready to customize or maintain this area.

Dashboard surfaces

Dashboard pages and range APIs delegate metric assembly to analytics feature modules.

  • src/app/(dashboard)/analytics/platform/page.tsx
  • src/app/(dashboard)/analytics/revenue/page.tsx
  • src/app/api/analytics/platform/range/route.ts
  • src/app/api/analytics/revenue/range/route.ts

Metric queries

Platform, revenue, MRR, and signal summaries are assembled server-side before chart UI renders them.

  • src/features/analytics/server/platform/queries/dashboard.ts
  • src/features/analytics/server/revenue/queries/dashboard.ts
  • src/features/analytics/server/billing/queries/mrr.ts
  • src/features/analytics/server/revenue/queries/signal-summary.ts

Series and model visibility

Revenue charts use shared range, time-series, and billing-model helpers so disabled billing models do not leak into UI.

  • src/features/analytics/server/services/query-range.ts
  • src/features/analytics/server/revenue/services/model-visibility.ts
  • src/features/analytics/server/billing/queries/timeseries/revenue.ts

Reference paths are relative to the Shipflash-Product checkout.

Analytics range flow

  1. 1

    Normalize the requested range

    Range services and schemas keep dashboard and API requests on the same date-window contract.

    Relevant Product code
    • src/features/analytics/server/services/dashboard-range.ts
    • src/features/analytics/shared/ranges/date-range.ts
  2. 2

    Query source tables server-side

    Metric queries read analytics, waitlist, content, billing, usage, and credit records without provider calls in render loops.

    Relevant Product code
    • src/features/analytics/server/platform/queries/dashboard.ts
    • src/features/analytics/server/revenue/queries/dashboard.ts
  3. 3

    Build chart series

    Series helpers normalize activity, checkout, revenue, usage, and credit data before UI cards render.

    Relevant Product code
    • src/features/analytics/server/services/series.ts
    • src/features/analytics/server/billing/queries/timeseries/revenue.ts
  4. 4

    Render with shared chart config

    UI components consume prepared data and shared chart config rather than duplicating metric rules.

    Relevant Product code
    • src/features/analytics/shared/charts/config.ts
    • src/features/analytics/ui/platform/dashboard.tsx
    • src/features/analytics/ui/revenue/dashboard.tsx

Analytics API authorization

Use this example as a starting point, then adapt it to your product's rules and configuration.

Range APIs authorize the user and feature before loading server-side analytics.

ts
type RangeAuthorization =
  | { profile: ActiveProfile; failure: null }
  | { profile: null; failure: ServiceResult<never> };

async function authorizeRangeRequest(requestId: string): Promise<RangeAuthorization> {
  const auth = await requireApiAuth(requestId);
  if (!auth.ok) {
    return {
      profile: null,
      failure: serviceFailure(auth.error.code, auth.error.message, requestId, apiStatusForErrorCode(auth.error.code)),
    };
  }

  const feature = await requireApiFeature(auth.data.profile, "insights", requestId);
  if (!feature.ok) {
    return {
      profile: null,
      failure: serviceFailure(feature.error.code, feature.error.message, requestId, apiStatusForErrorCode(feature.error.code)),
    };
  }

  return { profile: auth.data.profile, failure: null };
}
Source reference
  • src/features/analytics/server/services/dashboard-range.ts

Chart rules

  • Aggregate on the server before rendering chart components.
  • Avoid provider API calls in chart loops.
  • Keep revenue charts tied to local billing projection tables.
  • Show empty data as a normal state.
  • Use enabled billing models to decide which revenue or usage series should appear.