Group classes now carry a specific class time (alongside date and duration)
and an assigned instructor:
- Schema: add `class_time` (TIME) to `us_offerings`; `Offering` gains
`normalizeTime`/`sessionWindows`. (Rides the pending 1.0.0->1.1.0 dbDelta
upgrade, so no version bump.)
- Offering form: class-time field, plus a studio-admin instructor picker
(plain instructors always own their own classes).
- `ClassSlotReconciler`: assigning an instructor clears their open booking
slots overlapping each session and flags already-booked lessons that clash
(a booked lesson is never deleted). Uses new
`AvailabilityRepository::findOverlapping`.
- Front end: `GET /offerings` exposes `instructor_name`; the enrolment page
shows who teaches each class and when it meets.
Back-office group-class views redesigned:
- Instructor **My Group Classes** and studio-admin **Group Classes** are now
per-class summaries with enrolment counts, not flat student lists.
- Each links through (`?class_id=<id>`) to a per-class **details page**
(schedule panel, roster with payment status, and — for invite-only classes
— the add/make-available/invite-by-email controls). Invite-only membership
is managed entirely from this page.
- Invite actions are allowed for the class's owning instructor or any
`view_all_lessons` studio admin, so an owner-operator (studio admin who also
teaches) can reach every class's roster and invites from the Group Classes
page.
Tests: composer test (508), composer lint, composer cs all pass.
Co-Authored-By: Claude Opus 4.8 <[email protected]>