feat(analytics): typed Umami event taxonomy across the funnel
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 18s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 57s
Build and Push Docker Images / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 12s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 1s

Add lib/analytics.ts with a single typed track() wrapper. SSR-safe,
never throws, no-ops when Umami isn't loaded. Event names form a
fixed union so refactors stay safe.

14 events wired:

  Discovery (3)
    search_submitted          FilterBar submit + near_me path
    near_me_used              all geolocation outcomes
    empty_results             search returns 0 schools

  Engagement (5)
    school_viewed             SchoolDetail + Secondary on mount, with
                              urn / phase / local_authority / from
    section_nav_used          section-nav links on both detail views
    chart_metric_changed      mobile chart chip switch
    metric_compared_in_rankings rankings metric dropdown
    external_link_clicked     Ofsted / school website / DfE (declarative
                              data-umami-event attributes)

  Conversion (5)
    compare_school_added      search/rankings/detail/compare sources
    compare_school_removed    detail toggle and compare page
    compare_viewed            once per session when there's a selection
                              (school_count, phase_mix)
    compare_metric_changed    compare page metric dropdown
    compare_shared            native sheet vs clipboard distinguished

  Operational (1)
    api_error                 caught in handleResponse, includes
                              endpoint / status / route

Suggested Goals to configure in the Umami dashboard for the funnel
report: search_submitted → school_viewed → compare_school_added →
compare_viewed → compare_shared.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Tudor Sitaru
2026-05-19 22:04:22 +01:00
parent 4cfae93a0d
commit 7e182e88b2
11 changed files with 234 additions and 10 deletions
+7 -1
View File
@@ -16,6 +16,7 @@ import { ChartOptions, ChartDataset } from 'chart.js';
import '@/lib/chartSetup';
import type { SchoolResult } from '@/lib/types';
import { formatAcademicYear } from '@/lib/utils';
import { track } from '@/lib/analytics';
import styles from './PerformanceChart.module.css';
interface NationalByYear {
@@ -389,7 +390,12 @@ export function PerformanceChart({
role="tab"
aria-selected={active}
disabled={!enabled}
onClick={() => setActiveChip(chip.id)}
onClick={() => {
if (chip.id !== activeChip) {
track('chart_metric_changed', { chip: chip.id, phase: isSecondary ? 'secondary' : 'primary', viewport: 'mobile' });
}
setActiveChip(chip.id);
}}
className={`${styles.chip}${active ? ` ${styles.chipActive}` : ''}`}
title={!enabled ? 'No data for this school' : undefined}
>