refactor(admissions): rename published_admission_number to places_offered
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 18s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 46s
Build and Push Docker Images / Build Pipeline (Meltano + dbt + Airflow) (push) Failing after 13s
Build and Push Docker Images / Trigger Portainer Update (push) Has been skipped

The staging model aliased EES's total_number_places_offered column as
published_admission_number, but PAN is the school's published capacity
(not exposed by EES at school level) — what we actually have is the
count of places offered in a given admissions round. The misnomer
propagated to the mart, SQLAlchemy model, API response, TS types, and
UI copy ("places per year", "(PAN)").

Rename end-to-end and fix the UI labels:
  - "29 places for 42 first-choice applications"
      → "29 places offered for 42 first-choice applications"
  - "Reception/Year 7 places per year"
      → "Reception/Year 7 places offered"
  - drop the misleading "(PAN)" suffix in the secondary view

Also add a comment in stg_ees_admissions clarifying this is the number
of places offered, not PAN. Requires dbt to rebuild fact_admissions
(marts are materialized as tables) before the backend can start.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Tudor Sitaru
2026-04-14 09:45:43 +01:00
parent 24ba65c829
commit 6d685b7e8a
7 changed files with 19 additions and 14 deletions
+6 -6
View File
@@ -787,15 +787,15 @@ export function SchoolDetailView({
{admissions && (
<section id="admissions" className={styles.card}>
<h2 className={styles.sectionTitle}>How Hard to Get Into This School ({formatAcademicYear(admissions.year)})</h2>
{admissions.first_preference_applications != null && admissions.published_admission_number != null && (
{admissions.first_preference_applications != null && admissions.places_offered != null && (
<div className={styles.admissionsBarWrap}>
<div className={styles.admissionsBarLabel}>
<strong>{admissions.published_admission_number}</strong> places for <strong>{admissions.first_preference_applications}</strong> first-choice applications
<strong>{admissions.places_offered}</strong> places offered for <strong>{admissions.first_preference_applications}</strong> first-choice applications
</div>
<div className={styles.admissionsBarTrack}>
<div
className={`${styles.admissionsBarFill} ${admissions.oversubscribed ? styles.admissionsBarOversubscribed : styles.admissionsBarUndersubscribed}`}
style={{ width: `${Math.min(100, (admissions.published_admission_number / admissions.first_preference_applications) * 100)}%` }}
style={{ width: `${Math.min(100, (admissions.places_offered / admissions.first_preference_applications) * 100)}%` }}
/>
</div>
</div>
@@ -808,10 +808,10 @@ export function SchoolDetailView({
</div>
)}
<div className={styles.metricsGrid}>
{admissions.published_admission_number != null && (
{admissions.places_offered != null && (
<div className={styles.metricCard}>
<div className={styles.metricLabel}>{isSecondary ? 'Year 7' : 'Reception'} places per year</div>
<div className={styles.metricValue}>{admissions.published_admission_number}</div>
<div className={styles.metricLabel}>{isSecondary ? 'Year 7' : 'Reception'} places offered</div>
<div className={styles.metricValue}>{admissions.places_offered}</div>
</div>
)}
{admissions.total_applications != null && (