Update availability, lesson-booking, and user-roles docs and add specs for offerings, group classes, registration questions, versioned policies, Stripe payments (with e-transfer/comp overrides and receipts), and monthly per-instructor payment reporting. Tracked in issues #1-#9. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4.7 KiB
Feature: Lesson Booking
Overview
Students register for a private lesson by choosing an offering, picking a time (or reserving a weekly slot for the term), answering the offering's intake questions, accepting current policies, and paying. Instructors confirm or cancel from wp-admin or via the REST API. A lesson becomes confirmed only once its payment is paid (or the student is comp'd).
Data Model — {prefix}us_lessons
| Column | Type | Notes |
|---|---|---|
id |
BIGINT UNSIGNED | Primary key |
slot_id |
BIGINT UNSIGNED | FK → us_availability.id |
offering_id |
BIGINT UNSIGNED | FK → us_offerings.id (the private-lesson type booked) |
student_id |
BIGINT UNSIGNED | WordPress user ID |
instructor_id |
BIGINT UNSIGNED | WordPress user ID (denormalised for fast queries) |
recurrence |
VARCHAR(10) | single or weekly |
series_id |
BIGINT UNSIGNED | Nullable — groups the lesson rows of one weekly reservation |
status |
VARCHAR(20) | pending / confirmed / cancelled |
payment_id |
BIGINT UNSIGNED | Nullable FK → us_payments.id |
notes |
TEXT | Optional student notes |
created_at |
DATETIME | Insertion time |
Registration Flow
- Student opens the page with the
[us_booking]shortcode and browses the calendar. - Student picks an offering (a 30 or 60-minute private-lesson type) and a slot.
- For a
weeklyreservation, the same weekday/time is held for the rest of the offering's term. - Student answers the offering's questions (
GET /offerings/{id}/questions). - Student accepts the current published policy versions (
GET /policies) — required to continue. - Payment is taken per the student's billing method (card by default;
pendingfor e-transfer; skipped for comp). Seepayments.md. POST /bookingscreates the lesson row(s) (status = pending), records answers and policy acceptances, marksus_availability.is_booked = 1, and links the payment.- On successful payment (or comp) the lesson is
confirmedand a receipt is emailed. - Instructor sees the booking under My Lessons and may update status via
PATCH /bookings/{id}/status.
Weekly Reservations
A weekly reservation creates one series_id shared across N lesson rows (one per
week in the term) and reserves the matching availability windows. It is billed
full-term upfront as a single payment (billing_mode = full_term on the
offering).
REST API
| Method | Endpoint | Permission |
|---|---|---|
GET |
/wp-json/us-scheduler/v1/bookings |
Any logged-in user |
POST |
/wp-json/us-scheduler/v1/bookings |
book_lesson |
PATCH |
/wp-json/us-scheduler/v1/bookings/{id}/status |
manage_availability or admin |
POST /bookings body: offering_id, slot_id, recurrence, answers[]
(question_id → value), accepted_policy_version_ids[], and payment data
(see payments.md).
GET /bookings returns the caller's own lessons (student view) or upcoming lessons for the instructor if the caller has manage_availability.
Group classes follow the same registration flow but enrol against an offering of
kind group_class; see group-classes.md.
Admin Interface
- Scheduler (
manage_optionsonly): all upcoming lessons across all instructors - My Lessons (
view_own_lessons): upcoming lessons for the logged-in instructor
Frontend Shortcodes
[us_booking]— student calendar + registration flow; requiresbook_lessoncapability[us_student_login]— front-end login form for students
Implementation
- Repository:
Unsupervised\Schedular\Booking\BookingRepository - Model:
Unsupervised\Schedular\Booking\Lesson - Admin controller:
Unsupervised\Schedular\Booking\LessonController - REST endpoint:
Unsupervised\Schedular\Booking\BookingEndpoint - Frontend:
Unsupervised\Schedular\Booking\BookingPage,Unsupervised\Schedular\Auth\LoginPage
Tests
tests/Unit/Booking/BookingRepositoryTest.phptests/Unit/Booking/LessonTest.php