Semesters & Locations
Tables: semesters, locations, semester_locations,
semester_location_dates, semester_location_teachers
locations
The physical sites where BCM teaches, seeded with Access Bronx Charter
School and Bronx Community College. Columns: name, address,
is_active. Locations are global; which ones are in use for a given term is a
per-semester decision (below).
semesters
The organizing unit of the whole schedule. A semester is a season
ENUM(fall,spring,summer,test) plus a year, unique together, with a
start_date and end_date.
“Current semester” resolution
(SemesterManagement::resolveDefaultSemester): the semester containing
today, else the next future one, else the most recent past one. test
semesters are ignored unless nothing else exists.
The semester also carries all pricing (moved here from the settings table, so each term can have its own prices):
| Column | Meaning |
|---|---|
registration_fee |
Charged once per student when their reservation is confirmed |
lesson_fee_30_minutes |
Bronx residents: full-semester price for weekly 30-minute private lessons |
lesson_fee_60_minutes |
Bronx residents: full-semester price for weekly 60-minute private lessons |
guitar_ensemble_fee |
Bronx residents: full-semester price for 30-minute Guitar Ensemble |
lesson_fee_30_minutes_nonresident |
Non-residents / online students: 30-minute lessons |
lesson_fee_60_minutes_nonresident |
Non-residents / online students: 60-minute lessons |
guitar_ensemble_fee_nonresident |
Non-residents / online students: Guitar Ensemble |
recital_fee |
Charged per lesson block |
installment_plan_fee |
One-time fee for paying tuition in two installments |
lessons_per_semester |
Default 15; used for per-lesson price display on the registration form |
These fee columns are DECIMAL(8,2) dollars; they are converted to integer
cents when charges are posted to the ledger.
semester_locations
Which locations are in use for a semester — step 2 of the semester creation
wizard. Just the unique (semester_id, location_id) pair, cascading from
both sides.
semester_location_weekdays
The declared class days: which weekdays each location holds classes on
for a semester, with that day’s standard hours — imported by CSV in the
wizard (step 3), unique on (semester_id, location_id,
day_of_week) with start_time/end_time. This is the explicit,
higher-level statement the rest of the semester hangs off: the class-dates
import rejects a date on an undeclared weekday (and blank times inherit the
declared hours), an explicit day in the location-teachers import must be a
day the location is open, and the schedule grid draws a day’s band over these
hours as soon as the day is declared — before any dates are imported.
Derivations use the union of declared weekdays and actual class-date
weekdays, so a one-off date on an odd weekday still counts. Locations that
predate declarations (none declared) are simply unchecked.
semester_location_dates
The class calendar per location, imported by CSV in the wizard (step 3).
One row per (semester, location, date) — unique together — with start_time,
end_time, a status ENUM(active,inactive), and a title (the CSV notes
column: “Day 1”, “Holiday Week”).
Inactive rows are breaks and holidays: they are surfaced to students on their schedule (“Holiday Week”) but generate no lessons. This table is what drives lesson generation — a confirmed reservation produces one lesson per active date at its location that falls on its day of week.
semester_location_teachers
Which teachers teach at which location on which day of the week for a
semester — wizard step 4, unique on (semester_id, location_id,
teacher_user_id, day_of_week). These are the columns of the Semester
Schedule in the admin UI — the schedule draws one grid per class day, and a
teacher who works Saturdays but not Tuesdays has a Saturday row only —
and sort_order fixes the column order within a location. A reservation can
only be placed in a column that exists here, which is why carrying a schedule
forward to a new semester skips reservations whose teacher no longer teaches
at that location on that day.
