Files
school_compare/nextjs-app/lib/metrics.ts
Tudor 5eff9af69c
Some checks failed
Build and Push Docker Images / Build Frontend (Next.js) (push) Has been cancelled
Build and Push Docker Images / Build Pipeline (Meltano + dbt + Airflow) (push) Has been cancelled
Build and Push Docker Images / Trigger Portainer Update (push) Has been cancelled
Build and Push Docker Images / Build Backend (FastAPI) (push) Has been cancelled
feat: add secondary school support with KS4 data and metric tooltips
- Backend: replace INNER JOIN ks2 with UNION ALL (ks2 + ks4) so primary
  and secondary schools both appear in the main DataFrame
- Backend: add /api/national-averages endpoint computing means from live
  data, replacing the hardcoded NATIONAL_AVG constant on the frontend
- Backend: add phase filter param to /api/schools; return phases from
  /api/filters; fix hardcoded "phase": "Primary" in school detail endpoint
- Backend: add KS4 metric definitions (Attainment 8, Progress 8, EBacc,
  English & Maths pass rates) to METRIC_DEFINITIONS and RANKING_COLUMNS
- Frontend: SchoolDetailView is now phase-aware — secondary schools show
  a GCSE Results section (Att8, P8, E&M, EBacc) instead of SATs; phonics
  tab hidden for secondary; admissions says Year 7 instead of Year 3;
  history table shows KS4 columns; chart datasets switch for secondary
- Frontend: new MetricTooltip component (CSS-only ⓘ icon) backed by
  METRIC_EXPLANATIONS — added to RWM, GPS, SEN, EAL, IDACI, progress
  scores and all KS4 metrics throughout SchoolDetailView and SchoolCard
- Frontend: METRIC_EXPLANATIONS extended with KS4 terms (Attainment 8,
  Progress 8, EBacc) and previously missing terms (SEN, EHCP, EAL, IDACI)
- Frontend: SchoolCard expands "RWM" to "Reading, Writing & Maths" and
  shows Attainment 8 / English & Maths Grade 4+ for secondary schools
- Frontend: FilterBar adds Phase dropdown (Primary / Secondary / All-through)
- Frontend: HomeView hero copy updated; compact list shows phase-aware metric
- Global metadata updated to remove "primary only" framing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 14:59:40 +00:00

