Privacy Policy
Last updated: 2026-08-29
Scope & contact
BJJ Training App (“we”, “us”) operates this website and app. This notice describes the processing we control. A linked provider may also process data under its own notice. Questions or privacy requests can be sent to support@bjjtraining.app.
This is a training journal, not a medical service. Injury and weight entries can still be sensitive and receive the same private-by-default access controls as other account data.
Data we process
- Account and identity: email, name, optional phone, avatar, belt, role, authentication/session records, locale, and preferences.
- Training: journal text, dates, techniques, partners, outcomes, goals, review history, belt history, timer presets, private lessons, coach feedback, and legacy Training Mode cards.
- Health-adjacent and competition: injury notes, weight and weight goals, perceived effort, readiness signals, competitions, matches, and target divisions.
- Travel: saved gyms, locations, planned training dates, and reminder preferences.
- Media: photos or other journal media you choose to upload to the private journal-media storage bucket.
- Video Library: public YouTube, Instagram, TikTok, or X links you save, plus your title, creator, position, technique, tags, rating, study status, favorite choice, and notes. When you add a public YouTube or TikTok link, the canonical link is sent to that provider's oEmbed service to request a title and creator suggestion. Your Library notes, categories, account id, and other private app data are not included in that request. Instagram and X links are not sent to their providers for metadata. After Play, an authenticated same-origin wrapper may fetch allowlisted official TikTok embed HTML; that HTML is not stored. The bulk-transfer tool parses a selected CSV or XLSX file in your browser; it does not upload or retain the raw file. Only structured candidate rows are sent after you prepare or confirm an import, and bulk import makes no provider metadata or media request. After you sign in, an approved TikTok short-share link may be sent to TikTok only to follow bounded redirect headers and identify its canonical public video URL; the app does not read the response page or send cookies or a referrer. If you use the installed app's Android or ChromeOS share action, the app briefly checks the shared URL, text, and title to find one supported public link; it discards the raw text and title, stages only the validated link in the add form, and never saves without your action.
- Video Discovery (release-gated): the implemented but currently unavailable Discovery feature can store one shared provider resource and, where approved, one deduplicated thumbnail for the same public video across multiple savers. It publishes only provider title/creator details and aggregate contributor counts after an eligible user chooses not to opt out; saver identities, notes, ratings, tags, journal/coaching context, and other private Library fields never enter Discovery. Existing Library items remain private until their owner completes a one-time review. Users can disable app, gym, or item contribution; gyms are off by default and may set a minimum contributor threshold. Required-reason reports, gym suppressions, site moderation, and permanent takedowns are audited. Provider players are click-to-load: no provider iframe is created until the user presses Play.
- Gyms and gym operations: gym membership, role, invitations, program enrollment, waiver status, occurrence attendance, gym-authored incident evidence, and per-Gym athlete-private scope grants and revocations.
- Integrations: calendar-feed token metadata; browser push endpoint, encryption keys, browser information, category preferences, and delivery state when Web Push is enabled; encrypted Gym Slack/Discord webhook URLs, selected events, redacted delivery status, and an athlete's separate belt-promotion sharing consent.
- Billing: Stripe customer/subscription identifiers, plan status, invoices and payment details held by Stripe. We do not store full card numbers.
- Support and security: support messages, email, optional name, IP address, user agent, referrer, rate-limit records, audit events, and server logs.
- AI operations: the selected training context or transcript sent for a requested feature, generated output/cache, provider/model, token counts, latency, cost, and redacted error metadata.
Purposes & legal bases
Where data-protection law requires a legal basis, we rely on:
- Contract: account, journal, goals, billing, export, and the features you request.
- Consent: public member directory publication, athlete-private per-Gym sharing scopes, future community activity sharing, browser push, weekly digest email, and athlete-controlled belt-promotion sharing to a Gym's Slack or Discord destination. Voice recording is disabled for this release. You can withdraw consent without affecting earlier processing.
- Legitimate interests: security, abuse prevention, support, service reliability, and aggregate privacy-focused performance measurement, balanced against user rights.
- Legal obligation: tax, accounting, fraud prevention, lawful requests, and records we must retain.
We do not sell your training, injury, weight, travel, or voice data.
Gym records & athlete-private sharing
- Gyms are private unless a manager explicitly publishes the gym page.
- Accepting an invite or membership never grants athlete-private data by itself.
- Gym-authored operational records stay separate from athlete-private data: membership identity and status, program enrollment, waiver status, occurrence attendance, and gym-authored incident evidence are role-authorized records for the Gym.
- If both the gym and member publish, the public gym page can show the member's name, avatar, and belt. The member can revoke directory publication in Settings; pages are rendered dynamically so revocation takes effect on the next request.
- Linked athlete contact details, belt, and rank, plus every private category, require an active accepted athlete-Gym relationship and the exact athlete-approved per-Gym scope. The scopes are
coach_feedback,training_summary,journal_entries,readiness,wearable_readiness,goals_focus_plans,competition,weight,injuries, andcontact_details. - Each private category starts off by default, is individually revocable, is audited, and takes effect on the next read. Leaving a Gym, deleting an account, or deactivating a Gym clears the active scopes for that relationship, and rejoining requires a fresh grant.
- For child profiles, the guardian relationship must be verified and accepted before separate child permissions can be granted. Staff cannot grant those child permissions from the admin flow.
- Public member directory publication and belt-promotion consent are separate choices from these private-data scopes. The member can revoke directory publication in Settings, and belt-promotion consent only controls that one outbound post type.
- A Gym owner or active manager can choose to post schedule changes or announcements to a validated Slack or Discord webhook. A belt promotion is never queued unless that athlete separately opted in for that Gym; disabling consent blocks later promotion posts.
- Community feed and leaderboard activity sharing are disabled for this release, even if a stored preference exists.
- Membership and scope evidence remain private records after publication is revoked; revocation stops future disclosure rather than deleting the membership.
AI & disabled voice transcription
Social Assist AI is disabled by default. If it is separately release-enabled, an authorized Gym manager must give fresh consent for every request, and any athlete-linked source also requires current athlete or guardian consent. The feature sends the bounded deterministic caption and public Gym context to one pinned provider and model, creates a separate AI sibling draft, and does not change the deterministic source draft. It does not fall back to another model or provider and never publishes automatically. Raw provider requests and responses are not retained; only the approved sibling draft and sanitized operational evidence remain. The deterministic drafting workflow remains independently available when Social Assist is disabled.
AI features run only when you request them. Selected journal text, reflections, goals, training statistics, or competition context may be sent to the configured provider. The launch runtime is configured to select Google Gemini; the OpenAI and Anthropic code paths must be separately configured and certified before they can receive launch requests. Do not include information about another person unless you have permission.
Voice transcription is disabled for this release. Recording controls are not shown, the browser Permissions Policy denies microphone access, and the voice endpoint rejects requests before it reads an upload or contacts a provider, so BJJ Training App does not collect or send voice audio. The voice panel in the public demo uses fixed synthetic text, never opens the microphone, and never saves a journal entry. Re-enabling recording requires a new release review and a point-of-action privacy notice.
If the OpenAI Responses path is configured in a future release, requests set store=false. Provider safety and abuse monitoring can still apply. The app keeps generated response caches for use for up to 24 hours and request metadata for operations; raw prompts and model output are excluded from routine application logs.
The Video Library transfer tool offers a model-agnostic prompt that you may copy to an external model to prepare a CSV or XLSX file. BJJ Training App does not send that document or prompt to an AI provider. Remove sensitive material first and review the privacy terms of the external service you choose.
Analytics & browser storage
Necessary cookies/local storage keep sessions, theme, locale, and short-lived app handoffs working. Vercel Web Analytics and Speed Insights collect route-level, device, geography, and performance measurements designed not to identify an individual; query strings and fragments are removed before Web Analytics events are sent. You can disable both for the current browser below or in Settings under Your data.
Sentry provides essential error reporting so we can detect and fix crashes in the browser and on our servers. It receives a minimized stack trace, route path, release identifier, runtime details, and a random request or event identifier. We configure the app and Sentry to remove account identity, IP addresses, cookies, authorization headers, form and request bodies, query strings, URL fragments, and stack variables. We do not enable Sentry Logs, Session Replay, profiling, user feedback, or release-health sessions. Essential error reporting remains active in Preview and Production when the app is available; it is separate from optional browser performance traces. Those browser traces use the analytics preference below, at a 10% Production sample, and stop when you opt out.
Permitir o Vercel Web Analytics e o Speed Insights neste navegador.
Lendo a preferência deste navegador…
Google Analytics and campaign/referrer attribution cookies are disabled for this release. Supplying a Google measurement ID does not activate tracking. Application-managed email delivery remains disabled even though digest preferences and an unsubscribe flow are implemented; the weekly worker is not scheduled.
Service providers
- Supabase: authentication, Postgres database, Storage, backups, and auth email delivery.
- Vercel: hosting, request/runtime logs, Web Analytics, and Speed Insights.
- Sentry: minimized application errors and optional browser/server performance traces for reliability and incident response. Sentry is configured not to store IP addresses or the identity, credentials, request bodies, query strings, and fragments listed above.
- Stripe: checkout, subscriptions, invoices, portal, fraud controls, and payment records.
- YouTube (Google): receives a canonical public YouTube link when an authenticated user requests add-form suggestions. If Video Discovery is separately release-enabled, YouTube metadata and an approved unaltered thumbnail may be refreshed within the documented retention window, and the privacy-enhanced player is created only after Play. We do not send private Library notes, categories, ratings, or saver identity.
- TikTok: approved short-share redirect resolution may identify a canonical public video. Official URL-based oEmbed may supply public title/creator details. After Play, an authenticated same-origin wrapper may render allowlisted official embed HTML and load embed.js only inside that sandbox. TikTok thumbnail storage remains disabled; no oEmbed HTML or provider script is persisted.
- Instagram: metadata and thumbnail collection remain disabled. If Video Discovery is separately release-enabled and the public creator permits embedding, an official Instagram embed is created only after Play; otherwise the app keeps the external-link fallback.
- Google Gemini: selected by the launch runtime for requested AI generation, subject to candidate model-availability and quality checks. OpenAI and Anthropic integration code is present but neither is configured to receive launch requests; voice transcription is disabled.
- Resend: present in code for application email, but application-managed delivery is disabled for this release.
- Your chosen calendar service: receives the planned sessions, competitions, private lessons, or Gym class schedule in a read-only feed only after someone adds its bearer URL to that service. Anyone with the URL can read that feed until it is rotated or revoked.
- Slack or Discord: receives only the event content a Gym owner or manager selected after configuring a validated webhook. Webhook URLs are encrypted at rest and are not shown again.
- Browser push services: when Web Push is release-enabled and you opt in, the browser's push provider receives an encrypted notification for your subscribed device. The code-owned release flag is currently off, so no customer push delivery occurs.
Class Booking remains disabled. Providers may process data in other countries under their contracts and transfer safeguards.
Retention
- Account, training, injury, weight, travel, gym, and media data: kept while the account is active or until a verified deletion request is completed, unless a legal/security exception applies. No inactivity auto-delete is currently applied.
- Deletion safety evidence: after completion, we retain a service-only SHA-256 fingerprint of the account ID to reject stale account recreation and authorize cleanup of late Stripe records. It is excluded from account exports and normal data APIs, but can be linked by someone who already knows the account ID. No fixed purge is currently enforced.
- Directory, athlete-private scope, and guardian consent evidence: kept with the membership or guardian relationship to prove the current choice. Revocation or relationship end stops future disclosure on the next read. When you leave a gym, delete your account, or the gym is deactivated, active scopes for that gym are cleared and a rejoin requires fresh regrant.
- Integration credentials and delivery state: personal calendar and push rows are deleted with the account; rotating or revoking a calendar feed invalidates its bearer URL. Shared gym webhook configuration remains with the gym when one manager leaves, while that manager's creator reference is cleared. Delivery queues are operational state, not portable account content.
- Video Discovery: personal settings, publication choices, gym choices, and reports are deleted with the account and active aggregate counts update immediately. A shared public resource or thumbnail may remain while another Library item/publication references it or while a report, suppression, moderation, takedown, legal, or security retention need applies. Exact unreferenced resources are removed through bounded cleanup; unrelated shared objects are not scanned or deleted. Global permanent suppression prevents republishing that provider identity.
- Support and audit records: kept while needed to resolve the request, secure the service, and meet legal obligations. No automatic fixed-period purge is currently claimed.
- Sentry error and performance records: kept only for the bounded retention period configured for the Sentry organization, then deleted by Sentry; intentional verification events are resolved promptly after release proof.
- AI: app response caches are used for 24 hours; operational metadata remains with the account. Google may retain safety-monitoring data for up to 55 days. If OpenAI or Anthropic is configured in a future reviewed release, its standard retention controls apply. Exceptions can apply for suspected abuse or law.
- Social Assist AI: actor references are removed when an account is deleted. The approved sibling draft follows the ordinary account and Gym content lifecycle, while sanitized operational evidence is retained with the Gym so budgets and provider use remain auditable. Gym-scoped evidence is retained with the Gym and removed when the Gym is deleted.
- Vercel: anonymous visitor hashes expire after 24 hours; aggregate reporting/log retention depends on the configured Vercel plan and operational policy.
- Stripe: Stripe and we may retain transaction and billing records for tax, accounting, fraud, dispute, and legal requirements after account closure.
- Backups: deleted data may remain inaccessible in provider backups until the provider’s backup cycle expires.
Your rights & choices
- Correct profile data in Profile and change preferences in Settings.
- Revoke each gym's athlete-private scope grants individually or all at once, revoke gym directory sharing and belt-promotion webhook consent separately, rotate or revoke calendar feeds, change in-app notification categories, and control anonymous analytics in the relevant Settings or gym surface.
- Browser push notifications are optional per-device opt-in from Settings and can be turned off per browser at any time. The weekly email digest remains disabled in this release, so there is nothing to unsubscribe from for email delivery yet.
- Download a versioned JSON account manifest covering every reviewed app data domain. Journal media is represented by stable object paths and an inventory; the JSON does not embed media binaries or expiring signed URLs. Contact support@bjjtraining.app if you also need help retrieving the binary files.
- Download the flat, editable records from your private Video Library as CSV or XLSX. These files can contain private notes and should be stored and shared carefully; study segments and linked technique graphs remain in the complete account JSON export.
- Request access, correction, restriction, objection, portability, or deletion by contacting support@bjjtraining.app. We may verify identity and normally respond within the period required by applicable law.
- Use self-service account deletion in Profile or contact support@bjjtraining.app. The workflow cancels linked Stripe billing and removes the app's Stripe customer before erasing live app data. Stripe can retain transaction records required for tax, disputes, fraud prevention, or law.
Self-service deletion uses a durable, retryable workflow: it first resolves gym ownership, then cancels billing, removes the account's journal-media prefix, anonymizes retained security evidence, deletes live database domains, and removes Supabase Auth last. If you are the only manager for a gym with other active members, transfer ownership or add another active manager before retrying. Provider legal records and expiring backups may outlive the live-account deletion window described above.
Children & security
The service is not directed to children under 13, and users who are not legally able to consent in their country should use it only with a parent or guardian. For email-less child profiles, the guardian relationship must be verified and accepted first, and then the child's separate permissions can be granted from the guardian's own account. We use TLS, access controls, row-level database policies, private Storage, rate limiting, and audit/security monitoring, but no system can guarantee absolute security.
For help, visit the Help Center or email support@bjjtraining.app. We may update this notice when processing changes and will update the date above.