b3ed3a67d5a153bd34e2db9f2ad8fed9bc4d4e2c
5
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
8c21a3fa9d
|
Let the studio book lessons and record intake collected elsewhere
CI / Tests (PHP 8.1) (pull_request) Successful in 6m39s
CI / Tests (PHP 8.2) (pull_request) Successful in 57s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m59s
CI / Tests (PHP 8.5) (pull_request) Successful in 3m31s
CI / No Debug Code (pull_request) Successful in 3s
CI / Coding Standards & Static Analysis (pull_request) Successful in 3m28s
CI / Build Plugin Zip (pull_request) Skipped
Two related gaps, closed together because the second is created by the first. A private lesson could only be booked by the student or their guardian, so a booking taken over the phone had no way in — where group classes have had "Add students directly" all along. "Book a lesson for a student" is now a panel on Scheduler and My Lessons: student, open time, lesson type, with weekly term reservations and a no-charge option for make-up lessons. The booking core is extracted to Booking\LessonBooker and shared with POST /bookings, so the two paths cannot drift on offering rules, slot claiming, or billing. That leaves a registration with no intake answers and no policy acceptances, because nobody was at a keyboard to give them — already true of every directly added group-class student. Ticking the boxes on a student's behalf would be an audit trail that says something untrue, so instead the answers are collected another way and recorded afterwards, from a lesson's or an enrolment's detail page. Every recording must say how it was collected, which is stamped on each row along with who typed it and shown in a new "How it was given" column: a policy ticked online and one transcribed from paper must never look alike. Only staff-made registrations qualify (us_lessons.booked_by, us_group_enrollments.enrolled_by) — one the student made already holds their own answers. Only what is still missing can be recorded, re-checked at write time, so a stale or double-posted form cannot duplicate or overwrite. No IP is stored for a transcription, and accepted_by stays the student while recorded_by names the staff member. Intake is now generic over Registration\IntakeSubject, which Lesson and Enrollment both implement; LessonDetail became Registration\IntakeAudit and is shared by both detail views rather than duplicated. Closes #182 Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01QfHt6CyJHz6KkA4RuaS7WK |
||
|
|
b772e1811e
|
Let parents register once and book for their children
A parent registers once and manages lessons for one or more children, who need no login of their own. A child is a real wp_users row with the student role but no usable login — so student_id keeps meaning "a WordPress user" on every table, and booking, credits, policies and enrolments work unchanged. A us_guardians link table maps guardian to child. The signup form gains a parent/guardian tick that reveals a block per child, with the account-signup questions asked per child rather than per guardian — they describe the student, not the account holder. Signup policies are recorded once per child with the guardian as the acceptor, which is the record that actually means something. A family that half-creates is rolled back entirely rather than leaving a guardian who cannot re-register. The booking and enrolment forms gain a "Who is this for?" picker listing children first, so the default selection is never the parent — booking for the wrong child is correctable, quietly billing a parent for their kid's lesson is not. POST /bookings and POST /enrollments take an optional student_id honoured only for that child's guardian; anything else is a 403. That check is the authorisation boundary of the feature. Payments and credits gain a payer: the charge names the child it was for and the guardian who owes it, so per-child reporting is unchanged while notices, receipts and the payment step reach the parent. Credit is held by the payer, so one child's cancellation can settle a sibling's charge, and the daily billing scan sends a guardian one notice covering every child. Closes #132 Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
c49171695a
|
Add policy, intake, and payment history to the admin student detail view
CI / Coding Standards (pull_request) Successful in 2m47s
CI / PHPStan (pull_request) Successful in 2m56s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m39s
CI / Build Plugin Zip (pull_request) Skipped
CI / Tests (PHP 8.2) (pull_request) Successful in 43s
CI / Tests (PHP 8.1) (pull_request) Successful in 44s
CI / No Debug Code (pull_request) Successful in 2s
The student-administration spec deferred three detail-view sections until Payments landed. Adds them now: policy-acceptance history (title, version, context, date), intake answers (label, answer, context), and — gated on manage_billing — payment history with HST breakdown and receipt numbers. New Auth\StudentHistory builds the display rows from per-student queries added to AcceptanceRepository, AnswerRepository, and PaymentRepository; the Payment model now carries created_at so unpaid rows still have a date. Closes #69 Co-Authored-By: Claude Fable 5 <[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]> |
||
|
|
6225e772f8
|
Add Policies domain (drafting, versioning, tracked acceptance)
CI / Coding Standards (pull_request) Successful in 1m0s
CI / PHPStan (pull_request) Successful in 1m4s
CI / Tests (PHP 8.1) (pull_request) Successful in 59s
CI / Tests (PHP 8.2) (pull_request) Successful in 56s
CI / Tests (PHP 8.3) (pull_request) Successful in 57s
CI / No Debug Code (pull_request) Successful in 3s
CI / Build Plugin Zip (pull_request) Has been skipped
Implements #6: studio admins draft, version, and publish policies; the public registration gate reads the current published version of each, and acceptance is recorded against the exact version so a new version must be re-accepted at the next booking. - src/Policy/: Policy, PolicyVersion, PolicyAcceptance value objects; PolicyRepository, PolicyVersionRepository, AcceptanceRepository; PolicyService (orchestrates create/add-draft/publish across the policies and versions tables); PolicyEndpoint (REST); PolicyController + templates/admin/policies.php (Policies admin menu, manage_policies) - us_policies, us_policy_versions, us_policy_acceptances tables in Schema - REST: public GET /policies (current published versions); manage_policies for create, add version, edit draft, and publish - Wiring in Plugin, RestRegistrar, AdminMenu AcceptanceRepository is built now and consumed by the booking/enrolment gate in #3/#4. Also bump PHPStan to --memory-limit=1G in the composer lint script; the default 128M now crashes the analysis as the codebase has grown. Tests: tests/Unit/Policy/ (value objects, repositories, service). composer test (90 total), cs, and PHPStan level 6 all pass. Refs #6 Co-Authored-By: Claude Opus 4.8 <[email protected]> |