Legal Documents (TOS, Privacy, Waivers)
Linear epic: Legal compliance (TOS/Privacy/Cookie/Waiver acceptance) Status: Legal requirements are always enforced. Israeli counsel review of the member documents is a launch prerequisite. Last reviewed: 2026-09-05
What
Platform-published legal documents (owner-only B2B Terms of Use, member terms, Privacy Policy, Cookie Policy, Acceptable Use, Fitness & Health Acknowledgement, and a separate external-payment responsibility acknowledgement) and the per-user consent ledger recording the exact version and locale accepted, time, IP, user-agent, and context. External-payment acknowledgement additionally binds acceptance to an organization.
Distinct from compliance forms (see ../forms/):
| Aspect | Legal documents | Compliance forms |
|---|---|---|
| Owner | Taikan platform | Each org / gym |
| Audience | Role-specific users | Org members |
| Storage | URL pointer + consent ledger | PDF in R2 + signature artefact |
| Locale | per-locale rows | per-template locale field |
| Output | A legal_consents audit row | A signed PDF + audit row |
| Israeli regulator surface | Privacy / consumer law | Sports Promotion Law |
Why
- Israeli Privacy Protection Law + GDPR-equivalent require recorded, version-tied consent.
- Reconsent when a required document changes; platform Terms are required of organization owners. Member terms are required only of members. Admins and coaches have no required platform document until staff-specific terms are introduced.
- Fitness & Health Acknowledgement complements the per-gym
health_declarationcompliance form. The existingfitness_waivertype and slug remain unchanged; the document preserves mandatory, non-waivable rights.
Personas
| Persona | Surface | Capabilities |
|---|---|---|
| Owner or member with required terms | sign-up, join, or reconsent flow | Read documents, accept the role-specific agreement; recorded with IP/UA/context |
| Returning user with outdated consent | Reconsent prompt at app entry | Accept the new version |
| Org owner during onboarding | Onboarding setup sheet | Accept platform Terms of Use |
| All users | Profile / settings | View consent status (per type), see version they accepted, dates |
Capabilities
- Document catalog (
legal_documents) — versioned by(type, version, locale)unique key.published_atorders versions. URL field points to the marketing-site canonical (https://usetaikan.com/{slug}). - Consent ledger (
legal_consents) — append-only per user × document, with organization scope for external-payment acknowledgement. Soft-revocable viarevoked_at(no UI today). Records exact localized document/version evidence,ip_address,user_agent,consent_context, andorganization_id. - Current-version resolver —
LegalService.getLatestDocuments(locale)returns one row per type, latestpublished_at(deterministic tiebreak on id). - Consent status —
GET /legal/consents/status?organizationId=…returns per-type version status plus serverisRequiredand resolvedorganizationId; the missing set is preciselyisRequired && requiresReconsent. - Gates —
UsersService.getLegalRequirementsreturns{ types, organizationId }for the selected organization role. Members require privacy + health acknowledgement + current member terms. Owners require only platform Terms of Use. Admins and coaches have no required platform terms until staff-specific documents are introduced. Existing members accept missing member documents through/accept-terms; already-current acceptance is preserved. External acknowledgement is required only for qualifying joining or pending-only member onboarding, never the active-member backstop. Organization selection matches web: valid explicit org, then membership role priority; stale/omitted selections fall back. - Server-enforced joining — Public resolve exposes a required-type array. Member onboarding presents privacy, Fitness & Health Acknowledgement, and member terms under one required legal checkbox; conditional external-payment responsibility remains a separate required acknowledgement. The server recomputes and enforces every required type before mutation. Analytics/session-replay consent is a distinct optional checkbox, unchecked by default, and never satisfies legal acceptance.
- Idempotent record —
recordConsentskips active evidence for the current version; external acknowledgement dedup also matches the organization. - Replay privacy — mobile PostHog is constructed only after analytics opt-in. The disclosure names analytics and session replay; replay masks all text inputs, images, and sandboxed views, while console-log and network-telemetry capture are disabled.
Capabilities (gaps)
| Gap | Tracking |
|---|---|
| Revoke consent UI (the column exists; no API surface) | not tracked |
| Cookie consent banner (cookie_policy type exists; banner not implemented) | not tracked |
| Region-aware document selection (always picks latest globally) | not tracked |
| Audit log integration once FIT-20 lands | FIT-20 |
| Staff-specific terms for admins and coaches | not tracked |
Related features
- Users / auth —
docs/features/users-auth/. Consent gating happens after Clerk sign-in. - Onboarding —
docs/features/onboarding/. The acceptance form is embedded in the setup sheet’s terms section. - Compliance forms —
../forms/. Different domain; do not confuse the two during QA. - Marketing site — hosts the canonical document URLs (
usetaikan.com/{slug}).
Source code anchor
- API:
apps/api/src/legal/legal.{service,controller,module}.ts+dto/record-consent.dto.ts - DB schema:
libs/db/src/lib/schema/legal.ts - Shared:
libs/shared/src/lib/schemas/legal.schema.ts - Web component:
apps/web/src/components/legal/legal-acceptance-form.tsx - Marketing fetch helper:
apps/web/src/app/api/legal-document/route.ts
See behavior.md for state and qa-plan.md for tests.