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]>
This commit is contained in:
2026-07-29 16:07:52 -03:00
co-authored by Claude Opus 5
parent c25260a367
commit b772e1811e
71 changed files with 4192 additions and 191 deletions
+11 -1
View File
@@ -11,7 +11,17 @@ When a `v*` tag is pushed, `.gitea/workflows/release.yml` publishes the matching
the plugin to the next patch version and adds a fresh section here for it. Record
each change under the current top section as you work.
## [1.2.5]
## [1.3.0]
### Added
- **Parent and guardian accounts.** A parent registers once and manages lessons for one or more children, who need no login of their own. The signup form gains an **"I'm registering as a parent or guardian"** tick that reveals a block per child — name, date of birth, and the studio's account-signup questions asked **per child**, since those describe the student rather than the account holder. Signup policies are recorded once per child with the guardian named as the person who agreed, which is the record that actually means something: "this guardian accepted version N on behalf of this child, at this time, from this address." A guardian can also be a student themselves and book their own lessons from the same account.
- A **"Who is this for?"** picker on the booking and group-class forms, listing **children first** and the account holder last — so the default selection is never the parent, and a lesson meant for a child is not quietly booked and billed in the parent's name. An account with only itself on the list sees no picker and behaves exactly as before. A guardian's upcoming-lessons panel covers the whole household, each row naming whose lesson it is, and they can cancel or withdraw for any of their children.
- A **Family** page for guardians (`[us_family]`, or the **Family** block) to add, edit and remove children after signup. Removing a child is refused once they have lessons or enrolments on record — that history belongs to them, and the studio unpicks it by hand rather than the page orphaning it.
- **One family, one bill.** Payments record the child the lesson was for *and* the guardian who owes it, so per-child reporting is unchanged while notices, receipts and the payment step all go to the parent. Account credit is held by the payer, so a credit from one child's cancelled lesson can settle a sibling's next charge, and the billing-method override (comp / card / e-transfer) is one setting on the guardian rather than one per child. The daily billing scan sends a guardian **one** notice covering every child, with each line naming whose lesson it is.
- **Students** in wp-admin gains a **Family** column linking a child to their guardian and a guardian to their children, and the student screen gains a **Family** panel. A child's row shows the guardian's email — a child's own address is a placeholder that can never receive mail — and their credit balance is labelled with whose account actually holds it.
### Changed
- Child accounts **cannot be signed in to**. They hold the student role so every existing lookup keeps working, but authentication is refused outright and the booking capability is withheld, so the only route to a lesson in a child's name is their guardian's authorised booking.
## [1.2.4]