mobile

HiveJournal flavor — TestFlight → App Store runbook

Why this exists (2026-07-16): store presence is the credibility gate for competing in the journaling market. The comparison SEO cluster (/compare/journaling, /best-journaling-apps-2026) honestly lists "no native app in the stores" as our top gap, and any future paid acquisition test is blocked on it. This is the P0 product task "Mobile: ship HiveJournal flavor to TestFlight → App Store".

This is the HiveJournal-flavor sibling of WORKOUT_WINDOW_PHASE0_TESTFLIGHT.md — same EAS flow, default flavor, and it's easier: no identity overrides needed, app.json already carries the store-grade config.

What's already done (verified 2026-07-16)

  • Code: the full journaling loop is shipped on mobile (entries list/detail/ editor, notebooks, goals, sleep, search, share) — see MOBILE_WEB_GAP.md "What mobile already has".
  • Identity (app.json): name/slug hivejournal, com.hivejournal.app bundle id + Android package, icon/splash/adaptive-icon assets, camera + photo-library permission strings, applinks: associated domains + Android intent filters for hivejournal.com/share, EAS projectId + owner: jurowski, ITSAppUsesNonExemptEncryption: false (skips the export compliance prompt).
  • Flavor: APP_FLAVOR unset → HiveJournal is the default flavor (app.config.js only overrides for workoutwindow), so the plain production / preview EAS profiles build this app.
  • EAS profiles (eas.json): production (+ preview) now carry the real production env — prod Supabase URL + anon key (public-by-design; it ships inside the binary either way) and EXPO_PUBLIC_API_URL=https://hivejournalbackend-production.up.railway.app. appVersionSource: remote + autoIncrement handle build numbers.
  • Legal URLs: privacy + terms are live at hivejournal.com/privacy and /terms (needed for the store listing).

Status update — 2026-07-29 (post-hardening)

