Group classes now carry a specific class time (alongside date and duration) and an assigned instructor, students see who teaches each class and when it meets, and the back-office group-class views are reworked into per-class summaries that click through to a full details page from which invite-only membership is managed.
Class time & instructor
Schema: add class_time (TIME) to us_offerings; Offering gains normalizeTime and sessionWindows. No version bump — 1.1.0 is unreleased, so this rides the pending 1.0.0→1.1.0 dbDelta upgrade.
Offering form gains a class-time field and a studio-admin Instructor picker (plain instructors always own the classes they create).
Offering\ClassSlotReconciler: assigning an instructor to a scheduled class clears their open booking slots overlapping each session and flags any already-booked lesson that clashes (a booked lesson is never deleted). Backed by new AvailabilityRepository::findOverlapping.
GET /offerings exposes instructor_name; the enrolment page shows the instructor and when the class meets.
Back-office views
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 permitted for the class's owning instructor or any view_all_lessons studio admin, so an owner-operator (studio admin who also teaches — for whom the My Group Classes menu is hidden) can reach every class's roster and invites from the Group Classes page.
Instructor name display
New Auth\UserName::format() shows the instructor's real name (first + last) or nickname, never their login/username; the front-end instructor_name and both back-end group-class views route through it.
Tests
composer test — 513 tests, 1484 assertions, all pass
composer lint (PHPStan level 10) — clean
composer cs (PHPCS WordPress standards) — clean
Docs (docs/features/offerings.md, docs/features/group-classes.md) and the [1.1.0] CHANGELOG section updated.
## Summary
Group classes now carry a specific **class time** (alongside date and duration) and an **assigned instructor**, students see who teaches each class and when it meets, and the back-office group-class views are reworked into per-class summaries that click through to a full details page from which invite-only membership is managed.
### Class time & instructor
- Schema: add `class_time` (TIME) to `us_offerings`; `Offering` gains `normalizeTime` and `sessionWindows`. No version bump — 1.1.0 is unreleased, so this rides the pending 1.0.0→1.1.0 `dbDelta` upgrade.
- Offering form gains a class-time field and a studio-admin **Instructor** picker (plain instructors always own the classes they create).
- `Offering\ClassSlotReconciler`: assigning an instructor to a scheduled class clears their **open** booking slots overlapping each session and **flags** any already-booked lesson that clashes (a booked lesson is never deleted). Backed by new `AvailabilityRepository::findOverlapping`.
- `GET /offerings` exposes `instructor_name`; the enrolment page shows the instructor and when the class meets.
### Back-office views
- 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 permitted for the class's owning instructor **or** any `view_all_lessons` studio admin, so an owner-operator (studio admin who also teaches — for whom the *My Group Classes* menu is hidden) can reach every class's roster and invites from the **Group Classes** page.
### Instructor name display
- New `Auth\UserName::format()` shows the instructor's real name (first + last) or nickname, never their login/username; the front-end `instructor_name` and both back-end group-class views route through it.
## Tests
- `composer test` — 513 tests, 1484 assertions, all pass
- `composer lint` (PHPStan level 10) — clean
- `composer cs` (PHPCS WordPress standards) — clean
Docs (`docs/features/offerings.md`, `docs/features/group-classes.md`) and the `[1.1.0]` CHANGELOG section updated.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Add Auth\UserName::format(), which prefers a user's first + last name, then
their nickname, avoiding display_name (which can be the login/username).
Route the instructor name through it in both the front-end offerings response
(instructor_name) and the back-end group-class summary and details views.
Tests: composer test (513), composer lint, composer cs all pass.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Group classes now carry a specific class time (alongside date and duration) and an assigned instructor, students see who teaches each class and when it meets, and the back-office group-class views are reworked into per-class summaries that click through to a full details page from which invite-only membership is managed.
Class time & instructor
class_time(TIME) tous_offerings;OfferinggainsnormalizeTimeandsessionWindows. No version bump — 1.1.0 is unreleased, so this rides the pending 1.0.0→1.1.0dbDeltaupgrade.Offering\ClassSlotReconciler: assigning an instructor to a scheduled class clears their open booking slots overlapping each session and flags any already-booked lesson that clashes (a booked lesson is never deleted). Backed by newAvailabilityRepository::findOverlapping.GET /offeringsexposesinstructor_name; the enrolment page shows the instructor and when the class meets.Back-office views
?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.view_all_lessonsstudio admin, so an owner-operator (studio admin who also teaches — for whom the My Group Classes menu is hidden) can reach every class's roster and invites from the Group Classes page.Instructor name display
Auth\UserName::format()shows the instructor's real name (first + last) or nickname, never their login/username; the front-endinstructor_nameand both back-end group-class views route through it.Tests
composer test— 513 tests, 1484 assertions, all passcomposer lint(PHPStan level 10) — cleancomposer cs(PHPCS WordPress standards) — cleanDocs (
docs/features/offerings.md,docs/features/group-classes.md) and the[1.1.0]CHANGELOG section updated.🤖 Generated with Claude Code