Commit Graph

39 Commits

Author SHA1 Message Date
0e5b71d4a0 fix(ks2): make reimport async with polling to avoid HTTP timeout
All checks were successful
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 47s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 1m12s
Build and Push Docker Images / Build Integrator (push) Successful in 58s
Build and Push Docker Images / Build Kestra Init (push) Successful in 31s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 1s
The geocoding pass over ~15k schools takes longer than any reasonable
HTTP timeout. New approach:
- POST /api/admin/reimport-ks2 starts migration in background thread,
  returns {"status":"started"} immediately
- GET /api/admin/reimport-ks2/status returns {running, done}
- ks2.py polls status every 30s (max 2h) before returning
- Kestra flow timeout bumped to PT2H

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 21:08:06 +00:00
68b15400b0 feat(ks2): enable geocoding during reimport
All checks were successful
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 47s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 1m3s
Build and Push Docker Images / Build Integrator (push) Successful in 56s
Build and Push Docker Images / Build Kestra Init (push) Successful in 32s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 1s
Add geocode query param to /api/admin/reimport-ks2 (defaults true).
ks2.py passes ?geocode=true so postcodes are resolved to lat/lng in
the same migration pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 20:57:11 +00:00
f1fb847164 feat(integrator): add KS2 re-import via Kestra and backend admin endpoint
All checks were successful
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
dd49ef28b2 feat(data): integrate 9 UK government data sources via Kestra
Some checks failed
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
Tudor Sitaru
8c60614023 Fix CSP to allow Umami analytics and remove stale GA directives
All checks were successful
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 58s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 1m48s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 1s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 15:43:51 +00:00
Tudor
5e296b6e5c Fix backend API to return location_info instead of search_location
All checks were successful
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 57s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 1m17s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 0s
The frontend expects location_info with coordinates array, but backend was
returning search_location with lat/lng keys. This fix enables the map toggle
to appear for location-based searches.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 11:38:56 +00:00
Tudor
f4919db3b9 Add automatic schema versioning with startup migration
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 57s
On startup, the app now checks if the database schema version matches
the code. If there's a mismatch or no version exists, it automatically
runs a full data migration before starting.

- Add backend/version.py with SCHEMA_VERSION constant
- Add backend/migration.py with extracted migration logic
- Add SchemaVersion model to track DB version
- Add version check functions to database.py
- Update app.py lifespan to use check_and_migrate_if_needed()
- Simplify migrate_csv_to_db.py to use shared logic

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 10:23:02 +00:00
Tudor
352eeec2db Add pupil absence data to school details modal
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 58s
Display test absence percentages (reading, maths, GPS, writing, science)
in a new section in the school modal. Requires database re-import.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 09:58:11 +00:00
Tudor
e0e3bb788e Add list/map view toggle for location search results
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 56s
When searching by location, users can now toggle between list view
(school cards grid) and a split map view showing:
- Interactive map on left with all school markers
- Scrollable school list on right
- Blue marker for search location, default markers for schools
- Clicking a marker highlights and scrolls to the corresponding card

Mobile responsive with stacked layout on smaller screens.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 11:09:35 +00:00
Tudor
75677f4252 Add contact form to footer and simplify footer content
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 59s
Replace footer note with a contact form that emails contact@schoolcompare.co.uk
via FormSubmit.co. Keep only the data source attribution. Update CSP to allow
form submissions to FormSubmit.co and add responsive styling for the form.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 20:01:47 +00:00
Tudor
1a9341eaf4 Simplify school types and persist selected schools
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m1s
- Add runtime normalization of cryptic school type codes to user-friendly names
  (e.g., AC/ACC/ACCS -> "Academy", CY/CYS -> "Community")
