Commit Graph
5 Commits
Author SHA1 Message Date
thatguygriffandClaude Opus 5 434fe801ba Ask some registration questions of students only
CI / Tests (PHP 8.2) (pull_request) Successful in 58s
CI / Tests (PHP 8.1) (pull_request) Successful in 58s
CI / No Debug Code (pull_request) Successful in 3s
CI / Coding Standards (pull_request) Successful in 2m53s
CI / PHPStan (pull_request) Successful in 3m0s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m42s
CI / Build Plugin Zip (pull_request) Skipped
Every account-signup question was asked of everybody who registered, on the
same terms: "school and grade" had to be put to an adult signing themselves
up, and a question a studio needed answered for each student could only be
made required by demanding it of everyone.

A question now carries an audience — everyone, or only the students someone
registers on behalf of — and its own required flag for each side, so optional
for you and required for every student you enrol is expressible. Both settings
are account-scope only: an offering asks its questions once, about the student
being booked, so there is no second audience to differ from, and an offering
question mirrors its single "required" into both columns.

Every caller reads askedOfSelf()/isRequiredForSelf()/isRequiredForChild()
rather than the raw flags, so a students-only question can neither block the
account holder nor have an answer filed against them by a crafted post. The
family screen, which only ever adds a student, is held to the students' rule.

is_required_child arrives from dbDelta defaulting to 0, which would quietly
stop every existing required question being required of the students a
guardian registers — the case it most likely existed for. A one-time backfill
copies is_required across, guarded by its own option so a question later made
optional for students stays that way.

Closes #163

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-07-30 13:51:52 -03:00
thatguygriffandClaude Opus 5 cb347ffca0 Demo follow-ups: editable policy name, one-page signup, group classes in upcoming lessons, deletion cleanup
CI / Tests (PHP 8.1) (pull_request) Successful in 1m0s
CI / Tests (PHP 8.2) (pull_request) Successful in 1m0s
CI / No Debug Code (pull_request) Successful in 3s
CI / Coding Standards (pull_request) Successful in 3m8s
CI / Build Plugin Zip (pull_request) Skipped
CI / PHPStan (pull_request) Successful in 2m49s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m44s
Five items from the latest demo pass:

- A policy's title can be edited from the Policies screen. Only the title
  moves; the slug is what the gates resolve policies by, so a rename can
  never detach a policy from acceptances already recorded against it.
- Signup is one page again. The studio's registration questions move from
  a second step behind "Next" onto the main form, in an "About you" panel
  above the students being added, and that panel also asks an adult
  student for their birth year (the same us_birth_year meta a child's
  uses). register.js disables and hides the whole panel for a pure
  guardian, since the questions describe a student.
- The password is re-scored on submit, not only as it is typed. zxcvbn's
  dictionary arrives after page load, so a password typed straight away
  was never scored at all and the first the student heard of it was the
  server rejecting the whole form.
- Group-class sessions appear alongside lessons wherever upcoming lessons
  are listed: the [us_scheduler] panel (students and instructors) and the
  admin student detail page. GroupClass\SessionSchedule derives them from
  Offering::sessionWindows(), the same derivation the billing scan uses.
  They carry kind = 'group_class' and no Cancel action - a session is one
  date in a term, not a booked slot.
- Deleting a user releases what the account was holding: each upcoming
  lesson is cancelled, its slot freed for rebooking, its pending payment
  voided, and active class enrolments cancelled. Past lessons and paid
  history are left alone.

Tests: composer test (851), composer lint, composer cs all pass.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-07-30 11:45:04 -03:00
thatguygriffandClaude Opus 4.8 721c4be1d6 Fix field-length saves, student wp-admin access, and empty instructor picker
CI / Tests (PHP 8.1) (pull_request) Successful in 49s
CI / Tests (PHP 8.2) (pull_request) Successful in 49s
CI / No Debug Code (pull_request) Successful in 2s
CI / Coding Standards (pull_request) Successful in 2m47s
CI / PHPStan (pull_request) Successful in 3m16s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m41s
CI / Build Plugin Zip (pull_request) Skipped
Three bug fixes for the 1.2.1 section:

- Fixed-size fields (question labels, offering titles/notes/e-transfer
  email, policy titles/slugs) no longer silently fail to save when the
  value exceeds its column length. The REST endpoints reject over-long
  values with a 400, the admin controllers refuse to insert them, and the
  form inputs carry a maxlength so the browser blocks over-long entry.
  Limits are MAX_* constants on the value objects, kept in lockstep with
  the schema columns.

- Students are kept out of wp-admin entirely. New StudentAdminGuard
  redirects front-end-only users (no back-office capability) away from the
  dashboard and hides the admin bar for them, while administrators, studio
  admins, and instructors keep full access.

- The Add/Edit Offering instructor picker now includes WordPress
  administrators when they act as instructors (the default single-account
  setup), so a solo studio owner is selectable instead of the dropdown
  being empty.

composer test (618), composer lint, composer cs all pass.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-24 20:22:04 -03:00
thatguygriffandClaude Opus 4.8 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]>
2026-07-23 09:59:59 -03:00
thatguygriffandClaude Opus 4.8 e61d99daed Add Registration Questions domain (per-offering intake forms)
CI / Coding Standards (pull_request) Successful in 51s
CI / PHPStan (pull_request) Successful in 1m0s
CI / Tests (PHP 8.1) (pull_request) Successful in 46s
CI / Tests (PHP 8.2) (pull_request) Successful in 48s
CI / Tests (PHP 8.3) (pull_request) Successful in 47s
CI / No Debug Code (pull_request) Successful in 3s
Implements #5: studio admin / instructors author intake questions scoped
per offering; answers are stored against a lesson or group enrolment via a
polymorphic registration reference.

- src/Registration/: Question + Answer value objects, QuestionRepository
  and AnswerRepository, QuestionEndpoint (REST), QuestionController +
  templates/admin/questions.php (Offerings -> Questions submenu)
- us_questions and us_question_answers tables in Schema.php
- REST: public GET /offerings/{id}/questions; POST/PATCH/DELETE /questions
  gated by manage_questions + offering ownership (owner or studio admin)
- Field types text/textarea/select/checkbox; select options stored as JSON
- Wiring in Plugin, RestRegistrar, AdminMenu

AnswerRepository is built now and consumed by the booking/enrolment flow
in #3/#4.

Tests: tests/Unit/Registration/ (19 tests). composer test (63 total), cs,
and PHPStan level 6 all pass.

Refs #5

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-05 11:11:06 -03:00