c85dcfaaf1cc3abaca585d8b48700f00a9a9956d
7
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2c4b481077
|
Add group-class withdrawal deadline and kind-aware offering form
CI / Tests (PHP 8.1) (pull_request) Successful in 44s
CI / Tests (PHP 8.2) (pull_request) Successful in 59s
CI / No Debug Code (pull_request) Successful in 3s
CI / Coding Standards (pull_request) Successful in 2m53s
CI / PHPStan (pull_request) Successful in 2m55s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m41s
CI / Build Plugin Zip (pull_request) Skipped
Group classes now carry an optional per-class withdrawal deadline. Up to
that day a student may withdraw themselves from the class; the withdrawal
frees the seat and voids any pending payment but never issues an account
credit. After the deadline self-withdrawal closes and a studio admin must
withdraw the student by hand (the admin path is never subject to the
deadline). A blank deadline keeps self-withdrawal open indefinitely.
Also make the Add/Edit Offering form show only the fields relevant to the
selected kind: group settings for group classes, weekly reservation for
private lessons. Progressive enhancement — without JS every field renders.
- New nullable us_offerings.withdrawal_deadline column; Offering model gains
$withdrawalDeadline + isWithdrawalOpen().
- New student endpoint POST /enrollments/{id}/withdraw, gated by the deadline
(403 withdrawal_closed), ownership-checked, idempotent.
- Front-end group-class page shows a Withdraw button while open.
- No USC_VERSION bump: 1.2.0 is unreleased and accumulates schema changes
under its section, matching the scheduled-billing and credit features.
Tests: composer test (596), composer lint, composer cs all pass.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
|
||
|
|
a281935811
|
Add invite-only group classes
CI / Tests (PHP 8.2) (pull_request) Successful in 44s
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 2m49s
CI / Coding Standards (pull_request) Successful in 2m55s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m40s
CI / Build Plugin Zip (pull_request) Skipped
Group classes can now be marked invite-only (us_offerings.access_mode). Invite-only classes are hidden from the public catalog and reachable only when the instructor lets someone in via one of three paths, managed from My Lessons -> My Group Classes: - Add students directly: enrols them now with a pending payment. - Make available: grants registered students access to self-enrol through the normal paid flow (multi-select, emailed a notice). - Invite by email: tokenised registration invite tied to the class for a non-account address; after they register the class becomes enrollable. Reuses an existing pending invite instead of sending a second link. New us_group_access table records grants; GET /offerings merges granted invite-only classes for the caller; enrolment requires a grant (403 invite_required) and flips it to enrolled on success. composer test (487), composer lint, composer cs all pass. Co-Authored-By: Claude Opus 4.8 <[email protected]> |
||
|
|
8b90b8d78d
|
Add cancellation cutoff limiting how close to a lesson a student can cancel
CI / Tests (PHP 8.1) (pull_request) Successful in 41s
CI / Tests (PHP 8.2) (pull_request) Successful in 53s
CI / No Debug Code (pull_request) Successful in 2s
CI / PHPStan (pull_request) Successful in 2m51s
CI / Coding Standards (pull_request) Successful in 2m54s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m38s
CI / Build Plugin Zip (pull_request) Skipped
Students can no longer cancel their own lesson online once it starts within a configured window; instructors and studio admins can always cancel. - Studio default `us_cancellation_cutoff_hours` (stored/computed in hours, entered and displayed in days under Studio Settings → Cancellations). - Optional per-offering override `cancellation_cutoff_hours` (entered in hours); blank inherits the studio default, 0 allows anytime cancellation. - `Booking\CancellationPolicy` resolves the effective window and decides; `BookingEndpoint::cancel()` returns a 403 `cancellation_closed` when too late. The instructor status endpoint and studio-admin student actions bypass it. Closes #93 Co-Authored-By: Claude Opus 4.8 <[email protected]> |
||
|
|
1d6ac46ba3
|
Upgrade PHPStan to 2.x and raise analysis level from 6 to 10
CI / No Debug Code (pull_request) Successful in 3s
CI / Tests (PHP 8.2) (pull_request) Successful in 48s
CI / Tests (PHP 8.3) (pull_request) Successful in 52s
CI / Coding Standards (pull_request) Successful in 57s
CI / Tests (PHP 8.1) (pull_request) Successful in 1m1s
CI / PHPStan (pull_request) Successful in 1m11s
CI / Build Plugin Zip (pull_request) Has been skipped
- Bump phpstan/phpstan ^2.0 and szepeviktor/phpstan-wordpress ^2.0 - Move the analysis level into phpstan.neon (single source) and raise it to 10 - Add Val, a runtime coercion helper that narrows untyped WordPress boundary values (wpdb rows, REST params, superglobals, options) with explicit checks instead of blind casts, plus unit tests - Type value-object fromRow() params as stdClass (what wpdb returns) and map columns through Val so unexpected shapes degrade safely - Use %i identifier placeholders for table names in all wpdb::prepare() calls so every query string is a literal and identifiers are escaped by WordPress; raises the minimum WordPress version to 6.2 where %i was introduced - Guard wpdb::prepare() null result before wpdb::query() in updateTax() - Fix nullable get_permalink()/strtotime() handling, list types at REST and capability call sites, dead null-coalescing on checked superglobals, and narrow get_users() results before mapping - Register Val method names with the ValidatedSanitizedInput sniff so it validates the real sanitizer around each superglobal read - Update repository unit tests for the %i placeholder arguments Co-Authored-By: Claude Fable 5 <[email protected]> |
||
|
|
9873cb5e30
|
Add e-transfer destination email (studio default + offering/booking overrides)
CI / No Debug Code (pull_request) Successful in 3s
CI / Coding Standards (pull_request) Successful in 46s
CI / Tests (PHP 8.1) (pull_request) Successful in 52s
CI / Tests (PHP 8.3) (pull_request) Successful in 52s
CI / Tests (PHP 8.2) (pull_request) Successful in 57s
CI / PHPStan (pull_request) Successful in 1m12s
CI / Build Plugin Zip (pull_request) Has been skipped
The e-transfer destination is resolved at booking time (offering override -> studio default) and frozen onto the payment, so each record keeps where the student was directed. It can then be corrected per booking. - StudioSettings: us_etransfer_email option + a Default e-transfer email field on the Studio Settings page. - Offering: etransfer_email column/field (instructor override) across VO, repo, REST endpoint, admin controller, and form. - Payment: etransfer_email column on the payment (frozen record) + PaymentRepository::updateEtransferEmail; PaymentService freezes it from the offering override or studio default at creation; booking/enrolment pass the offering override. - My Lessons: instructors edit the e-transfer email per pending lesson payment (ownership-checked). - Payments queue: studio admin can correct the email at confirmation (for when a student sends it to the wrong place). - Docs updated. Tests: Payment/Offering rows + PaymentService freezing. composer test (148), cs, and PHPStan level 6 all pass. Refs #7 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]> |
||
|
|
36331388d1
|
Add Offerings domain and studio-admin capabilities
CI / Coding Standards (pull_request) Successful in 55s
CI / PHPStan (pull_request) Successful in 1m0s
CI / Tests (PHP 8.1) (pull_request) Successful in 50s
CI / Tests (PHP 8.2) (pull_request) Successful in 46s
CI / Tests (PHP 8.3) (pull_request) Successful in 50s
CI / No Debug Code (pull_request) Successful in 2s
Implements the offerings catalog (#1): private-lesson types and group classes carrying pricing, billing mode (one_time/full_term), duration, capacity, and term details. Adds the src/Offering/ domain (value object, repository, REST endpoint, admin controller + template), the us_offerings table, and an Offerings admin page. Also lands the capability slice of #9: registers the us_studio_admin role and the new capability strings (manage_instructors, manage_offerings, manage_questions, manage_policies, manage_billing, view_all_payments, view_own_payments, export_payments) so offering management gates correctly. Tests: tests/Unit/Offering/ (value object + repository) and a studio-admin case in RoleManagerTest. composer test, cs, and PHPStan level 6 all pass. Refs #1 #9 Co-Authored-By: Claude Opus 4.8 <[email protected]> |