PU College: institution type & academic setup¶
Pre-University (PU) colleges run classes 11 and 12 with Science / Commerce / Arts streams, and they're the institution type NEET and JEE aspirants belong to. Kwilo could already create a pu_college (via the Schools page) but couldn't set up its academics: every academic-setup surface routed pu_college into the higher-ed flow (Programs → Branches → Semesters), which PU has no concept of. This feature makes PU College a first-class type with a class-based, stream-aware setup (1st/2nd PU + combinations), so a PU admin can onboard end-to-end and enroll students by stream.
How it works¶
PU sits between K-12 and higher-ed and shares pieces of both: minors (face-consent required), NCERT-eligible, and class-based rather than semester-based. The structural unit a student enrolls into is a combination of exactly four electives (PCMB, PCMC, EBAC, HEPS, …), not a broad stream, because the combination drives subjects and exam track (NEET vs JEE).
PU College (org_unit_type = pu_college) class-based, NOT semester
Program "PU" (program_type=school, grades 11-12)
└── Branch = combination (PCMB · PCMC · EBAC · HEPS · …) ← the enrollable unit
├── AcademicLevel: Class 11, Class 12
└── 4 elective subjects, assigned mandatory to each level
A student enrolls into a combination + year (e.g. 2nd PU PCMB). There are no sections in this model.
Routing keys off the class-vs-semester axis¶
The bug was that academic-setup surfaces keyed off isHigherEducation (HIGHER_ED_TYPES includes pu_college) instead of the class-vs-semester axis. Routing now keys off usesClasses / usesSemesters (already correct for PU in apps/web/src/utils/institutionType.ts), so pu_college lands in the class-based structure. HIGHER_ED_TYPES is left untouched so analytics, attendance, calendar, and enrollment surfaces that intentionally treat PU as "college" don't regress.
First-class onboarding type¶
Onboarding has a third PU College bucket (TInstitutionType = 'k12' | 'pu' | 'college') with its own setup step: pick combinations (curated presets grouped by stream, plus a custom-combination form), which creates Program(school, 11–12) → Branch per combination → AcademicLevel Class 11/12, and creates and assigns each combination's four electives. The academic-setup view for pu_college reuses the hierarchical CollegeCurriculumPage, which is generic over orgUnitId.
The onboarding write-back is guarded so an existing pu_college is never overwritten to k12_school (the K-12 wizard's handleTypeNext hard-sets the type otherwise). On the hierarchical view, PU switches to class vocabulary (tab "Classes", "Add class", "Select class", empty/delete states) via hasSchoolProgram(programs) + getLevelTermKeys; colleges are unchanged. AcademicSetupPage shows a "PU College" badge.
No backend change was needed: the backend already accepts program_type=school, start_grade / end_grade, and level_type=class.
Non-goals¶
- Not building NEET/JEE test-prep content or question banks. This is institution modeling + academic setup only.
- Not reworking the higher-ed (Programs/Branches/Semesters) flow for degree/engineering colleges.
- Not changing how
pu_collegeis treated in analytics, attendance, calendar, or user-enrollment beyond correct structure. Those revisit deliberately, not wholesale. - Standalone NEET/JEE coaching centers that aren't PU colleges are a different org type (
training_center), out of scope.
Where it lives¶
- Routes:
/admin/schools(institution type),/admin/academic-setup(structure), org-admin Institution Onboarding wizard. apps/web/src/utils/institutionType.ts:HIGHER_ED_TYPES,CLASS_BASED_TYPES/SEMESTER_BASED_TYPES,usesClasses/usesSemesters,isHigherEducation.apps/web/src/pages/school-admin/AcademicSetupPage/index.tsx:viewModerouting.apps/web/src/pages/org-admin/InstitutionOnboardingPage/:deriveInstitutionType,handleTypeNextwrite-back,helpers/institutionRouting.ts.apps/backend/src/models/academic.py:Program(start_grade/end_grade),Branch,Class.apps/backend/src/models/org_unit.py:OrgUnitType.PU_COLLEGE,K12_ORG_UNIT_TYPES,CONSENT_REQUIRED_ORG_UNIT_TYPES.