- Update SCHOOL_TYPE_MAP in schemas.py with consolidated mappings
- Add normalize_school_type() and get_school_type_codes_for_filter() helpers
- Persist selected schools in localStorage across page refreshes
- Move "Add to Compare" button from modal footer to header

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 15:55:23 +00:00
Tudor
9cd36a0b15 Add Google Analytics 4 with cookie consent integration
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m2s
- Add GA4 measurement ID to config (default: G-J0PCVT14NY)
- Add /api/config endpoint to expose GA ID to frontend
- Update cookie consent with Analytics category (opt-in)
- Load GA4 only after user consents to analytics cookies
- Update CSP to allow Google Analytics domains

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 15:19:05 +00:00
Tudor
6597ee40fb bug fixing
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 58s
2026-01-10 11:40:02 +00:00
Tudor
bb58d607c2 bug fix
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 56s
2026-01-10 11:32:40 +00:00
Tudor
e1383b3432 Fix postcode search ValueError when calculating distances
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 59s
Use direct bracket indexing instead of .get() for pandas Series
row access in calc_distance function to ensure scalar values
are returned for pd.isna() checks.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 11:25:21 +00:00
Tudor
79cf16d6b3 Add higher standard display and trend indicators to school cards
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 57s
- Display RWM Higher % alongside RWM Expected % on school cards
- Add trend indicators (up/down/stable arrows) showing year-over-year change
- Backend calculates previous year's RWM for trend comparison
- Trend appears on cards and in school detail modal

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 14:36:01 +00:00
Tudor
e3fc031ecf addings details and map to modal
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 59s
2026-01-09 11:52:13 +00:00
Tudor
8458d638ec bug fix
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 55s
2026-01-09 00:10:40 +00:00
Tudor
51836852e4 bug fix
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 59s
2026-01-09 00:07:51 +00:00
Tudor
116be294a3 bug fix
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 57s
2026-01-08 23:55:36 +00:00
Tudor
4b91eb403a bug fix
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 57s
2026-01-08 23:53:30 +00:00
Tudor
b7943e1042 implementing map on school card; adding more school details
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 59s
2026-01-08 23:20:42 +00:00
Tudor
1d19c88e49 bug fix
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 56s
2026-01-08 16:18:11 +00:00
Tudor
40348cb1bd moving geocoding to a background task
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 57s
2026-01-08 15:30:33 +00:00
Tudor
73971a43f0 Add SVG favicon matching logo design
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m0s
Creates a scalable favicon with the same design as the header logo:
dark background with coral-colored circle, grid lines, and center dot.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 15:10:14 +00:00
Tudor
39d0de751b Add GDPR-compliant cookie consent banner using Silktide
Implements Silktide Consent Manager via jsDelivr CDN for GDPR compliance.
The banner informs users the site only uses essential cookies and allows
them to manage preferences.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 14:59:21 +00:00
Tudor
0aafdfa382 SEO improvements
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m0s
2026-01-08 11:47:38 +00:00
Tudor
71b05769ae Fix CSP connect-src to allow cdn.jsdelivr.net
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 58s
Allow connections to cdn.jsdelivr.net for Chart.js resources.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 11:13:07 +00:00
Tudor
24ab4593f3 security improvements
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m10s
2026-01-07 16:20:49 +00:00
Tudor Sitaru
1a8ec670b9 fixing data load
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 57s
2026-01-06 22:06:59 +00:00
Tudor Sitaru
4668e19c45 database 2
Some checks failed
Build and Push Docker Image / build-and-push (push) Failing after 33s
2026-01-06 17:22:39 +00:00
Tudor Sitaru
52fbade30c Introducing Postgresql for persistance
Some checks failed
Build and Push Docker Image / build-and-push (push) Failing after 32s
2026-01-06 17:15:43 +00:00
Tudor Sitaru
bd3640d50f location search beta 1
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m3s
2026-01-06 16:59:25 +00:00
Tudor Sitaru
7684ceb9c0 adding missing la codes to list
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 58s
2026-01-06 16:42:06 +00:00
Tudor Sitaru
eb986b2644 fixed issue
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 54s
2026-01-06 16:34:15 +00:00
Tudor Sitaru
54e4bc2e77 Refactoring and bug fixes
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m7s
2026-01-06 16:30:32 +00:00
Tudor Sitaru
0ea4720ac1 Including all schools in England
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 58s
2026-01-06 16:17:00 +00:00
Tudor Sitaru
1e3fd5f8cc Making adjustments to branding to reflect new domain
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 57s
2026-01-06 15:39:06 +00:00
Tudor Sitaru
c65eb1a00f initial commit 2026-01-06 13:52:00 +00:00