Table of Contents
03 — Coach invitations and family linking
Technical reference. For task-based help, see the corresponding user guide.
Documentation status: complete for the current implementation
Reviewed: 2026-07-21
Primary users: coaches and invited family members
Surfaces: mobile web app, coach admin portal and platform API
Purpose
This feature establishes an explicit, consented support relationship between one family and one coach. Coaches can create a one-use email invitation or share code, optionally snapshot a questionnaire and expiry date, and monitor its status. Families can preview the named coach and practice before authentication, accept or decline a pending invitation, or redeem a code.
Acceptance creates the trusted assignment and coach-sponsored premium access. It does not merely set a client-side flag.
User outcomes
| User | Outcome |
|---|---|
| Coach | Invite a family by email or share code and see whether it is pending, accepted, declined, expired or revoked. |
| New family | Preview coach/practice identity, register or sign in, consent and continue the same invitation. |
| Existing family | Accept/decline a pending email invitation or enter a coach code from the access screen. |
| Connected family | See the current practice/coach access and disconnect it deliberately when support ends. |
Entry points
| Surface | Entry point | Function |
|---|---|---|
| Public mobile | /invite?code=… | Preview a share code before sign-in and preserve the route through login/registration. |
| Family mobile | /family/access | Pending invitations, code entry, connection status and family-initiated disconnect. |
| Family home | Pending invitation card | Consent, accept or decline without leaving Home. |
| Coach portal | /families → Invitations | Create and manage invitations; legacy /family-invitations links redirect here. |
Coach workflow
Create an invitation
The coach chooses one method:
- Email: a valid family email is required and normalized to lowercase.
- Share code: the coach may supply a code, which the UI uppercases, or leave it blank for generation.
The coach can also set an optional expiry date and questionnaire behavior:
- select an active named template;
- use the current default when no explicit selection is available; or
- choose Send later / no questionnaire yet.
For a one-use invitation, the chosen template identity, name, title and questions are snapshotted with the invitation. Later template edits or default changes cannot alter what that family receives. Acceptance creates that questionnaire once; retries do not create duplicates.
Monitor and revoke
- Summary controls show Pending, Accepted, Expiring and Codes counts.
- Search matches email, code, family and invitation ID.
- Status filters include all, pending, accepted, declined, revoked, expired, expiring soon and share codes.
- “Expiring soon” means a pending invitation with an expiry in the next seven days.
- A pending invitation can be revoked. Accepted, declined, revoked and expired records remain historical and are not presented as reusable pending invitations.
Coach invitation creation is subscription-gated. A coach without eligible billing is directed to start or resume the coach subscription before creating invitations or managing linked families.
Family workflow
1. Preview
The public preview endpoint normalizes and validates the code and returns only the information needed for informed consent:
- coach name;
- practice/organization name and public branding;
- whether the coach can view logs;
- whether the coach can edit logs;
- invitation expiry, when present; and
- confirmation that consent is required.
Preview does not link the family and does not reveal another family's data.
2. Authenticate without losing the invitation
If no session is present, the screen offers Login and Create family account with the full internal invite route in the safe next parameter. After authentication the family returns to the preview. A non-family actor is denied rather than being linked accidentally.
3. Explicit consent and acceptance
The consent checkbox must be selected before Redeem invite, Confirm and redeem or Accept becomes available. The request carries literal consentToCoachAccess: true; omitting it is invalid.
The platform then atomically creates or updates the assignment, coach-sponsored entitlement, redemption/invitation state, audit event and any invitation questionnaire snapshot. A welcome modal shows the connected coach/practice after success.
4. Active store-subscription conflict
When a family already has an active direct App Store or Google Play subscription, acceptance pauses for an explicit warning. The family can:
- open the relevant store-management page first;
- cancel and keep the invitation pending; or
- acknowledge the active subscription and continue.
The second acceptance includes acknowledgeActiveStoreSubscription: true. The platform rechecks the conflict; acknowledgement is recorded for audit/analytics. A coach relationship does not silently cancel a store subscription.
5. Decline or disconnect
- Declining changes only the pending invitation; it does not create an assignment or entitlement.
- A connected family can use Disconnect coach. Confirmation immediately revokes coach access and removes the named relationship from normal coach tools.
- Reconnecting a revoked family requires a new invitation or code and fresh family acceptance; a revoked assignment is never silently restored.
- After disconnect/revocation, ordinary organizations give the family a seven-day premium grace period. The family keeps its account and logs and can continue tracking throughout.
Core state model
| State | Family-visible meaning | Coach action |
|---|---|---|
pending | Can consent and accept or decline, unless expired/revoked. | May revoke. |
accepted | Relationship and access were created. | Manage support through the family lifecycle tools. |
declined | Family chose not to connect. | Create a new invitation if invited again. |
revoked | Coach withdrew the unused invitation. | Cannot reuse; create another. |
expired | The expiry passed before acceptance. | Create a new invitation with a valid period. |
Only one active coach assignment is allowed for a family. Attempts to create a conflicting active relationship are rejected by the platform rather than replacing the current coach in the client.
Validation and user-visible states
| State | Expected behavior |
|---|---|
| Blank/invalid code | Do not redeem; show the invite-specific invalid/expired/revoked error state. |
| Preview loading | Show focused loading and keep redeem disabled. |
| Signed-out preview | Show public identity information, then require family login/registration. |
| Consent absent | Keep acceptance disabled. |
| Expired or revoked invitation | Explain that it can no longer be accepted; do not create access. |
| Coach billing inactive | Block new invitation use/creation with a billing-directed message. |
| Existing coach conflict | Keep the current relationship and report the platform conflict. |
| Active store subscription | Show the management/acknowledgement dialog before retrying. |
| Acceptance succeeds | Refresh the family summary and branding, remove the pending card and show welcome/success. |
| Network failure | Leave the code/invitation available for retry without duplicating the relationship. |
Platform API contract
| Method and path | Role | Authentication |
|---|---|---|
GET /invites/preview?code=… | Return normalized public coach/practice consent information. | Public, schema validated |
POST /invites/redeem | Redeem a reusable/share code with consent and optional store acknowledgement. | Signed-in family |
GET /families/me/invitations | List invitations currently addressed to the signed-in family. | Signed-in family |
POST /families/me/invitations/:id/accept | Accept a one-use invitation with consent. | Addressed signed-in family |
POST /families/me/invitations/:id/decline | Decline a pending invitation. | Addressed signed-in family |
PATCH /families/me/coach-access/revoke | Disconnect the family's current coach. | Signed-in family self-mode |
GET /coach/family-invitations | List the coach's scoped invitation records. | Signed-in coach |
POST /coach/family-invitations | Create an email invitation or share code. | Eligible signed-in coach |
PATCH /coach/family-invitations/:id/revoke | Revoke the coach's pending invitation. | Owning signed-in coach |
Authorization and privacy rules
- Preview is intentionally public but contains no family identity, logs or tenant-private data.
- Redemption and acceptance require a family role and explicit consent on the server.
- A coach can list/revoke only invitations scoped to their authorized practice membership.
- Assignment and entitlement creation is transaction-backed; client navigation cannot create coach access.
- Expiry blocks new redemption and constrains coach-sponsored access derived from the invitation.
- Coach access to logs remains subject to assignment, support and per-operation permissions after acceptance.
- Family-authored data remains owned by the family after decline, expiry, disconnect or revocation.
Acceptance checklist
- A coach can create an email invitation and a generated/custom share code with an optional expiry.
- The selected questionnaire snapshot remains stable if the source template later changes.
- A signed-out family can preview identity, authenticate and return to the same invitation.
- No invitation can be accepted before the family consents.
- Pending email invitations can be accepted or declined from Home and the access screen.
- Active store billing triggers an explicit warning and acknowledgement, never silent cancellation.
- A second active coach is rejected and a revoked relationship requires a new invitation.
- Family disconnect removes coach access immediately while preserving the family account/logs and grace period.
Source evidence
Mobile web
mobile-web/src/routes/InviteScreen.tsxmobile-web/src/routes/FamilyAccessScreen.tsxmobile-web/src/routes/FamilyDashboard.tsxmobile-web/src/components/CoachAccessConsentCheckbox.tsxmobile-web/src/components/CoachInviteStoreSubscriptionConflictDialog.tsx
Coach portal
admin-web/src/routes/FamilyInvitationsPanel.tsxadmin-web/src/routes/FamilyInvitationsModal.tsx
Platform and contracts
platform/apps/api/src/routes/invite-routes.tsplatform/apps/api/src/routes/family-routes.tsplatform/apps/api/src/routes/coach-routes.tsplatform/packages/shared/src/invites.tsplatform/packages/shared/src/family-invitations.tsplatform/docs/multi-tenancy/05-development-plan.md