174 lines
7.3 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Plain-language metric labels and explanations.
* Single source of truth for all metric display strings.
*/
export interface MetricExplanation {
label: string;
plain: string;
detail?: string;
}
export const METRIC_EXPLANATIONS: Record<string, MetricExplanation> = {
rwm_expected_pct: {
label: 'Reading, Writing & Maths',
plain: '% of pupils achieving the expected standard in all three subjects at age 11',
detail: 'The national average is around 60%. Higher means more pupils reached the expected level.',
},
rwm_high_pct: {
label: 'Higher Standard — Reading, Writing & Maths',
plain: '% of pupils exceeding the expected level in all three subjects',
detail: 'A more demanding threshold. The national average is around 8%.',
},
reading_expected_pct: {
label: 'Reading — Expected Standard',
plain: '% of pupils achieving the expected standard in reading at age 11',
},
writing_expected_pct: {
label: 'Writing — Expected Standard',
plain: '% of pupils achieving the expected standard in writing at age 11',
},
maths_expected_pct: {
label: 'Maths — Expected Standard',
plain: '% of pupils achieving the expected standard in maths at age 11',
},
reading_high_pct: {
label: 'Reading — Higher Standard',
plain: '% of pupils exceeding the expected level in reading',
},
writing_high_pct: {
label: 'Writing — Higher Standard',
plain: '% of pupils exceeding the expected level in writing',
},
maths_high_pct: {
label: 'Maths — Higher Standard',
plain: '% of pupils exceeding the expected level in maths',
},
gps_expected_pct: {
label: 'Grammar & Spelling',
plain: '% of pupils achieving the expected standard in grammar, punctuation & spelling',
},
science_expected_pct: {
label: 'Science',
plain: '% of pupils achieving the expected standard in science',
},
reading_progress: {
label: 'Reading Progress',
plain: 'How much pupils improved in reading compared to similar schools',
detail: '0 = national average. Positive means better-than-average progress from Year 2 to Year 6.',
},
writing_progress: {
label: 'Writing Progress',
plain: 'How much pupils improved in writing compared to similar schools',
detail: '0 = national average. Positive means better-than-average progress from Year 2 to Year 6.',
},
maths_progress: {
label: 'Maths Progress',
plain: 'How much pupils improved in maths compared to similar schools',
detail: '0 = national average. Positive means better-than-average progress from Year 2 to Year 6.',
},
reading_avg_score: {
label: 'Reading Average Score',
plain: 'Average scaled score in the reading test (range 80120, average = 100)',
},
maths_avg_score: {
label: 'Maths Average Score',
plain: 'Average scaled score in the maths test (range 80120, average = 100)',
},
gps_avg_score: {
label: 'Grammar & Spelling Average Score',
plain: 'Average scaled score in the grammar, punctuation & spelling test',
},
overall_absence_pct: {
label: 'Absence Rate',
plain: '% of school sessions missed due to any reason',
detail: 'Lower is better. The national average is around 5%.',
},
persistent_absence_pct: {
label: 'Persistent Absence',
plain: '% of pupils missing 10% or more of school sessions',
detail: 'Lower is better. Persistent absence can significantly affect attainment.',
},
rwm_expected_disadvantaged_pct: {
label: 'Disadvantaged Pupils — Reading, Writing & Maths',
plain: '% of disadvantaged pupils achieving the expected standard in all three subjects',
},
disadvantaged_gap: {
label: 'Disadvantaged Gap',
plain: 'Difference in attainment between disadvantaged pupils and their peers',
detail: 'A smaller gap means the school is doing more to support disadvantaged pupils.',
},
sen_support_pct: {
label: 'SEN Support',
plain: '% of pupils receiving SEN (Special Educational Needs) support without a formal plan',
detail: 'These pupils need extra help but do not yet have an Education, Health and Care Plan (EHCP).',
},
sen_ehcp_pct: {
label: 'Education, Health and Care Plan (EHCP)',
plain: '% of pupils with a formal EHCP — a legal plan for pupils with significant additional needs',
},
eal_pct: {
label: 'English as an Additional Language',
plain: '% of pupils whose first language is not English',
},
idaci_decile: {
label: 'Deprivation (IDACI)',
plain: 'How deprived the area around the school is. Decile 1 = most deprived 10% of areas in England.',
detail: 'IDACI stands for Income Deprivation Affecting Children Index. It measures the proportion of children living in low-income households in an area.',
},
// ── KS4 / GCSE metrics ────────────────────────────────────────────────
attainment_8_score: {
label: 'Attainment 8',
plain: 'Average grade across a pupil\'s best 8 GCSEs, including English and Maths',
detail: 'Each GCSE grade is converted to a points score (grade 9 = 9 points, grade 1 = 1 point). The national average is around 46.',
},
progress_8_score: {
label: 'Progress 8',
plain: 'How much pupils improved from their primary school results to GCSE, compared to similar pupils nationally',
detail: '0 = national average. Positive means better-than-expected progress; negative means lower-than-expected. A score above +0.5 is considered well above average.',
},
english_maths_standard_pass_pct: {
label: 'English & Maths — Grade 4+ (Standard Pass)',
plain: '% of pupils achieving at least a grade 4 in both English and Maths',
detail: 'Grade 4 is the minimum "standard pass". Employers and colleges often require grade 4 in English and Maths.',
},
english_maths_strong_pass_pct: {
label: 'English & Maths — Grade 5+ (Strong Pass)',
plain: '% of pupils achieving at least a grade 5 in both English and Maths',
detail: 'Grade 5 is a "strong pass". Many sixth forms and universities expect grade 5 in English and Maths.',
},
ebacc_entry_pct: {
label: 'EBacc Entry',
plain: '% of pupils who entered the English Baccalaureate — a set of GCSE subjects covering English, Maths, Sciences, a Language, and Humanities',
detail: 'EBacc entry keeps academic options open post-16. It is not a separate qualification.',
},
ebacc_standard_pass_pct: {
label: 'EBacc — Grade 4+ (Standard Pass)',
plain: '% of pupils achieving grade 4 or above across all EBacc subjects',
},
ebacc_strong_pass_pct: {
label: 'EBacc — Grade 5+ (Strong Pass)',
plain: '% of pupils achieving grade 5 or above across all EBacc subjects',
},
ebacc_avg_score: {
label: 'EBacc Average Score',
plain: 'Average points score across all EBacc subject entries',
},
gcse_grade_91_pct: {
label: 'GCSE Grade 91 %',
plain: '% of GCSE entries where a pupil achieved a grade between 9 (highest) and 1',
},
};
/**
* Returns a plain-English band label for a KS2 progress score.
* Progress scores are centred at 0 (= national average).
*/
export function progressBand(score: number): string {
if (score > 3) return 'well above average';
if (score > 1) return 'above average';
if (score >= -1) return 'around average';
if (score >= -3) return 'below average';
return 'well below average';
}