d1dd30dc60bd039776e9d94f8726cf9125947eb2
21
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
36e7178158 |
Merge pull request 'Show booked lesson info on upcoming lists and add admin booking detail' (#104) from feature/lesson-booking-detail into main
CI / Tests (PHP 8.2) (push) Successful in 39s
CI / Coding Standards (push) Successful in 2m52s
CI / PHPStan (push) Successful in 2m55s
CI / Tests (PHP 8.3) (push) Successful in 2m36s
CI / Tests (PHP 8.1) (push) Successful in 55s
CI / No Debug Code (push) Successful in 2s
CI / Build Plugin Zip (push) Successful in 2m46s
Reviewed-on: #104 |
||
|
|
32619a1b75
|
Show booked lesson info on upcoming lists and add admin booking detail
CI / Tests (PHP 8.1) (pull_request) Successful in 46s
CI / Coding Standards (pull_request) Successful in 2m53s
CI / Tests (PHP 8.2) (pull_request) Successful in 44s
CI / No Debug Code (pull_request) Successful in 3s
CI / PHPStan (pull_request) Successful in 3m12s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m36s
CI / Build Plugin Zip (pull_request) Skipped
Front end: the student "upcoming lessons" panel now shows each booked offering's name and length next to the time, and renders only the soonest five lessons with a "Show all" reveal. GET /bookings returns offering_title and duration_minutes so the list needs no extra request. Admin: the Scheduler and My Lessons week/list views now show the booked offering, and each lesson links to a detail view showing the policy versions the student accepted (with acceptance time and IP) and their intake answers. On My Lessons an instructor may only open their own lessons; the studio Scheduler may open any. composer test / composer lint / composer cs all pass. Co-Authored-By: Claude Opus 4.8 <[email protected]> |
||
|
|
fc7c0fa966
|
Show "Enrol by <date>" on the group-class card while enrolment is open
CI / Build Plugin Zip (pull_request) Skipped
CI / Tests (PHP 8.1) (pull_request) Successful in 46s
CI / Tests (PHP 8.2) (pull_request) Successful in 48s
CI / No Debug Code (pull_request) Successful in 2s
CI / PHPStan (pull_request) Successful in 2m47s
CI / Coding Standards (pull_request) Successful in 3m1s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m40s
The front end used the deadline only to gate the Enrol button; students had no way to see when enrolment closes. Add an "Enrol by <date>" line to each class card, shown while enrolment is still open, for the effective deadline (the instructor's date, or the first class day by default). Co-Authored-By: Claude Opus 4.8 <[email protected]> |
||
|
|
bf29162587
|
Add group-class enrolment deadline with instructor late-enrolment override
CI / Tests (PHP 8.1) (pull_request) Successful in 48s
CI / Tests (PHP 8.2) (pull_request) Successful in 47s
CI / No Debug Code (pull_request) Successful in 3s
CI / PHPStan (pull_request) Successful in 2m51s
CI / Coding Standards (pull_request) Successful in 3m2s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m37s
CI / Build Plugin Zip (pull_request) Skipped
Group classes gain an instructor-set enrolment deadline (new us_offerings.enrollment_deadline column) that defaults to the first day of the class (term_start). Past the deadline students can no longer self-enrol: the enrolment endpoint rejects it (403 enrollment_closed) and the front-end class list shows "Enrolment has closed." in place of the Enrol button. Instructors keep a manual path: the "Add students directly" control on each class's details page now renders for public classes too (not just invite-only) and deliberately bypasses the deadline and capacity, so a student can be added as a late enrolment after the class has closed. Past the deadline the details page labels these as late enrolments. Bumps USC_VERSION to 1.1.3 for the schema change. Co-Authored-By: Claude Opus 4.8 <[email protected]> |
||
|
|
b066bef353
|
Add group-class scheduling, instructor assignment, and details/invite management
CI / Tests (PHP 8.2) (pull_request) Successful in 39s
CI / Tests (PHP 8.1) (pull_request) Successful in 46s
CI / No Debug Code (pull_request) Successful in 2s
CI / Coding Standards (pull_request) Successful in 2m52s
CI / PHPStan (pull_request) Successful in 2m50s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m36s
CI / Build Plugin Zip (pull_request) Skipped
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]> |
||
|
|
49c59a950c
|
Add studio-defined account-registration questions
CI / Tests (PHP 8.2) (pull_request) Successful in 44s
CI / Tests (PHP 8.1) (pull_request) Successful in 45s
CI / No Debug Code (pull_request) Successful in 2s
CI / Coding Standards (pull_request) Successful in 2m46s
CI / PHPStan (pull_request) Successful in 2m58s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m41s
CI / Build Plugin Zip (pull_request) Skipped
Studio admins can now define registration questions that every new student answers as a required second step during signup, with each student's answers shown under a "Registration Information" section in the admin. Extends the existing Registration domain: us_questions gains a scope column (offering | account) and a nullable offering_id, and account answers reuse us_question_answers with registration_type = 'account'. Authoring reuses the Offerings -> Questions page via an "Account signup" scope (studio-admin only). The registration form becomes two steps (progressive enhancement via assets/js/register.js; works without JS); required answers are validated before the account is created and apply to all signup paths (invite, group link, self-approval). StudentHistory::registrationInfo() powers the admin section. Bumps the plugin version to 1.1.0 so dbDelta runs the schema migration. Closes #90 Co-Authored-By: Claude Opus 4.8 <[email protected]> |
||
|
|
14f43232c9
|
Default lessons to a week view on the booking page and in wp-admin
CI / Tests (PHP 8.2) (pull_request) Successful in 1m15s
CI / Tests (PHP 8.1) (pull_request) Successful in 1m16s
CI / No Debug Code (pull_request) Successful in 2s
CI / Coding Standards (pull_request) Successful in 3m15s
CI / PHPStan (pull_request) Successful in 3m14s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m37s
CI / Build Plugin Zip (pull_request) Skipped
The front-end booking calendar now opens in the Week view (anchored to the week of the earliest open slot) with List still available. The Scheduler and My Lessons admin pages gain a week calendar (usc_view/usc_week, bucketed via a new generic WeekCalendar::bucket()) and open in it by default; the original table remains as the List view since it carries the HST / e-transfer forms. Closes #76 Co-Authored-By: Claude Fable 5 <[email protected]> |
||
|
|
7b00811133
|
Show a sign-in link instead of the form after email confirmation
CI / Tests (PHP 8.2) (pull_request) Successful in 41s
CI / Tests (PHP 8.1) (pull_request) Successful in 46s
CI / No Debug Code (pull_request) Successful in 2s
CI / PHPStan (pull_request) Successful in 2m45s
CI / Coding Standards (pull_request) Successful in 2m55s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m35s
CI / Build Plugin Zip (pull_request) Skipped
Closes #67 When a student lands on the registration page from the confirmation email (?us_confirmed=1), replace the registration form with the confirmation message and a "Sign in to your account" link — the form is useless at that point and re-submitting would only produce an "account already exists" error. A confirmed-but-unapproved student can already log in (the pending gate only withholds booking), so signing in is the natural next step. The link target follows the booking block's pattern: a loginPageId block attribute (page picker in the editor sidebar) or login_page_id shortcode attribute, falling back to wp_login_url(). The expired-link notice keeps the form as before. Co-Authored-By: Claude Fable 5 <[email protected]> |
||
|
|
30b0112431
|
Show enrolment status on the student group classes page
CI / Tests (PHP 8.2) (pull_request) Successful in 48s
CI / Tests (PHP 8.1) (pull_request) Successful in 49s
CI / No Debug Code (pull_request) Successful in 2s
CI / PHPStan (pull_request) Successful in 1m17s
CI / Tests (PHP 8.3) (pull_request) Successful in 37s
CI / Coding Standards (pull_request) Successful in 2m47s
CI / Build Plugin Zip (pull_request) Has been skipped
The class list now loads the student's own enrolments alongside the catalog; a class they already have an active enrolment in shows "You are enrolled in this class." instead of the Enrol button, in both the browse-all catalog and the single-class embed mode. Previously the button always rendered and a duplicate attempt walked the student through the whole questions/policies flow before failing with 409 already_enrolled. A cancelled enrolment does not block re-enrolling, matching the server-side duplicate rule. Closes #61 Co-Authored-By: Claude Fable 5 <[email protected]> |
||
|
|
cde8704267
|
Group class term dates, single-class embed mode, and offering editing
CI / Tests (PHP 8.2) (pull_request) Successful in 45s
CI / Tests (PHP 8.1) (pull_request) Successful in 48s
CI / No Debug Code (pull_request) Successful in 2s
CI / Coding Standards (pull_request) Successful in 1m14s
CI / PHPStan (pull_request) Successful in 1m16s
CI / Tests (PHP 8.3) (pull_request) Successful in 37s
CI / Build Plugin Zip (pull_request) Has been skipped
Group class offerings now carry real dates: the add/edit form takes a start date plus a sessions control (one-off, or weekly for N sessions; the end date is computed as start + (N-1) weeks via Offering::weeklyTermEnd). Dates are validated strictly (Y-m-d) and shown in the offerings list and on the student-facing class card, including the weekly session count. [us_group_classes offering="<id>"] (block attribute offeringId, chosen from a dropdown of active classes fetched from the public offerings endpoint) restricts the page to a single class so the enrolment flow can be embedded on a page dedicated to that class; a pinned class that is no longer offered reports itself closed instead of falling back to the catalog. Offerings are now editable from the admin screen: an Edit button prefills the shared add/edit form and saving posts usc_action=update. Updates always preserve the original owner and currency, and non-admin instructors can only load and update their own offerings. The form also gains the previously missing description field and an Active toggle (the admin-UI counterpart of the REST is_active flag) so an edit cannot wipe data the form never collected. Closes #59 Co-Authored-By: Claude Fable 5 <[email protected]> |
||
|
|
c7d5d72c9c
|
Require an offering on every lesson booking, with a student-facing picker
CI / Tests (PHP 8.1) (pull_request) Successful in 41s
CI / Tests (PHP 8.2) (pull_request) Successful in 45s
CI / No Debug Code (pull_request) Successful in 2s
CI / Tests (PHP 8.3) (pull_request) Successful in 1m40s
CI / PHPStan (pull_request) Successful in 2m24s
CI / Coding Standards (pull_request) Successful in 2m49s
CI / Build Plugin Zip (pull_request) Has been skipped
Generic slots (no tied offering) were bookable with no offering at all: free, instantly confirmed, and with no intake questions. POST /bookings now rejects offering-less bookings (400 offering_required), and a student-chosen offering must be an active private-lesson type owned by the slot's instructor whose duration matches the slot. The registration form gains a Lesson type field: locked to the slot's tied offering (title, duration, price) so the student sees what they are booking, or a required picker of fitting offerings for generic slots, with intake questions following the selection. Fixes #55 Co-Authored-By: Claude Fable 5 <[email protected]> |
||
|
|
ab90dae638
|
Let students cancel their own lessons from the booking page
CI / No Debug Code (push) Successful in 3s
CI / Coding Standards (push) Successful in 46s
CI / Tests (PHP 8.1) (push) Successful in 45s
CI / Tests (PHP 8.2) (push) Successful in 45s
CI / PHPStan (push) Successful in 1m11s
CI / Tests (PHP 8.3) (push) Successful in 1m0s
CI / Build Plugin Zip (push) Successful in 1m10s
Adds POST /bookings/{id}/cancel (owner-only, idempotent): marks the lesson
cancelled, releases the availability slot for rebooking, and voids a
still-pending payment so it leaves the admin confirmation queue. Paid
payments are untouched — refunds stay a manual admin decision.
The instructor PATCH /bookings/{id}/status path now does the same slot
release and payment voiding on cancellation (previously cancelled lessons
left their slot permanently booked), and reinstating a cancelled lesson
re-claims the slot, rejecting with 409 if the freed time was rebooked.
The "Your upcoming lessons" panel gets a Cancel button with a confirm
prompt; on success both the lesson list and the slot calendar refresh.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
||
|
|
5888032ed7
|
Skip payment step for unpriced bookings, confirm them immediately, show students their lessons
CI / No Debug Code (pull_request) Successful in 2s
CI / Tests (PHP 8.2) (pull_request) Successful in 53s
CI / PHPStan (pull_request) Successful in 2m46s
CI / Tests (PHP 8.1) (pull_request) Successful in 42s
CI / Coding Standards (pull_request) Successful in 47s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m35s
CI / Build Plugin Zip (pull_request) Has been skipped
Booking a slot with no priced offering created the lesson but no payment,
yet the front end still called POST /payments/intent, which 400ed with
"Could not start payment for this registration" — the student saw an error
while the backend held a claimed slot and a lesson stuck at pending.
- POST /bookings and POST /enrollments now return a `payment` summary
({id, method, status}) or null when nothing is owed; the JS only runs
the payment step when a payment exists.
- Bookings with nothing owed are confirmed at creation — there is no
payment step that would ever confirm them later.
- The booking page now shows the student's upcoming lessons (GET /bookings,
now scoped to upcoming non-cancelled lessons with slot start/end times)
with a pending-payment/confirmed status badge.
Fixes #53
Co-Authored-By: Claude Fable 5 <[email protected]>
|
||
|
|
9d89bc6d0e
|
Add link-target and auto-redirect options to booking/login blocks
CI / Coding Standards (pull_request) Successful in 51s
CI / No Debug Code (pull_request) Successful in 3s
CI / Tests (PHP 8.2) (pull_request) Successful in 50s
CI / Tests (PHP 8.3) (pull_request) Successful in 1m2s
CI / Build Plugin Zip (pull_request) Has been skipped
CI / Tests (PHP 8.1) (pull_request) Successful in 53s
CI / PHPStan (pull_request) Successful in 1m24s
The booking block gains a loginPageId attribute choosing which page its logged-out "log in to book a lesson" link points to (default remains the WordPress login screen), and the student-login block gains a bookingPageId attribute controlling the logged-in "View available lessons" link and the post-login redirect target (default remains the current page). Both blocks also gain an autoRedirect toggle, off by default, that sends the visitor straight to the target page; block rendering starts after output, so the redirect runs on template_redirect by parsing the queried page's content for the block, with a self-target guard against redirect loops. The link targets are also available to the shortcodes as login_page_id/booking_page_id. Also fixes a pre-existing fatal: WordPress passes an empty string (not an array) to shortcode callbacks when a shortcode is used without attributes, so bare [us_booking] etc. threw a TypeError against the strictly-typed render(array $atts) methods. ShortcodeRegistrar now wraps each callback to normalize non-array attribute values. Closes #51 Co-Authored-By: Claude Fable 5 <[email protected]> |
||
|
|
b7d5e3039e
|
Split availability windows into bookable lesson-length slots with weekly calendar views
CI / Build Plugin Zip (pull_request) Has been skipped
CI / Tests (PHP 8.2) (pull_request) Successful in 45s
CI / PHPStan (pull_request) Successful in 2m48s
CI / Tests (PHP 8.1) (pull_request) Successful in 41s
CI / No Debug Code (pull_request) Failing after 2s
CI / Coding Standards (pull_request) Successful in 52s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m36s
Availability windows were stored and served as a single bookable row, so a 9:00 AM-4:00 PM window showed to students as one giant slot and booking it consumed the whole day; past and multi-day windows also leaked into the booking page as nonsense entries. - Split windows into consecutive lesson-length slots on save (REST and admin form); each chunk is independently bookable and weekly recurrence creates a series per chunk so "reserve this time weekly" holds the same hour each week - Reject windows spanning multiple days or shorter than the lesson length (400 invalid_window) - Never return slots whose start has passed from GET /availability - Migrate pre-split rows: Plugin::boot re-runs the Installer on version change and AvailabilityRepository::splitOversizedWindows() rewrites unbooked same-day oversized windows in place - Display all times in 12-hour AM/PM form (booking page, wp-admin lists, editor previews) - Add a List | Week view toggle to the student booking page and the instructor availability page, with previous/next-week navigation honouring the site's start_of_week option (new WeekCalendar helper) Co-Authored-By: Claude Fable 5 <[email protected]> |
||
|
|
fc70cde9d5
|
Add Gutenberg dynamic-block wrappers for the front-end shortcodes
CI / No Debug Code (pull_request) Successful in 4s
CI / Tests (PHP 8.2) (pull_request) Successful in 52s
CI / Tests (PHP 8.1) (pull_request) Successful in 54s
CI / Tests (PHP 8.3) (pull_request) Successful in 1m29s
CI / Coding Standards (pull_request) Successful in 1m57s
CI / PHPStan (pull_request) Successful in 2m14s
CI / Build Plugin Zip (pull_request) Has been skipped
Wrap the four shortcodes (us_booking, us_student_login, us_student_register, us_group_classes) in dynamic blocks so pages can be previewed and styled in the block editor. Front-end rendering delegates to the same page objects the shortcodes use; in the editor's block-renderer REST preview a static, script-free BlockPreview is rendered instead (no live REST calls, redirects, or Stripe.js). The editor script (vanilla JS, no build step) registers each block with wp.serverSideRender previews and shortcode transforms; frontend.css is attached as the block style so previews pick up theme styling. Resolves #44 Co-Authored-By: Claude Fable 5 <[email protected]> |
||
|
|
925a4b79ba
|
Add live Stripe card charges (PaymentIntent + Elements + webhook)
CI / No Debug Code (pull_request) Successful in 40s
CI / Tests (PHP 8.2) (pull_request) Successful in 48s
CI / Coding Standards (pull_request) Successful in 1m0s
CI / PHPStan (pull_request) Successful in 1m13s
CI / Tests (PHP 8.1) (pull_request) Successful in 2m9s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m8s
CI / Build Plugin Zip (pull_request) Has been skipped
Completes the deferred half of payments: real credit-card processing on top of the existing ledger/e-transfer/comp foundation. - StripeGateway wraps stripe/stripe-php: creates idempotent PaymentIntents (amount in cents, registration ids in metadata) and verifies webhook signatures. Stripe calls sit behind protected seams for unit testing. - PaymentService::createIntent resolves the client-side step for a new registration (card → client secret; e-transfer → display data; comp → none) with caller-ownership enforcement. - PaymentService::handleWebhook finalises a payment exactly once on payment_intent.succeeded (mark paid → confirm → receipt) and marks it failed on payment_intent.payment_failed. - PaymentEndpoint: POST /payments/intent (book_lesson) and public, signature-verified POST /payments/webhook. - PaymentRepository: setStripeIntentId / findByStripeIntentId. - StudioSettings: us_stripe_webhook_secret option, with the webhook URL and required events surfaced on the settings page. - Front end: shared payment.js mounts Stripe Payment Elements and confirms the card (or shows e-transfer instructions); Stripe.js enqueued only when configured. Wired into booking and group-class flows. Tests: new StripeGatewayTest; PaymentService card-intent + webhook cases; repository coverage. composer test/lint/cs all green. Co-Authored-By: Claude Opus 4.8 <[email protected]> |
||
|
|
9cb5207dcd
|
Add group-class enrolment (year commitment, capacity, registration gate)
CI / Tests (PHP 8.1) (pull_request) Successful in 45s
CI / Coding Standards (pull_request) Successful in 50s
CI / PHPStan (pull_request) Successful in 1m4s
CI / No Debug Code (pull_request) Successful in 2s
CI / Tests (PHP 8.2) (pull_request) Successful in 42s
CI / Tests (PHP 8.3) (pull_request) Successful in 42s
CI / Build Plugin Zip (pull_request) Has been skipped
Implements #4: students enrol in a group_class offering via the same registration gate as private lessons (intake questions + booking-scoped policy acceptance). Enrolment is capacity-enforced and prevents duplicates. - Schema: us_group_enrollments table. - Enrollment value object + EnrollmentRepository (countActiveForOffering, hasActiveEnrollment, per-student/instructor/all-active queries, status). - EnrollmentEndpoint: GET /enrollments (scoped) and POST /enrollments (validates group_class, capacity, no-duplicate; reuses RegistrationGate; records answers/acceptances type enrollment). - GroupClassController + admin page (view_all_lessons): all active enrolments. - Front-end: [us_group_classes] shortcode (GroupClassPage) + group-classes.js enrol flow (list classes -> questions + policies -> POST /enrollments). - Wiring in Plugin, RestRegistrar, AdminMenu, ShortcodeRegistrar. Payment is the deferred seam (#7): enrolment lands active, payment_id null. JS left untested for parity with the repo's no-build vanilla-JS posture. Tests: tests/Unit/GroupClass/ (Enrollment, EnrollmentRepository). composer test (121), cs, and PHPStan level 6 all pass. Refs #4 Co-Authored-By: Claude Opus 4.8 <[email protected]> |
||
|
|
6d163e5d0e
|
Add lesson booking registration flow (offering, questions, policies)
CI / Coding Standards (pull_request) Successful in 1m51s
CI / PHPStan (pull_request) Successful in 2m17s
CI / Tests (PHP 8.1) (pull_request) Successful in 2m24s
CI / No Debug Code (pull_request) Successful in 2s
CI / Tests (PHP 8.2) (pull_request) Successful in 42s
CI / Tests (PHP 8.3) (pull_request) Successful in 47s
CI / Build Plugin Zip (pull_request) Has been skipped
Implements #3: students register for a private lesson by picking a slot, answering the offering's intake questions, and accepting booking-scoped policies. Payment is a clean seam for #7 (lessons land pending; payment_id null; instructor confirms via PATCH /bookings/{id}/status). - Schema: us_lessons += offering_id, recurrence, series_id, payment_id. - Lesson: new fields + recurrence constants. - BookingRepository::insertSeries() builds a weekly series sharing a series_id; AvailabilityRepository::findUnbookedInGroup() reserves a group. - RegistrationGate (src/Registration/): validate + record intake answers and booking-scoped policy acceptances. Reused by group enrolment (#4). - BookingEndpoint::book(): offering_id, recurrence, answers, accepted_policy_version_ids; single or weekly; records answers/acceptances (type lesson). - GET /policies?scope=booking filter. - Front-end booking.js: slot -> questions + policies -> submit. - Wiring: RegistrationGate built in Plugin, passed via RestRegistrar. - Test-only WP_Error stub in tests/bootstrap.php for gate testing. Refs #3 Co-Authored-By: Claude Opus 4.8 <[email protected]> |
||
|
|
19e663d6fa
|
Extend availability (durations, weekly recurrence, calendar); price offerings in dollars
CI / Coding Standards (pull_request) Successful in 50s
CI / PHPStan (pull_request) Successful in 1m2s
CI / Tests (PHP 8.1) (pull_request) Successful in 47s
CI / Tests (PHP 8.2) (pull_request) Successful in 48s
CI / Tests (PHP 8.3) (pull_request) Successful in 46s
CI / No Debug Code (pull_request) Successful in 2s
CI / Build Plugin Zip (pull_request) Has been skipped
Availability (#2): - us_availability gains offering_id, duration_minutes (default 60), and recurrence_group; AvailabilitySlot carries the new fields. - AvailabilityRepository::createWeeklySeries() generates N weekly rows sharing a recurrence_group; findAvailable() filters by offering and duration. Date math uses DateTimeImmutable::modify() (the no-debug CI regex `dd\(` matches `->add(`). - REST GET filters by offering_id/duration_minutes; POST accepts duration_minutes, offering_id, recurrence (single|weekly) + weeks. - Admin form adds duration, an offering picker, and one-off/weekly options (OfferingRepository wired into AvailabilityController). - booking.js renders an agenda calendar (slots grouped by day, with duration). The richer booking UX lands with the booking-flow work. Offering price in dollars: - Switch us_offerings.price_cents (INT) to price DECIMAL(10,2); Offering uses float $price. Admin form and REST take dollars. - Fix a pre-existing misalignment in the Offering insert/update $wpdb format arrays (billing_mode/capacity/is_active were mapped to the wrong specifiers, which would corrupt values) via a single COLUMN_FORMATS list. Also bump PHPStan to --memory-limit=1G in the lint script; 128M now crashes analysis as the codebase has grown. Refs #2 Co-Authored-By: Claude Opus 4.8 <[email protected]> |
||
|
|
0fbafc9d18
|
Initial plugin scaffold: lesson scheduling WordPress plugin
CI / Coding Standards (push) Failing after 2m31s
CI / PHPStan (push) Failing after 50s
CI / Tests (PHP 8.1) (push) Successful in 50s
CI / Tests (PHP 8.2) (push) Successful in 48s
CI / Tests (PHP 8.3) (push) Successful in 40s
CI / No Debug Code (push) Successful in 2s
- Custom DB tables for availability slots and lesson bookings - Instructor (wp-admin) and student (front-end) roles with custom capabilities - REST API under us-scheduler/v1 for availability CRUD and booking - [us_booking] and [us_student_login] shortcodes for student front end - PHPUnit + Brain\Monkey unit test suite (29 tests) - Gitea Actions CI: lint, PHPStan, tests on PHP 8.1/8.2/8.3, no-debug check - Feature docs under docs/features/ Co-Authored-By: Claude Sonnet 4.6 <[email protected]> |