Nothing above regressed; the app got more store-ready since 2026-07-16.

  • Contributor hardening landed (Silver / silverz86), all directly de-risking Phase A dogfood + Phase C review: Turnstile bot-protection in auth (#1489), safe-area chrome + overlay placement + sleep/drop API (#1644), and auto-sign-out when the API rejects a stale token (#1655).
  • SDK is current — Expo ~54.0.30 / RN 0.81.5. Staleness is not a blocker.
  • Not real blockers (checked): the ~240 mobile tsc errors are almost all test-harness type-noise (Cannot find name 'jest'/'describe' — missing @types/jest in the typecheck config), not app regressions, and Metro/EAS builds don't run tsc; the 2 console.logs are in Workout Window screens (a separate flavor), not the HiveJournal app.
  • Still NOT shippedlib/journaling-compare.ts still reads native mobile app in development, which is the tell that Phase D was never done.

The real bottleneck is accounts/access, not engineering. The steps below gate on owner-held credentials (Apple Developer, EAS project membership, Play Console), not on code.

Split of work — who does what

Silver can do now (no accounts needed — the highest-leverage lane):

  1. Prep the full store-listing artifact set (the long pole that isn't accounts): screenshots (6.7"+5.5" iOS; phone+7"/10" Android), description leading with "free full journaling," keywords (journal, diary, mood tracker, AI journal), privacy/data-safety answers (cite the RLS/backend-only model). Capture from a dev build.
  2. Run the full physical-device dogfood gate (APP_STORE_DEPLOYMENT.md) on a dev/preview build, so a TestFlight build is known-good the moment it exists.
  3. Optional cleanups (not blockers): add @types/jest to green the mobile tsc; the 2 WW console.logs.

Needs the owner (Sandon) — the actual unblock, in order:

  • A. Apple Developer account active + register the app in App Store Connect under com.hivejournal.app (TestFlight internal needs registration, no review).
  • B. Add Silver to the EAS project (owner: jurowski) + the Apple Developer team so he can run eas build/eas submit — or run those two one-liners yourself (Phase A below).
  • C. Google Play Developer account ($25 one-time) + create the app in Play Console.

Single most important move: decide who holds/runs the store accounts (A+B). Everything engineering is done or Silver-doable; the app sits behind Apple Developer + EAS access.

Status update — 2026-07-30 (prep lane, issue #1684)

Silver's no-account lane items 1 and 3 are done or partly done; item 2 still needs a device. The listing copy, privacy answers and screenshot spec now live in store-listing/ — paste-ready, so submission is a transcription job rather than a writing job.

What the prep turned up that changes the plan above:

  • The required screenshot sizes in this doc are wrong. Apple no longer takes 6.7"+5.5" as the required set: it's 6.9" iPhone plus — because app.json sets ios.supportsTablet: true13" iPad, which nobody had on the list. Exact pixel sizes: store-listing/screenshots/README.md.
  • There is no /support route, and Support URL is a required App Store Connect field. Ship the page or pick a stopgap before Phase C.
  • No report/block anywhere in the product, while Drops and JQ Bridge show other users' content — Apple Guideline 1.2 and Play's UGC policy both require it. Most likely single cause of a first-submission rejection.
  • The "~240 tsc errors are all test-harness noise" line above was wrong. Fixing typeRoots so @types/jest resolves drops it to 54 — and those 54 are real, including three runtime defects. Settings → Export Data threw on expo-file-system@19 (fixed, #1706); DreamPro's AI breakdown and the action panel still import functions services/api doesn't export.
  • The app has no dark mode, so no listing copy may claim it. It at least no longer declares one: userInterfaceStyle is now "light" and expo-system-ui is installed so Android honors it (#1707). Light-only and consistent, rather than light screens under dark system chrome.

Item 2 (the physical-device dogfood gate) is written up as a runnable checklist at store-listing/dogfood-gate.md, with a "known suspects" section pointing at the defects above.

Status update — 2026-08-01 (review-blocker clearing)

Two of the flagged store-review blockers are now resolved in code:

  • Support URL — DONE. /support shipped (contact, guides, delete-account path, report path; footer-linked). Use https://hivejournal.com/support as the App Store Connect + Play "Support URL". (Was: "no /support route".)
  • Report + block for UGC — mostly DONE (Apple Guideline 1.2 / Play UGC). Migration 617 (content_reports + user_blocks); /api/moderation/* (report / block / unblock / my blocks + super-admin reports/resolve); the Encouragement-Drops feed now filters blocked senders server-side; super-admin review at /dashboard/admin/moderation; mobile ⋯ → Report / Block sender on the Drops-received screen (services/api.ts reportContent / blockUser). Apply migration 617.
    • JQ Bridge control — ADDED (MyConnectionsScreen.tsx): ⋯ → Report / Block on each connection (blocks the other user by profiles.id; a block hides their Drops via the existing enforcement). STILL TO DO before submit: an on-device pass of both flows (Drops + JQ Bridge) on a real build — the last verification, a good Silver/RN handoff. Optional follow-ups: the same control on InvitationsScreen, and server-side filtering of blocked users from the /jq-bridge/connections list (today the block removes them locally
      • hides their Drops; the connections list itself isn't yet block-filtered server-side).

The human steps (in order)

Phase A — TestFlight internal (no Apple review)

  1. Apple Developer account active; app registered in App Store Connect under com.hivejournal.app (name "HiveJournal"). Internal TestFlight requires registration but no review.
  2. Build + submit:
    cd apps/mobile
    npx eas build --platform ios --profile production
    npx eas submit --platform ios --latest
    
    (EAS handles signing; first run walks through credentials.)
  3. In App Store Connect → TestFlight → add yourself (+ testers) as internal testers; install via the TestFlight link.
  4. Dogfood the journaling loop against prod for a few days — auth, entry CRUD, notebooks, search, share links, a device set to dark, poor network. The APP_STORE_DEPLOYMENT.md checklist is the full pre-store gate; TestFlight-internal only needs it to work.

Phase B — Play internal testing (parallel, no review)

npx eas build --platform android --profile production

Upload the AAB to Play Console → internal testing track; installs via opt-in link.

Phase C — store review submission (after dogfood holds)

  1. Store listing — all of this is written and paste-ready in store-listing/; only the screenshot PNGs and the 1024×500 Play feature graphic still need producing. Note the required iOS sizes are 6.9" iPhone + 13" iPad, not the 6.7"+5.5" this doc used to say.
  2. Age rating questionnaire; content is user-generated → note the moderation/ report path.
  3. Submit for review on both stores.

Phase D — the payoff loop (don't skip)

  • Flip the comparison-cluster cells in apps/frontend/src/lib/journaling-compare.ts: the "Native iOS / Android apps" row (in developmentyes) and HIVEJOURNAL_SELF.honestGaps / platforms. Those pages advertise the gap by design — shipping is what un-advertises it.
  • Update the /features catalog + footer with store badges/links.
  • Mark the P0 task done; voice-entry capture (Tier 1) becomes the next journaling-market lever (paid on Rosebud, free here).

Gotchas

  • TestFlight needs a device build from the production profile — the preview iOS profile is simulator: true; don't use it for TestFlight.
  • Local .env never reaches EAS builds (gitignored) — env must come from the eas.json profiles (done) or EAS project env vars.
  • The WW flavor ships separately on its own timeline (WORKOUT_WINDOW_PHASE0_TESTFLIGHT.md); a new slug/bundle-id needs its own EAS project (eas init) — called out there.
HIVEJOURNAL TESTFLIGHT RUNBOOK — Docs | HiveJournal