Privacy Policy
Effective date: 2026-06-12 Last updated: 2026-06-12 Operator: Konjo (an individual project by Galen Jauss; no incorporated company yet) Contact: galen@getkonjo.com
This policy explains what Konjo (formerly "Mojo Martial Arts"; the "App," "Konjo," "we") collects, why, where it lives, who can see it, and how to delete it. The App is a Cuong Nhu martial arts training tool for iOS, Android, and the web, operated as a personal project; once it incorporates, this policy will be updated to reflect the new entity.
We wrote this policy ourselves rather than using a template generator so that every claim below maps to a real database column or code path. Table and column names refer to the App's Supabase Postgres schema and are accurate as of the effective date.
Table of Contents
- Summary
- Who this policy applies to
- What we collect
- How we use your information
- How content is shared inside the App
- Where your data is stored (subprocessors)
- Push notifications
- Diagnostics and telemetry
- Retention and deletion
- Your rights
- Children
- Security and breach notification
- No advertising, tracking, or sale of data
- International users and data residency
- Changes to this policy
- Contact
1. Summary
In plain English:
- We collect what we need to run the App: account info, the training content you create, a date of birth (for age gating), and a push token if you opt in to notifications.
- Your training videos and photos are stored on Supabase (images) and Mux (videos). Your content is shown to other users only according to the visibility settings you choose in the App.
- We do not run advertising. We do not use third-party analytics or tracking SDKs. We do use a third-party diagnostics vendor (Sentry) on production builds to capture errors and crashes, record a sampled session replay of in-app activity to help debug those crashes, and provide an in-app feedback widget; see Section 8.1. We do not sell or share your data for cross-context behavioral advertising.
- You can delete your account from inside the App at any time. Deletion cascades through your account row, posts, sessions, attendance, follows, notifications, coaching content, and other personal data within minutes. Storage objects (photos, video sources) are best-effort deleted within 30 days.
- Our data lives on US-based infrastructure (Supabase US region; Mux US delivery).
- Minimum age is 13. The App is not intended for children under 13.
2. Who this policy applies to
This policy covers anyone who creates an account in the App, receives a push notification from it, or contacts us at the email above. It does not cover websites, services, or in-person dojo programs operated by third parties (including the dojos listed inside the App); each dojo has its own information-handling practices outside Konjo.
3. What we collect
We collect three kinds of information: account data, content you create inside the App, and limited diagnostics. Each is detailed below with the underlying database column it maps to.
3.1 Account data (public.users)
When you sign up and use the App, the following fields are stored on your user row:
- Email address — used to sign you in and send transactional messages (password resets, security notices). Not used for marketing.
- Display name and avatar image — shown to other users on your profile, posts, comments, and coaching feedback.
- Bio (optional, free text).
- Date of birth (
date_of_birth) — captured at signup to enforce the 13+ age floor. Not visible to other users. - Belt rank (
belt_rank) — your verified Cuong Nhu rank (white through post-black). Drives curriculum visibility and coaching audience eligibility. Verified ranks can only be set by an instructor at your dojo through the in-app verification flow. - Claimed belt rank, claimed role, and claimed dojo (
claimed_belt_rank,claimed_role,claimed_dojo_id) — what you submit during verification. Visible to instructors at the dojo you claim while your request is pending. - Verification status (
verification_status) — one ofunverified,pending,verified, orrejected. - Dojo membership (
dojo_id) — the school you train at, after verification. - Age group — adult or kids (used to route curriculum content and to enforce age-appropriate audience defaults).
- Counts —
followers_countandfollowing_countfor your social graph. - Training visibility setting (
training_visibility) — controls who can see your logged training sessions:private(only you),instructors_same_dojo(you plus instructors at your dojo), orpublic(any signed-in user). - Notification preferences (
notification_preferences) — JSON object of toggles you set in Settings. - Push token (
push_token) — see Section 7. - Terms acceptance (
terms_accepted_at,terms_version) — timestamp and version of the Terms of Service / Privacy Policy you accepted at signup. Not visible to other users.
You can edit your name, bio, avatar, age group, training visibility, and notification preferences any time from your profile or Settings.
3.2 User-generated content
These items are created by using the App. You own them. They are stored against your user ID and removed when you delete your account.
- Posts, likes, comments, mentions (
public.posts,post_likes,post_comments,post_mentions,comment_mentions) — your captions, optional image or video, group scope, reactions, replies, and@-tags. - Training sessions and session media (
public.sessions,session_media) — entries you log on the Train tab (timestamp, dojo, duration, activity tags, note, optional class link, hashtags) plus any photos or videos attached. - Reflections (
sessions.reflection,sessions.reflected_at) — short journal entries on a logged session. - Coaching sessions, requests, and feedback (
public.coaching_sessions,coaching_requests,coaching_feedback) — videos or post references you submit, the audience and belt-gate parameters of each request, and the structured feedback (strength / focus / next step) you give or receive. - Attendance (
public.attendance) — records of class attendance, withsourceindicating whether an instructor checked you in (bulk_check_in), you logged it manually (manual), or the system inferred it from a class-linked session (session_auto). - Curriculum progress and philosophy review state (
public.curriculum_progress,philosophy_review_state) — your next-belt checklist and spaced-repetition flashcard data (ease factor, interval, due date, last grade). - Follows, notifications, group memberships (
public.follows,notifications,groups,group_members). - Verification and promotion requests (
public.dojo_verification_requests). - Dojo announcements you post (
public.dojo_announcements) — instructor-only.
3.3 Media (photos and videos)
- Photos are uploaded to Supabase Storage in the
post-mediabucket under a path scoped to your user ID. Three resized thumbnails (thumb_tiny_url,thumb_small_url,thumb_medium_url) are generated on-device before upload. Image URLs are public so the App can display them, but they are unguessable. - Videos are uploaded directly to Mux for transcoding and HLS delivery; we never serve raw video files from our own servers. Each video stores a
mux_asset_idandmux_playback_id; playback URLs look likehttps://stream.mux.com/<playback_id>.m3u8. During upload, video files are temporarily transcoded on your device (cache directorymojo-video-xfer/) and streamed to Mux via a background upload session; local cache is cleared on success.
3.4 Identifiers
Your Supabase user ID (a UUID) is your stable identifier inside the App. Push tokens are covered in Section 7. We do not use the iOS IDFA, the Android Advertising ID, or any other cross-app advertising identifier.
3.5 What we do not collect
We do not collect your precise location, contacts, calendars, or photo library indexes (we only see photos you explicitly pick during a post or session-logging flow). We do not embed third-party analytics or advertising SDKs, and we do not collect health, biometric, or financial data. We do embed a third-party diagnostics SDK (Sentry) that includes mobile session-replay; the replay records masked UI structure and interaction sequences, not the raw screen — see Section 8.1 for the full disclosure. The App currently supports only email + password authentication, so we do not request Sign in with Apple or Google; if that changes we will update this policy first.
3.6 Health-related content
The App includes journaling, reflection, and coaching features in which you may voluntarily describe injuries, body mechanics, or physical condition (for example, "tweaked my knee in sparring"). We do not require this content, do not analyze it for health inferences, and do not share it with anyone outside the audience you choose. Some state laws (including the Washington My Health My Data Act) treat self-reported health-related text as sensitive consumer health data; you can delete any session, reflection, post, or coaching feedback row from inside the App, and you can delete all of it at once via Settings → Account → Delete Account.
3.7 Additional stored fields
For completeness, we also store: multi-image attachments on a post (posts.extras_media); attendance-row provenance (attendance.source); class-cancellation audit (class_instances.cancelled_by, cancelled_at, cancellation_reason); device metadata in upload-error rows (platform name, OS version string, App build number — never device serial numbers, advertising IDs, or precise location); a service-only Mux webhook idempotency log (mux_webhook_events) that no client can read; and Supabase Auth's own audit fields (last sign-in time, last sign-in IP, account creation time, email confirmation time).
4. How we use your information
We use what we collect only to operate the App: to run your account; to show the right content (curriculum, philosophy flashcards, your dojo's class schedule and announcements); to render social features (posts, comments, likes, mentions, follows, and coaching feedback to the audience you choose); to deliver push notifications and the in-app inbox per your notification preferences; to support instructor workflows (verification requests, opted-in training session visibility, class attendance); and to capture structured error rows when a media upload fails so we can fix bugs (Section 8).
We do not use your information for advertising, profiling for third parties, or any purpose unrelated to operating the App.
4.1 Legal bases (EU / UK users)
If you are in the EU or UK, GDPR / UK GDPR requires us to identify a lawful basis for each processing activity. We rely on:
- Performance of a contract (Art. 6(1)(b)) — for creating and operating your account, storing the content you create, and providing the features you use.
- Legitimate interests (Art. 6(1)(f)) — for diagnosing media-upload failures, preventing abuse, and operating the App safely. You can object to legitimate-interests processing at any time by emailing us.
- Consent (Art. 6(1)(a)) — for push notifications, granted via the iOS / Android system prompt and revocable any time in device Settings.
- Compliance with legal obligations (Art. 6(1)(c)) — when responding to lawful requests from regulators or courts.
4.2 Automated decision-making
We do not subject you to automated decisions producing legal or similarly significant effects. Some features (for example, the coaching-feedback belt-rank gate) apply rules configured by users; these do not produce legal effects on you.
5. How content is shared inside the App
What other users can see depends on the surface. Defaults are conservative; you can tighten or widen them per surface, and every rule below is enforced server-side by row-level security, not just in the UI.
- Profile — your display name, avatar, bio, belt rank, dojo, and follower counts are visible to all signed-in users.
- Posts — posts in the All feed are visible to all signed-in users. Posts scoped to a group are visible only to members of that group; comment and like counts on group posts are also restricted to members.
- Training sessions — controlled by your
training_visibilitysetting (default:private). - Coaching feedback — the audience for each coaching request is set when you create the request. Feedback text is only visible to the requester and people in that audience.
- Attendance — visible to you and to instructors at the dojo where the class was held.
- Verification requests — visible to head instructors and admin staff at the dojo you claim, and to you. Other users do not see them.
- Mentions — when you
@-mention someone, they receive a notification regardless of feed scope; the underlying post or comment respects its own visibility rules. - Dojo announcements — visible to verified members of the dojo only.
5.1 Content involving minors
Some posts and training-session videos may show children training (Cuong Nhu schools run kids' classes in person). Posters are responsible for obtaining consent from a child's parent or guardian before posting any content depicting them. If you are a parent or guardian and want content depicting your child removed, email galen@getkonjo.com with a description of the post; we will remove it within 7 days, without requiring proof of relationship.
5.2 Feedback about you
If you receive coaching feedback you find embarrassing, mischaracterizing, or unwanted, email galen@getkonjo.com and we will remove the row. The author of a coaching-feedback row can also delete it themselves.
6. Where your data is stored (subprocessors)
Konjo runs on three operational vendors, all pinned to US infrastructure for the production deployment.
| Subprocessor | Role | Data exposed |
|---|---|---|
| Supabase | Postgres database, file storage (post-media bucket), auth |
Account data, user-generated content, photos, push tokens, notification preferences |
| Mux | Video transcoding and HLS delivery | Video files you upload, derived playback artifacts, playback metadata |
| Expo Push Notification Service and Apple Push Notification service (APNs) | Push notification delivery | Push token, notification payloads (sender display name + short message) |
| Apple TestFlight | Beta distribution (TestFlight phase only) | Tester email, device crash reports forwarded to App Store Connect |
| Sentry | Crash and error reporting, mobile session replay (sampled), in-app feedback widget, diagnostic logs | Stack traces, breadcrumbs (navigation events, network call URLs without bodies, taps), device metadata (platform, OS version, app version, build number), IP address and HTTP request headers (via sendDefaultPii: true), masked session-replay recordings (UI structure and interaction sequences; text, images, vector elements, and webviews are masked by default), feedback you voluntarily submit through the widget, console / Sentry.logger output, and your Supabase user ID attached to events |
Our subprocessors run on their own infrastructure providers (for example, Supabase runs on AWS; Mux uses Cloudflare and AWS for delivery). Each subprocessor's privacy policy describes its further sub-processing relationships.
We are an individual-operated project today and rely on each vendor's standard customer terms; if we incorporate or onboard enterprise customers, we will execute formal data processing agreements and update this section.
7. Push notifications
If you grant the App permission to send push notifications, we obtain an Expo push token from your device and store it on your user row (users.push_token). The token is used to deliver notifications when other users like, comment on, mention, follow, send coaching feedback, post a dojo announcement, or take a verification action that involves you. Each notification type can be turned off individually in Settings (turning everything off keeps your token on file but suppresses delivery). You can revoke push permission entirely in your device Settings, which invalidates the token at the OS level.
Push tokens are stored on your user row in our Supabase database and are accessible to operator-side service-role processes for the sole purpose of delivering notifications you have opted into. They are not shared with anyone outside Apple, Expo, and our delivery infrastructure.
8. Diagnostics and telemetry
When a media upload fails (image optimization, thumbnail generation, Supabase Storage upload, Mux upload, or post-row update), the App writes a structured error row to public.media_upload_errors containing the pipeline stage that failed, an error code and short message, retry attempt number, non-PII device information (platform, OS version, app version), and a timestamp. These rows are scoped to your user ID by row-level security so only you and our service-role processes can read them. They do not contain media bytes, captions, message contents, or any other user content.
8.1 Diagnostics via Sentry (crashes, errors, session replay, feedback, logs)
We use Sentry on production builds of the App to capture crashes and errors, record a sampled mobile session replay so we can reconstruct what led to a crash, accept in-app feedback you submit through a feedback widget, and capture diagnostic logs. Sentry is fully disabled in development builds; it only runs in TestFlight and App Store releases.
What Sentry receives:
- Crash and error events. The JavaScript stack trace and, for native crashes, the native stack trace, plus the message and (where available) source map context. Triggered automatically on any unhandled error.
- Breadcrumbs. A short trailing log of in-app activity that preceded the event: navigation events, network request URLs (without request or response bodies), and user-interface interactions (for example, a tap on a button by name). Breadcrumbs do not include the contents of posts, messages, coaching feedback, training reflections, or media.
- Device and network context. Platform (iOS or Android), OS version, app version, build number, locale, device model class, IP address, and HTTP request headers. We do not send device serial numbers, IDFA/Advertising ID, or precise location. The IP address and headers are collected because the SDK is configured with
sendDefaultPii: true, which Sentry recommends for full incident-debugging context. - Mobile session replay (provided by Sentry's
mobileReplayIntegration). 10% of normal app sessions and 100% of sessions in which an error occurs are recorded for later playback inside Sentry. The replay captures UI structure, layout, and your interaction sequence (taps, scrolls, screen transitions). Text content, images, vector elements (icons), and WebViews are masked by default by the SDK — they appear as solid blocks in the replay rather than their real values — so the replay does not expose the literal contents of your posts, captions, comments, coaching feedback, training reflections, or media. The replay does, however, reveal which screens you visited and in what order. - Feedback widget submissions. Sentry's feedback integration is enabled. If you choose to submit feedback through that widget (when it appears, for example after an error), the message you type, the email address you optionally provide, and a screenshot you optionally attach are sent to Sentry and tied to your user ID. The widget does not capture anything unless you explicitly submit it.
- Logs. Sentry's Logs feature is enabled (
enableLogs: true). Calls toSentry.logger.*and certain console output are forwarded to Sentry so diagnostic context follows a crash. We do not log post contents, message bodies, coaching feedback text, training reflections, passwords, or push tokens. - User identifier. Your Supabase user ID (the same UUID used elsewhere in the App) is attached to every Sentry event so we can correlate a report with the affected account and reach out if needed. We do not send your email, display name, avatar URL, push token, dojo, belt rank, date of birth, or content rows.
Where Sentry runs:
Sentry processes these events on its US infrastructure (region us.sentry.io) under the operator's mojo-p4 organization and react-native project. Only the operator (Galen Jauss) has access to events in the Sentry dashboard. Sentry retains event data per its own retention schedule (typically 30–90 days for errors and replays on its standard plans).
Your rights against the Sentry data set:
- You can request deletion of Sentry events associated with your user ID by emailing galen@getkonjo.com; we will run a Sentry-side deletion within 30 days.
- When you delete your account through the App, your Supabase user ID ceases to exist, so any Sentry events that referenced it are no longer joinable to an active account; the underlying event rows in Sentry then age out under its retention policy.
- You cannot turn off Sentry from inside the App today. If you would like Sentry to stop receiving events tied to your account, email galen@getkonjo.com and we will add your user ID to a server-side deny list that filters events before they ship.
If we change any of this — sample rates, new integrations, broader PII collection, additional log categories, or a different vendor — we will update this section and the App's App Privacy questionnaire on the App Store before shipping the change.
9. Retention and deletion
9.1 While your account is active
Your data persists as long as your account exists or until you delete the specific item. Posts you delete are removed within seconds, with notifications and counts cascading at the same time.
9.2 Account deletion
You can delete your account at any time inside the App: Settings → Account → Delete Account. The flow asks you to type your account email to confirm. Once you confirm, the App calls a server-side function (delete_my_account()) that deletes your row in auth.users. Postgres ON DELETE CASCADE constraints then propagate the deletion through public.users and every table that references it, including posts, post likes, post comments, mentions, training sessions, session media, attendance records, coaching sessions, coaching requests, coaching feedback you authored, follows in both directions, notifications, dojo verification and promotion requests, group memberships, philosophy review state, curriculum progress, dojo instructor memberships, and announcements you authored. Tables that reference you only by attribution (class_instances.cancelled_by, dojo_*_requests.resolved_by) keep the row and clear your name. After deletion you cannot recover the account.
9.3 Storage objects after account deletion
Photo files in Supabase Storage and video assets on Mux are best-effort deleted within 30 days of account deletion. Some objects can become orphaned if a deletion job retries past its window; orphaned objects are no longer referenced from any database row (so they cannot appear in the App), have unguessable URLs, are not indexed, and are removed on a routine cleanup pass. Email galen@getkonjo.com if you want a manual sweep.
9.4 Backups and logs
Supabase takes routine encrypted database backups; deleted content may persist in those backups until the backup rolls off under Supabase's standard retention policy for our plan tier (typically 7–30 days). Server logs (HTTP access logs, edge function logs) may include your user ID, IP address, User-Agent, and request paths for up to 30 days for debugging and abuse response. Neither is used for analytics or marketing.
9.5 Retention caps
- Server access logs: deleted within 30 days.
- Diagnostic upload-error rows (
media_upload_errors): deleted within 90 days. - Notifications: pruned after 1 year.
- Verification requests in
rejectedorcancelledstatus: retained for up to 1 year for fraud-prevention and audit, then deleted.
10. Your rights
Depending on where you live, you may have rights to access, correct, delete, or port your personal information and to object to or restrict certain processing. We honor these rights for all users regardless of location.
10.1 Categories of personal information (California)
Under the CCPA / CPRA, we collect the following statutory categories. We do not sell or share any of them for cross-context behavioral advertising.
| Category | Collected | Disclosed to service providers | Sold | Shared |
|---|---|---|---|---|
| Identifiers (email, user ID, IP, push token) | Yes | Supabase, Mux, Expo, Apple, Sentry (user ID + IP) | No | No |
| Customer records (name, avatar, bio) | Yes | Supabase | No | No |
| Internet/network activity (request logs, crash breadcrumbs, HTTP headers) | Yes | Supabase, Sentry | No | No |
| Geolocation (precise) | No | — | No | No |
| Audio, visual, biometric (photos, training video, masked session-replay recordings) | Yes | Supabase, Mux, Sentry (masked replay only) | No | No |
| Professional / employment information | No | — | No | No |
| Education information | No | — | No | No |
| Inferences | No | — | No | No |
| Sensitive PI (account credentials, content arguably revealing health) | Yes | Supabase | No | No |
10.2 Right to Know / Access
Email us; we will provide an export of your personal information within 45 days.
10.3 Right to Delete
Use Settings → Account → Delete Account, or email us to delete a specific item.
10.4 Right to Correct
Most fields are user-editable in the App; email us for the rest.
10.5 Right to Opt Out of Sale or Sharing
We do not sell or share. See Section 13.
10.6 Right to Limit Use of Sensitive Personal Information
We use Sensitive PI only for the purposes described in Section 4 and do not use it for inferring characteristics about you.
10.7 Right to Non-Discrimination
We will not deny service, charge a different price, or provide a different level of service because you exercised any of these rights.
10.8 State-specific rights
Residents of Virginia, Colorado, Connecticut, Utah, Texas, Oregon, Montana, Iowa, Tennessee, Indiana, Delaware, New Jersey, New Hampshire, Minnesota, Maryland, Rhode Island, and other states with comprehensive privacy laws have rights similar to those above (access, deletion, correction, portability, opt-out of targeted advertising / sale / profiling). The same email contact and the same Settings → Account → Delete Account flow apply. We will respond within the timeline required by your state's law (typically 30–45 days). Some state laws set the threshold for sensitive-data processing at 16 rather than 13; where applicable, we apply the stricter threshold.
11. Children
The App is not intended for and is not directed to children under 13. At signup we ask you to enter your date of birth; users under 13 cannot create an account, and the signup form refuses to submit if the date of birth resolves to an age below the minimum.
If we learn we have collected personal information from a child under 13 without verifiable parental consent, we will delete the account and all associated content within 30 days. Parents or guardians who believe their child has registered should email galen@getkonjo.com with the child's account email; we will respond within 7 days.
Cuong Nhu schools run kids' programs in person; younger students are tracked by their dojo and instructor outside the App.
12. Security and breach notification
Connections between the App and our backend use TLS 1.2 or higher. Database storage and file storage are encrypted at rest by our infrastructure providers. Database access is gated by Supabase row-level security on every user-facing table, and policy review is part of every migration. Server-side functions that touch sensitive columns run with SECURITY DEFINER, pinned search_path, and explicit grants — they are not exposed to anonymous callers. Privileged columns (role, belt_rank, email, Mux IDs) cannot be modified by ordinary users; database triggers raise a privilege error on unauthorized updates. Passwords are managed by Supabase Auth, which stores them as hashes; we never store or log plaintext passwords on our infrastructure.
No system is perfect. If you suspect your account is compromised, change your password and email galen@getkonjo.com.
12.1 If there is a data breach
If we discover unauthorized access to or disclosure of your personal information, we will notify affected users by email and (where required by law) the relevant regulator within the timelines required by applicable law: within 72 hours of awareness for EU/UK users under GDPR; within applicable state-law windows (typically 30–60 days) for US users.
13. No advertising, tracking, or sale of data
To be unambiguous: we do not run ads inside the App; we do not embed third-party advertising or analytics SDKs; we do not share your data with data brokers; we do not sell your data; we do not use your data to target you outside the App; and "tracking" as defined by Apple's App Tracking Transparency does not occur. We do embed a diagnostics SDK (Sentry) that includes mobile session replay; the replay records masked UI structure and your interaction sequence — not the literal screen content — and is used solely for debugging crashes and errors. Full details are in Section 8.1.
If we ever introduce advertising, analytics, or any third-party tracking SDK, we will (a) obtain in-app consent from existing users before data flows to the new vendor, (b) honor Global Privacy Control signals, and (c) update our App Privacy disclosure on the App Store.
13.1 Do Not Sell or Share My Personal Information
We do not sell or share your personal information for cross-context behavioral advertising as those terms are defined under the CCPA / CPRA. We honor Global Privacy Control (GPC) signals in browsers that send them.
14. International users and data residency
Production data is stored on Supabase's US infrastructure and delivered globally via Mux's content delivery network. If you use the App from outside the United States, you consent to your data being processed in the United States.
14.1 EU / UK representative
Konjo does not currently appoint an EU / UK representative under GDPR Article 27 / UK GDPR Article 27 because our processing of EU / UK personal data is occasional and does not involve large-scale processing of special-category data. We will appoint a representative if this changes.
14.2 International transfers
When we transfer EU / UK personal data to the United States, we rely on Standard Contractual Clauses (SCCs) approved by the European Commission and on the corresponding UK International Data Transfer Addendum. Our subprocessors (Supabase, Mux, Expo, Apple) provide SCCs in their data-processing addenda.
15. Changes to this policy
We may update this policy as the App evolves. When we make material changes (new categories of data, new subprocessors, new uses, changes to retention or deletion), we will update the "Effective date" and "Last updated" fields, show an in-app banner the next time you open the App, send a push notification (if you have notifications enabled), and email the address on your account. Non-material edits may be made without notice; the canonical version is always the one at this URL. Past versions of this policy are available on request.
16. Contact
For privacy questions, data requests, or anything else covered by this policy:
Email: galen@getkonjo.com Operator: Konjo (Galen Jauss, individual operator)
We typically respond within a few business days. If you need this policy in another format (large print, screen-reader friendly), email us and we will provide it.