Commit Graph
16 Commits
Author SHA1 Message Date
tudorandClaude Sonnet 4.6 6ce52d833c fix(kestra): bake flows into kestra-init image to fix empty /flows in container
Build and Push Docker Images / Build Frontend (Next.js) (push) Has been cancelled
Build and Push Docker Images / Build Integrator (push) Has been cancelled
Build and Push Docker Images / Build Kestra Init (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
Bind mounts don't work on the remote Portainer host since the files
aren't present there. Instead, Dockerfile.init copies the flow YAMLs
into a dedicated image (kestra/kestra:latest base) that is built in CI
and pulled by Portainer like the other images.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 12:40:43 +00:00
tudorandClaude Sonnet 4.6 eda3444147 fix(kestra): load flows via kestra-init one-shot container
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 34s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 1m10s
Build and Push Docker Images / Trigger Portainer Update (push) Has been cancelled
Build and Push Docker Images / Build Integrator (push) Has been cancelled
--flow-path is not a valid Kestra flag; flows must be pushed explicitly.
kestra-init waits for Kestra to pass its healthcheck then runs
'kestra flow namespace update schoolcompare.data /flows --no-delete'
to import all flow YAMLs. Runs once on stack start; --no-delete means
any flows created manually in the UI are not removed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 12:38:46 +00:00
tudorandClaude Sonnet 4.6 591cc87b39 fix(kestra): add server standalone command to prevent restart loop
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 32s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 1m9s
Build and Push Docker Images / Build Integrator (push) Successful in 31s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 1s
Without an explicit command the container prints help and exits,
causing Docker to restart it indefinitely.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 12:30:52 +00:00
tudorandClaude Sonnet 4.6 f1fb847164 feat(integrator): add KS2 re-import via Kestra and backend admin endpoint
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 47s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 1m13s
Build and Push Docker Images / Build Integrator (push) Successful in 40s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 0s
- backend: POST /api/admin/reimport-ks2 runs full CSV migration in a thread
- backend/docker-compose: ADMIN_API_KEY env var (default: changeme) so the
  key is stable across restarts and the integrator can call the endpoint
- integrator: sources/ks2.py triggers the backend endpoint (900s timeout)
- integrator: flows/ks2.yml Kestra flow (manual trigger, no schedule)

To re-ingest after a DB wipe: trigger the ks2-reimport flow from the
Kestra UI at http://localhost:8080.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 12:25:29 +00:00
tudorandClaude Sonnet 4.6 822ec936bf fix(integrator): install curl in Dockerfile; restore curl healthcheck
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 1m2s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 1m12s
Build and Push Docker Images / Build Integrator (push) Successful in 59s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 0s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 11:59:53 +00:00
tudorandClaude Sonnet 4.6 15289083c6 fix(integrator): use python urllib for healthcheck instead of curl
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 33s
Build and Push Docker Images / Build Integrator (push) Has been cancelled
Build and Push Docker Images / Trigger Portainer Update (push) Has been cancelled
Build and Push Docker Images / Build Frontend (Next.js) (push) Has been cancelled
python:3.12-slim doesn't include curl; urllib is part of the stdlib.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 11:58:28 +00:00
tudorandClaude Sonnet 4.6 04b9944140 ci: add integrator image build to Gitea Actions
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 32s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 1m8s
Build and Push Docker Images / Build Integrator (push) Successful in 55s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 1s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 11:45:18 +00:00
tudorandClaude Sonnet 4.6 dd49ef28b2 feat(data): integrate 9 UK government data sources via Kestra
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 47s
Build and Push Docker Images / Trigger Portainer Update (push) Has been cancelled
Build and Push Docker Images / Build Frontend (Next.js) (push) Has been cancelled
Adds a full data integration pipeline for enriching school profiles with
supplementary data from Ofsted, GIAS, EES, IDACI, and FBIT.

Backend:
- Bump SCHEMA_VERSION to 3; add 8 new DB tables (ofsted_inspections,
  ofsted_parent_view, school_census, admissions, sen_detail, phonics,
  school_deprivation, school_finance) plus GIAS columns on schools
- Expose all supplementary data via GET /api/schools/{urn}
- Enrich school list responses with ofsted_grade + ofsted_date

Integrator (new service):
- FastAPI HTTP microservice; Kestra calls POST /run/{source}
- 9 source modules: ofsted, gias, parent_view, census, admissions,
  sen_detail, phonics, idaci, finance
- 9 Kestra flow YAMLs with scheduled triggers and 3× retry

Frontend:
- SchoolRow: colour-coded Ofsted badge (Outstanding/Good/RI/Inadequate)
- SchoolDetailView: 7 new sections — Ofsted sub-judgements, Parent View
  survey bars, Admissions, Pupils & Inclusion / SEN, Phonics, Deprivation
  Context, Finances
- types.ts: 8 new interfaces + extended School/SchoolDetailsResponse

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 11:44:04 +00:00
tudorandClaude Sonnet 4.6 c49593d4d6 feat(row): redesign to clean 3-line layout with stats on second row
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 32s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 1m6s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 1s
Line 1: school name (bold) + school type (muted gray)
Line 2: R,W&M %  ·  Progress score + band  ·  Pupil count
Line 3: local authority  ·  distance (location searches)

Actions (View / Add) are vertically centred on the right across all lines.
Progress uses reading score, falling back to writing then maths. Removed
the old nameScore grouping and separate meta/progress rows in favour of
the cleaner 3-line structure.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 09:27:22 +00:00
tudorandClaude Sonnet 4.6 a11e322017 fix(buttons): force identical height on mixed <a>/<button> pairs
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 33s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 1m7s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 0s
Set explicit height:2rem, line-height:1, font-family:inherit on all children
of button group containers. Browsers apply different default line-height and
font-family to <button> vs <a>, causing height differences that persist even
with identical padding and display:inline-flex.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 09:22:42 +00:00
tudorandClaude Sonnet 4.6 8b193c830e fix(buttons): use inline-flex on all buttons so <a> and <button> render same height
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 32s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 1m7s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 1s
<a> tags are display:inline by default and don't respect vertical padding,
while <button> is inline-block. Mixed anchor/button pairs (View/Add) rendered
at different heights despite identical padding. Apply display:inline-flex +
align-items:center to every button-styled element across SchoolRow, RankingsView,
and SchoolCard. Add border:1px solid transparent to borderless buttons so total
box size matches bordered siblings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 09:15:33 +00:00
tudorandClaude Sonnet 4.6 b3892c1629 style(buttons): standardise button sizes across all components
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 32s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 1m4s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 0s
Define two button tiers and apply consistently:
- sm (inline pairs): padding 0.5rem 1rem, font-size 0.875rem, radius 6px
- md (standalone CTAs): padding 0.625rem 1.25rem, font-size 0.9rem, radius 8px

RankingsView: viewButton was 0.25rem/0.8rem/4px vs addButton 0.5rem/0.875rem/8px
— biggest mismatch, both now sm with same radius.
SchoolCard: horizontal padding 0.75rem → 1rem, font-size 0.8125rem → 0.875rem.
SchoolRow: padding 0.4375rem → 0.5rem to match sm exactly.
SchoolDetailView: font-size 0.8125rem → 0.875rem.
ComparisonView/Modal: addButton and shareButton aligned to md spec.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 22:53:09 +00:00
tudorandClaude Sonnet 4.6 65e3d8460d style(row): move RWM score next to name, enlarge buttons, show label on mobile
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 32s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 1m3s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 1s
Group school name and score together on the left using a nameScore flex
container, so the percentage sits close to the name rather than pushed to the
far right. Action buttons get slightly more padding on desktop (0.4375rem v
0.3125rem). On mobile the scoreLabel is now visible inline instead of hidden,
so the percentage reads as R,W&M not a bare number.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 22:44:39 +00:00
tudorandClaude Sonnet 4.6 6ddfcadbde fix(search): correct radius units and distance display for postcode search
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 32s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 1m4s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 0s
FilterBar was sending radius in km (e.g. 1.6) but the backend expects miles,
causing the "Showing schools within X miles" banner to display the wrong value.
Change option values to miles (0.5, 1, 3, 5, 10) and default from 1.6 to 1.

school.distance from the API is already in miles (backend haversine uses
R=3959). SchoolRow was dividing by 1609.34 giving 0.0 mi; CompactSchoolItem
was dividing by 1.60934. Both now display school.distance directly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 22:39:50 +00:00
tudorandClaude Sonnet 4.6 0f29397253 feat(ui): replace card grid with row-based results and plain-language metric labels
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 32s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 1m2s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 1s
Replace the school card grid with a scannable row list that shows 3x more
results per screen. Each row shows: school name + R,W&M % with trend,
area/type meta, and reading/writing/maths progress scores with plain-English
band labels (e.g. "above average") instead of raw numbers.

Add lib/metrics.ts as a single source of truth for plain-language metric
explanations and the progressBand() helper. Map view toggle is unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 22:32:33 +00:00
tudorandClaude Sonnet 4.6 3d24050d11 feat(ux): implement comprehensive UX audit fixes across all pages
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 1m8s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 1m5s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 1s
Addresses 28 issues identified in UX audit (P0–P3 severity):

P0 — Critical:
- Fix compare URL sharing: seed ComparisonContext from SSR initialData
  when localStorage is empty, making /compare?urns=... links shareable
- Remove permanently broken "Avg. Scaled Score" column from school
  detail historical data table

P1 — High priority:
- Add radius selector (0.5–10 mi) to postcode search in FilterBar
- Make Add to Compare a toggle (remove) on SchoolCards
- Hide hero title/description once a search is active
- Show school count + quick-search prompts on empty landing page
- Compare empty state opens in-page school search modal directly
- Remove URN from school detail header (irrelevant to end users)
- Move map above performance chart in school detail page
- Add ← Back navigation to school detail page
- Add sort controls to search results (RWM%, distance, A–Z)
- Show metric descriptions below metric selector
- Expand ComparisonToast to list school names with per-school remove
- Add progress score explainer (0 = national average) throughout

P2 — Medium:
- Remove console.log statements from ComparisonView
- Colour-code comparison school cards to match chart line colours
- Replace plain loading text with LoadingSkeleton in ComparisonView
- Rankings empty state uses shared EmptyState component
- Rankings year filter shows actual year e.g. "2023 (Latest)"
- Rankings subtitle shows top-N count
- Add View link alongside Add button in rankings table
- Remove placeholder Privacy Policy / Terms links from footer
- Replace untappable 10px info icons with visible metric hint text
- Show active filter chips in search results header

P3 — Polish:
- Remove redundant "Home" nav link (logo already links home)
- Add / and Ctrl+K keyboard shortcut to focus search input
- Add Share button to compare page (copies URL to clipboard)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 21:31:28 +00:00