Skip to main content

Privacy first

What we don’t do.
And what we do instead.

A team app sees your kid’s name, schedule, sometimes their photo. That earns a higher bar than “trust us, we try.” Below are eight specific things we don’t do — each one paired with what we built instead. Every claim here is backed by working code, not a values statement.

For the formal legal version, see the privacy policy. For the COPPA-specific story, see the COPPA & consent page.

01

Map previews use zero location services.

We don’t ask iOS for your location to render the map snapshot above an event's venue.

We do instead: render a static MapKit snapshot from the coords your coach already entered when they set up the venue. iOS never opens location services for the preview — there’s no NSLocationWhenInUseUsageDescription in the app’s Info.plist because the cell genuinely doesn’t need one.

02

Under-13 kid names never reach our support team.

We don’t let our cross-tenant support console show under-13 children by name — not in rosters, not in user detail, not in consent records, not in CSV exports.

We do instead: redact every under-13 entry to opaque Player #<id> labels and route support through the parent’s name + email regardless of the child’s age. Same redaction across the web admin, the consents export, and every internal API. The full child name is not even sent to the admin client.

03

Moderators physically can't see uploaded photos.

We don’t hand our triage team a single back door into kid headshots, team galleries, or sponsor banners.

We do instead: split the support tier — only a super-admin (a separate role with a separate server-side gate) can fetch a photo file. Moderators get the rest of the admin console for daily triage; the photo route 403s for them at the server, not just in the UI. Photo access takes a deliberate role escalation, audited.

04

Identity cards never expose phones or emails.

We don’t surface contact info in team chat or parent-friend chat identity cards.

We do instead: show role + relevant kids only— “Coach” or “Lily’s mom” tells you exactly who you’re talking to without leaking a way to reach them outside the app. Phone numbers aren’t even a field on user records.

05

No "log in as user X" feature.

We don’t give anyone — admin, moderator, engineer — a button to impersonate a user. It does not exist in the codebase.

We do instead: address every support question through documented, audited actions (resend verification, force-mark verified, clear push tokens, photo-report queue). Each logged with actor, target, timestamp, and reason. If we need to confirm what a user sees on their screen, they screen-share — we don't sign in as them.

06

Parent friends are adult-to-adult by design.

We don’t let a parent-friend connection grant any visibility into your kids, rosters, schedules, team chats, or message history.

We do instead: scope the connection to a 1:1 adult chat plus same-venue heads-ups that surface only friend name + venue + start time — never kid names, team names, or event titles. The privacy rule is enforced server-side at the query layer, not by a client-side checkbox.

07

No third-party trackers, analytics, or ad pixels.

We don’t embed Google Analytics, Mixpanel, Amplitude, Firebase, Sentry, ad-network tags, or any other “phone-home” SDK — anywhere on web or iOS.

We do instead: rely on first-party server logs we run ourselves. The only third-party in the iOS bundle is Stripe, scoped to fundraiser checkout. The Camera and Photo Library entries in Info.plist exist because Stripe’s SDK references them; we ourselves only ever write to Photos (saving a QR code) and never read the library.

08

Destructive admin actions need two keys.

We don’t let any admin unilaterally delete a user, escalate someone to admin, or fire a broadcast.

We do instead: require super-admin specifically (not moderator) for destructive or visible actions. Broadcasts are rate-limited to 1/hour with an explicit-override checkbox; every send is logged with who, when, audience, body, and device count. Role grants happen via single-use email invites — the recipient claims it themselves, no admin can mint a session for them.

How we keep it that way.

Every claim above is a server-side gate, not a UI rule. We re-check role at the action layer (not just the page layer) so a forged POST against a stale-rendered page can’t slip through. We audit destructive moves with actor + target + timestamp + reason. We default to in-memory caches over disk persistence wherever we can. And we keep an honest changelog — when a privacy stance shifts (it shouldn’t, but if it ever does) you’ll read it there in plain English first.

Questions? Email support@thefieldhouse.app and we’ll tell you exactly how anything on this page works, in as much code-level detail as you want.