feat(ofsted): add Report Card system support alongside legacy OEIF grades
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 1m11s
Build and Push Docker Images / Build Integrator (push) Successful in 58s
Build and Push Docker Images / Build Kestra Init (push) Successful in 32s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 1s
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 1m11s
Build and Push Docker Images / Build Integrator (push) Successful in 58s
Build and Push Docker Images / Build Kestra Init (push) Successful in 32s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 1s
Ofsted replaced single overall grades with Report Cards from Nov 2025. Both systems are retained during the transition period. - DB: new framework + 9 RC columns on ofsted_inspections (schema v4) - Integrator: auto-detect OEIF vs Report Card from CSV column headers; parse 5-level RC grades and safeguarding met/not-met - API: expose all new fields in the ofsted response dict - Frontend: branch on framework='ReportCard' to show safeguarding badge + 8-category grid; fall back to legacy OEIF layout otherwise; always show inspection date in both layouts - CSS: rcGrade1–5 and safeguardingMet/NotMet classes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -575,6 +575,10 @@ def get_supplementary_data(db: Session, urn: int) -> dict:
|
||||
# Ofsted inspection
|
||||
o = safe_query(OfstedInspection, "urn")
|
||||
result["ofsted"] = {
|
||||
"framework": o.framework,
|
||||
"inspection_date": o.inspection_date.isoformat() if o.inspection_date else None,
|
||||
"inspection_type": o.inspection_type,
|
||||
# OEIF fields (old framework)
|
||||
"overall_effectiveness": o.overall_effectiveness,
|
||||
"quality_of_education": o.quality_of_education,
|
||||
"behaviour_attitudes": o.behaviour_attitudes,
|
||||
@@ -582,8 +586,16 @@ def get_supplementary_data(db: Session, urn: int) -> dict:
|
||||
"leadership_management": o.leadership_management,
|
||||
"early_years_provision": o.early_years_provision,
|
||||
"previous_overall": o.previous_overall,
|
||||
"inspection_date": o.inspection_date.isoformat() if o.inspection_date else None,
|
||||
"inspection_type": o.inspection_type,
|
||||
# Report Card fields (new framework, from Nov 2025)
|
||||
"rc_safeguarding_met": o.rc_safeguarding_met,
|
||||
"rc_inclusion": o.rc_inclusion,
|
||||
"rc_curriculum_teaching": o.rc_curriculum_teaching,
|
||||
"rc_achievement": o.rc_achievement,
|
||||
"rc_attendance_behaviour": o.rc_attendance_behaviour,
|
||||
"rc_personal_development": o.rc_personal_development,
|
||||
"rc_leadership_governance": o.rc_leadership_governance,
|
||||
"rc_early_years": o.rc_early_years,
|
||||
"rc_sixth_form": o.rc_sixth_form,
|
||||
} if o else None
|
||||
|
||||
# Parent View
|
||||
|
||||
@@ -171,6 +171,10 @@ class OfstedInspection(Base):
|
||||
inspection_date = Column(Date)
|
||||
publication_date = Column(Date)
|
||||
inspection_type = Column(String(100)) # Section 5 / Section 8 etc.
|
||||
# Which inspection framework was used: 'OEIF' or 'ReportCard'
|
||||
framework = Column(String(20))
|
||||
|
||||
# --- OEIF grades (old framework, pre-Nov 2025) ---
|
||||
# 1=Outstanding 2=Good 3=Requires improvement 4=Inadequate
|
||||
overall_effectiveness = Column(Integer)
|
||||
quality_of_education = Column(Integer)
|
||||
@@ -180,8 +184,20 @@ class OfstedInspection(Base):
|
||||
early_years_provision = Column(Integer) # nullable — not all schools
|
||||
previous_overall = Column(Integer) # for trend display
|
||||
|
||||
# --- Report Card grades (new framework, from Nov 2025) ---
|
||||
# 1=Exceptional 2=Strong 3=Expected standard 4=Needs attention 5=Urgent improvement
|
||||
rc_safeguarding_met = Column(Boolean) # True=Met, False=Not met
|
||||
rc_inclusion = Column(Integer)
|
||||
rc_curriculum_teaching = Column(Integer)
|
||||
rc_achievement = Column(Integer)
|
||||
rc_attendance_behaviour = Column(Integer)
|
||||
rc_personal_development = Column(Integer)
|
||||
rc_leadership_governance = Column(Integer)
|
||||
rc_early_years = Column(Integer) # nullable — not all schools
|
||||
rc_sixth_form = Column(Integer) # nullable — secondary only
|
||||
|
||||
def __repr__(self):
|
||||
return f"<OfstedInspection(urn={self.urn}, overall={self.overall_effectiveness})>"
|
||||
return f"<OfstedInspection(urn={self.urn}, framework={self.framework}, overall={self.overall_effectiveness})>"
|
||||
|
||||
|
||||
class OfstedParentView(Base):
|
||||
|
||||
@@ -13,11 +13,12 @@ WHEN TO BUMP:
|
||||
"""
|
||||
|
||||
# Current schema version - increment when models change
|
||||
SCHEMA_VERSION = 3
|
||||
SCHEMA_VERSION = 4
|
||||
|
||||
# Changelog for documentation
|
||||
SCHEMA_CHANGELOG = {
|
||||
1: "Initial schema with School and SchoolResult tables",
|
||||
2: "Added pupil absence fields (reading, maths, gps, writing, science)",
|
||||
3: "Added supplementary data tables: ofsted, parent_view, census, admissions, sen_detail, phonics, deprivation, finance; GIAS columns on schools",
|
||||
4: "Added Ofsted Report Card columns to ofsted_inspections (new framework from Nov 2025)",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user