Managed Members — QA Plan
Status: phase 1. Every scenario below has automated coverage (see code-map.md § Tests). The QA’d column records manual verification on the review stack (web + iOS simulator, flag on, Hebrew): ✓ verified, — not yet.
Setup: an org on Pro or above with managed-members on; a staff admin; one adult who trains; one email address with no account yet. Run the member side once on web and once on mobile, at least once in he.
1. Staff enrolment
| # | Scenario | Expected | QA’d |
|---|---|---|---|
| 1.1 | Members → Add child, invite a new email | Child created as a member; record shows the adult “waiting to confirm”; staff-enrolment email sent | ✓ |
| 1.2 | Adult’s record → Add child | Adult pre-filled; same result, pending | ✓ |
| 1.3 | Add child naming an address already held by a managed member, or by an adult in another org | Refused as “unavailable”, without saying why | — |
| 1.4 | Resend on a pending child | New email; link still pending | — |
| 1.5 | Add child with flag off, or on a lower tier | Entry points hidden; direct API call → 403 managed_members_disabled | — |
2. Confirmation
| # | Scenario | Expected | QA’d |
|---|---|---|---|
| 2.1 | New adult signs up from the email link | Lands on /family/accept/<grantId>, not owner onboarding | ✓ |
| 2.1a | Adult with no Taikan login opens the email on a signed-out browser | Clerk sign-up on the accept page (sign-up is invitation-only), then the confirmation form | — |
| 2.1b | Adult with an existing login opens the email signed out | Redirected to sign-in, then back to the accept page | — |
| 2.2 | Adult confirms (name prefilled from profile, attestation) | Link active; a non-training adult becomes guardian_only; child appears in the switcher | ✓ |
| 2.2a | Adult with no birth date on their profile confirms | The form asks for the birth date; it is saved to the profile and the link becomes active | — |
| 2.3 | Adult under 21 | Refused; a birth date typed on the form stays editable and is not saved | — |
| 2.4 | Before confirming, try to book or sign for the child | Refused; pending link grants nothing | — |
| 2.5 | Adult declines | Link closed; staff task raised | — |
3. View as child
| # | Scenario | Expected | QA’d |
|---|---|---|---|
| 3.1 | Training adult with one child | Switcher: “myself” + child; opens on self | ✓ |
| 3.2 | guardian_only adult | Opens on the first child; their own row reads “Get a plan for yourself” and opens the Shop on “Me” | — |
| 3.3 | Switch child | Home, Schedule, Program, child’s Profile re-scope; “Your account” stays the adult’s | ✓ |
| 3.4 | Two children, switch back and forth | No data from one shows under the other | ✓ |
| 3.5 | Try to log a result, comment or check in for a child (incl. deep link) | View-only; no write | — |
| 3.6 | Relaunch the app | Selection persists per org; cleared on sign-out | ✓ |
4. Booking for a child
| # | Scenario | Expected | QA’d |
|---|---|---|---|
| 4.1 | Adult books and cancels for a child | Child’s rules apply (plan, overlap, forms, debt); cancel attributed to the adult | ✓ |
| 4.2 | Staff book a child | Adult sees “Booked by {staff}“ | ✓ |
| 4.3 | Two siblings, one seat left | One seat; the adult chooses | — |
| 4.4 | Youth-consent template exists, unsigned | Child can’t book until the adult signs it | — |
5. Profile, forms, billing
| # | Scenario | Expected | QA’d |
|---|---|---|---|
| 5.1 | Adult edits the child’s phone, emergency contact, gender | Saved | ✓ |
| 5.2 | Adult tries to edit the child’s name or email | Read-only in the UI; API 403 staff_only_field | ✓ |
| 5.3 | Adult signs a waiver for the child | Signature recorded with signedInCapacity='guardian' and the adult’s typed name | — |
| 5.4 | Adult buys the child a plan with a real card | Adult charged; receipt to the adult; payer stays the adult | — |
| 5.5 | guardian_only adult buys their own plan | Stays guardian_only while the checkout is open or abandoned; becomes trains once the plan is live; the self row appears in the switcher | — |
6. Notifications
| # | Scenario | Expected | QA’d |
|---|---|---|---|
| 6.1 | Booking reminder for a child | Reaches every confirmed adult with notifications on; never the child | — |
| 6.2 | Push about a child, on a real device | Tapping opens the screen as that child | — |
| 6.3 | Promotional automation targeting a child | Skipped | — |
7. Staff surfaces
| # | Scenario | Expected | QA’d |
|---|---|---|---|
| 7.1 | Members → Responsible adults filter | Every adult with an active or pending link, training or not | ✓ |
| 7.2 | Household section on child and adult records | Links both ways; pending shown as pending | ✓ |
| 7.3 | Message {guardian} about {child} | Opens a conversation with the adult | — |
8. Sign-up block, suppression, flag, import
| # | Scenario | Expected | QA’d |
|---|---|---|---|
| 8.1 | Sign up with an address a child record holds (live Clerk webhook) | “Ask your gym to link your account”; no second account; audit row with ids only | — |
| 8.2 | Suppress an adult’s access (API) | Immediately 403 for that adult on the child; unsuppress restores | — |
| 8.3 | Turn the flag off after children exist | Children stay members; parents lose Family and the switcher; notifications still reach adults; children book without youth consent | — |
| 8.4 | CSV import with child rows | Children created with pending links; unresolvable rows queued (no_guardian, no_birth_date, guardian_ambiguous) | — |
| 8.5 | Existing adult members after the migration | Sign-in, booking, forms, payments unchanged | — |