rebreak-monorepo/ops/RELEASE_READINESS.md
chahinebrini e76be7ee78 feat(profile): Profile-Page komplett + Header-Dropdown + UI-Pattern-Fixes
Profile (3 Iterationen):
- app/profile/index.tsx + components/profile/* (Header, StatsBar, Approved,
  Streak, UrgeStats, Demographics, DigaMissionBanner)
- echte Live-Daten via useMe-Hook (Avatar/Nickname/Plan/Email/Provider-Pill)
- Demographics mit echten Inputs (TextInput + Bottom-Sheet-Selects),
  debounced auto-save, Pro-Trial-Reward-Banner, Mikro-Why-Texte
- Approved Domains als plain integer (KEIN Plan-Slot/Cap)
- Friendly Hint-Text statt Progress-Bar (alignSelf:'stretch' Pattern)
- StatsBar zentriert mit 3 prominenten Cards (vertikale Dividers)
- Cooldown-Timeline als Liste mit 1px-Rail
- ApprovedDomainsList: Collapse-Chevron rechts in Title-Row (Pattern-Fix)
- Eigene vs fremde Profile-Ansicht streng getrennt (DSGVO/Anonymität)

Header-Dropdown (kein 3-Punkte-Icon):
- Avatar als Trigger im AppHeader (User-Wunsch)
- Custom-Modal beide Plattformen, Card-Style
- SOS prominent oben (nur Wort 'SOS' rot, Tagline 'wir sind für dich da' klein darunter)
- Profile/Settings/Games/Debug(__DEV__)/Logout
- Logout neutral (nicht rot — Recovery-tonal)
- AppHeader: neue showBack + title Props für Sub-Routes

Routes (Stub bis Phase C):
- app/profile/[userId].tsx — anonym (nur public-Stats)
- app/settings.tsx — Coming-Soon-Skeleton
- app/games.tsx — Standalone Games-Page mit GameCard-Grid
- app/debug.tsx — __DEV__-only

Game-Picker (Migration aus Nuxt):
- components/games/{GameCard, StarRating, GameRatingStars}
- 2x2 Grid, 56pt SVG-Icons (inline aus components/urge/gameSvgs.ts)
- Live-Backend /api/games/ratings (silent-fail)
- Re-use UrgeGames.tsx ohne TTS/Cooldown-Loop

UI-Pattern-Fixes (alle aus screenshot-User-Feedback 2026-05-07):
- Snake-Bug (food-pellet React-18-StrictMode-Reducer-double-call) gefixt
- Snake-Buttons platform-native (iOS-blue / Android-ripple)
- Tetris-Margins (16px paddingHorizontal)
- PostCard-Buttons Apple-44pt-Hit-Area (Image-Select, Image-Remove,
  Cancel, Share-Pill — via hitSlop)
- ProfileHeader Demographics-Hint: alignSelf:'stretch' Pattern
- ApprovedDomainsList Collapse: Title flex:1 + Chevron rechts
- ProtectionDetailsSheet FAQ-Items: alignSelf:'stretch' defensive
- AppHeader Back-Button: neue showBack-Prop + chevron-back

Memory + Plan-Docs:
- 17 Memory-Files dokumentieren System-Wissen + Patterns
- ops/{CUTOVER, UI_MIGRATION, PROFILE_PAGE, WEBHOOK, GAMES_1V1,
  RELEASE_READINESS, TESTING_STATE, MAESTRO_HOSTING}_*.md

Backend bleibt unverändert (Tier-LLM + Nickname + sort:latency
sind seit gestern deployed).
2026-05-07 18:22:58 +02:00

16 KiB
Raw Blame History

RELEASE_READINESS — TestFlight Internal + Play Internal Testing

Owner: zied (Release-/Rollout-Engineer) Stand: 2026-05-07 (Donnerstag) Deadline: Wochenende 2026-05-09/10 — iOS auf TestFlight Internal, Android auf Play Console Internal Testing Stack: Expo SDK 53 + React Native 0.79.6 (NICHT Capacitor — alte zied.md ist veraltet) Repo-Pfad: /Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/

Ziel "Internal Only": kein Apple-Review, kein Google-Review nötig. Apple TestFlight Internal Tester (≤100, App-Store-Connect-User) sind direkt installierbar. Play Console Internal Testing Track lässt bis zu 100 Tester per Email-Liste sofort builden.


Status-Quo-Tabelle

Legende: ready / 🟡 vorhanden aber Anpassung nötig / 🔴 fehlt blockierend / User-Bestätigung nötig

iOS

Item Status Detail
Bundle-ID org.rebreak.app (app.config.ts:22 + Info.plist)
App Store Connect entry Existiert? Apple-Login nötig — User-Bestätigung
Apple Developer Account aktiv TestFlight setzt aktiven $99/Jahr-Account voraus
Provisioning Profile + Cert EAS managed credentials kann das, aber Account muss connected sein
eas.json 🔴 fehlt komplett — muss generiert werden für eas build
iOS Native-Folder (ios/) Existiert via expo prebuild, Workspace + Pods sind drin
Info.plist Versions 🟡 CFBundleShortVersionString=0.1.0, CFBundleVersion=1 — für TF muss CFBundleVersion bei jedem Re-Upload steigen
PrivacyInfo.xcprivacy vorhanden (Pflicht seit April 2024); declared APIs FileTimestamp/UserDefaults/DiskSpace/SystemBootTime + NSPrivacyTracking=false
Entitlements 🟡 aps-environment=development — für TestFlight production-Build muss auf production (oder via EAS-Profile gesetzt). Family-Controls + Network-Extension + App-Group sind drin
Apple Sign-In 🟡 Code-Stub in stores/auth.ts:82-87 mit TODO. UI zeigt "via Apple Sign-In"-Pill (components/profile/ProfileHeader.tsx:55). Capability fehlt im entitlements file. Apple-Review-Risk: Apple verlangt Sign-In-with-Apple wenn andere 3rd-Party-Logins (Google) vorhanden. Für TestFlight Internal nicht zwingend, aber für External + Production blocker
App-Icon (1024×1024) ios/Rebreak/Images.xcassets/AppIcon.appiconset/App-Icon-1024x1024@1x.png + Contents.json
Splash SplashScreen.storyboard + Image-Assets im Xcasset
Stripe-IAP-Konflikt 🟡 Code prüft Pro/Legend (stores/auth.ts, app/(app)/blocker.tsx:268). UI hat KEINEN Upgrade-Button in App — alle Upgrade-Pfade sind Alert.alert(...) ohne Stripe-Link → für TestFlight Internal OK, aber bei External/Prod muss klar dokumentiert werden: Subscription nur via rebreak.org/web (nicht in App). Apple-Reviewer-Notes nötig

Android

Item Status Detail
Package-ID org.rebreak.app (app.config.ts:38 + AndroidManifest.xml + build.gradle:90/92)
Google Play Developer Account Validiert 2026-05-05 (siehe trucko-memory project_google_dev_account.md)
Play Console App-Entry User-Bestätigung: existiert "ReBreak"-App im Play Console schon mit Internal-Track?
Android Native-Folder (android/) Existiert, gradle-Setup ok
Keystore (Production) 🔴 android/app/build.gradle:113 signed Release-Build mit debug.keystore — Play Store akzeptiert das nicht. Production-Keystore muss erzeugt werden. Alternativ (empfohlen): EAS managed Android Credentials → EAS hält Keystore, kein User-Custody-Risk
versionCode/versionName 🟡 versionCode=1, versionName="0.1.0" — versionCode muss bei jedem Play-Upload steigen
AAB-Build-Konfig 🟡 Keine custom AAB-Targets, default bundleRelease würde laufen — aber mit debug-keystore. EAS erzeugt automatisch AAB bei production-Profile
eas.json 🔴 fehlt — siehe iOS
Adaptive Icon (foreground/background) adaptive-icon-android.png (foreground only, ohne Schrift wegen Mask) + adaptiveIcon.backgroundColor=#0a0a0a. mipmap-xxxhdpi etc. via prebuild generiert
Notification-Icon (24×24 monochrome) 🟡 nicht explizit gesetzt — Expo nutzt fallback. Für expo-notifications im Push-Use-Case sollte ein dedicated white-icon hinterlegt werden
Manifest Permissions INTERNET, BIND_VPN_SERVICE, BIND_ACCESSIBILITY_SERVICE, FOREGROUND_SERVICE, POST_NOTIFICATIONS, RECORD_AUDIO etc. drin
VpnService + AccessibilityService im Manifest deklariert (Zeile 38-48). Risk: Google Play prüft AccessibilityService-Apps streng (Use-Disclosure-Form pflicht). Empfehlung unten
Data-Safety-Form 🔴 Pflicht-Form in Play Console — User muss DSGVO-Selbstauskunft ausfüllen
Content-Rating 🔴 Erwartet PEGI 12+ wegen Glücksspiel-Thematik; Form muss vor Internal-Submit ausgefüllt werden

Cross-Platform

Item Status Detail
Versionierung sync (app.config.ts ↔ ios ↔ android) 🟡 app.config.ts:7 version="0.1.0" ↔ Info.plist CFBundleShortVersionString=0.1.0 ↔ android versionName="0.1.0". Synchron, aber mehrfache Locations → Sync-Skript fehlt
Privacy-Policy URL (öffentlich erreichbar) 🔴 NICHT gefunden im App-Code. Pflicht für App Store + Play Store. URL z.B. https://rebreak.org/privacy muss live sein
Imprint/Impressum URL 🔴 dito
Test-Account-Credentials für Reviewer 🔴 Erst External-Review-relevant, für Internal not blocking
apiUrl-Default im Build 🟡 https://staging.rebreak.org als fallback in app.config.ts:91 — für TF/Play-Internal sollte ein Production-API gewählt werden ODER explizit dokumentiert werden, dass Tester Staging-Backend nutzen
Supabase-Anon-Key hardcoded 🟡 app.config.ts:103 hat hardcoded staging anon-key (Comment sagt: temp bis BFF-Migration in Phase 5). Anon-Key ist designed für Client-Ship, RLS protected — aber für Production-Build sollte besser via env-Var injected werden

Internal-Only-Pfad (3 Tage — realistisch für Wochenende)

Nötiger Minimalumfang für TestFlight Internal + Play Console Internal Testing:

  1. eas.json schreiben mit 2-3 Profilen (development, preview, production-internal)
  2. Apple Developer Account aktiv + ASC-App "ReBreak" erstellen (User-Action)
  3. Play Console App-Entry für org.rebreak.app erstellen, Internal Testing Track aktiv (User-Action)
  4. EAS Login + projekt initialisieren (eas init → projectId in app.config.ts speichern)
  5. EAS managed credentials: eas credentials für iOS (cert + provisioning) und Android (Keystore generieren lassen ODER existing hochladen)
  6. iOS APS-Environment → für production-Build via EAS-Profile auf production setzen
  7. Build triggern: eas build --platform ios --profile production + eas build --platform android --profile production (kostet je 1 Build-Quota — User-Approval)
  8. Submit: eas submit --platform ios (lädt automatisch zu TestFlight) + eas submit --platform android --track internal
  9. TestFlight Internal Tester in ASC einladen (User per Email-Liste)
  10. Play Console Internal Tester in Play Console einladen (Email-Liste oder Google-Group)

Was Internal NICHT braucht (im Gegensatz zu External/Production):

  • Apple-Review (nur External Beta + Public)
  • Google-Review (nur Closed/Open Testing + Production)
  • Privacy-Policy-URL hardcoded sichtbar (nur für Listing)
  • Screenshots, Feature-Graphic, Beschreibung
  • Data-Safety-Form (technisch ja, aber für Internal nicht streng durchgesetzt — sollte trotzdem ausgefüllt werden)
  • Content-Rating

External-Beta-Pfad (zusätzlich, ~1 Woche)

Wenn ihr nach Internal-Test auf External (TestFlight Public Link / Play Closed-Test) gehen wollt:

  • Privacy-Policy-URL live unter https://rebreak.org/privacy (DSGVO-konform, mit Lyra-Memory + Auto-Extract-Klauseln, Hans-Müller-DSB review)
  • Imprint live unter https://rebreak.org/imprint
  • App Store Listing: 8+ Screenshots (iPhone 6.5", 5.5"), App-Beschreibung DE/EN
  • Play Store Listing: 8+ Screenshots Phone, Feature-Graphic 1024×500, Beschreibung DE/EN
  • Data-Safety-Form Play Console
  • App-Content-Rating Play Console (~PEGI 12+)
  • Apple-Review Notes: Demo-Account-Credentials, Hinweis dass Subscription über Web läuft (nicht IAP)
  • Apple Sign-In wirklich implementiert (nicht TODO) — wenn Google-OAuth bleibt, Apple-Sign-In-Pflicht
  • AccessibilityService Disclosure-Form Play Console (warum BIND_ACCESSIBILITY_SERVICE nötig — App-Schutz vor Glücksspiel-Apps)

Risk-Assessment

R1 — Stripe-IAP-Konflikt (HOCH für External, MITTEL für Internal)

Apple lehnt Apps für "digital goods" ab wenn nicht via IAP gekauft. Rebreak hat Pro/Legend-Subscription via Stripe. Aktueller App-Code zeigt KEINEN Upgrade-Button — nur Alert.alert("Upgrade nötig") ohne Stripe-Link. Das ist Apple-konformer Workaround:

  • App informiert User dass Pro nötig ist
  • Kein Link zur Web-Bezahlseite (Apple verbietet das im App-Body)
  • User abonniert auf rebreak.org/web (extern)
  • App nutzt aktiviertes Abo

Empfehlung: für Internal-Build OK lassen. Vor External-Submit Apple-Reviewer-Note schreiben: "Subscriptions are sold exclusively on rebreak.org. The app does not contain purchase flows. Pro features unlock automatically when the user's web account holds an active subscription."

R2 — VPN-Filter-Inclusion im Build (MITTEL)

Native Module rebreak-protection ist via app.config.ts plugins-Block aktiv. iOS NEFilter Extension + Android VpnService + AccessibilityService sind im Build mit drin. Für erstes Internal-TestFlight ist das Risiko:

  • iOS: NEFilterDataProvider braucht spezielle Entitlement-Approval von Apple (Network Extensions). Falls Apple Account das nicht hat → Build schlägt beim Codesign fehl.
  • Android: AccessibilityService braucht in Play Console eine Use-Disclosure beim Submit; ohne Form lehnt Google ab.

User-Decision nötig: Soll VPN-Filter im ersten TestFlight/Play-Internal-Build sein, oder erst V2? Empfehlung: für Internal Test OK behalten (kein Review), für External/Prod muss Disclosure-Form + Apple-Entitlement-Antrag laufen.

R3 — Apple Sign-In TODO (MITTEL für External)

stores/auth.ts:82-87 ist TODO. UI zeigt aber Apple-Pill. Bei External-Beta verlangt Apple Sign-In-with-Apple wenn andere 3rd-Party-Logins (Google) da sind — Pflicht-Guideline 4.8. Für Internal ist das egal (kein Review).

R4 — Production-Keystore-Custody (HOCH)

Aktuell ist nur Debug-Keystore eingerichtet. Bei eigenem Keystore: User hält Passwort, Backup-Pflicht (verloren = Update-Path tot). Empfehlung: EAS managed Credentials (EAS hält Keystore, ist Industry-Standard, kein User-Custody-Stress).

R5 — Hardcoded Supabase Anon-Key in app.config.ts (NIEDRIG)

app.config.ts:103 hat hardcoded staging anon key. Anon-keys sind designed for client-ship (RLS protected DB). Aber für Production sollte env-injection. Internal-Build OK.

R6 — Backend-API-Pointer für Tester (MITTEL)

apiUrl default ist https://staging.rebreak.org. Tester nutzen also Staging-DB. Wenn Prod-DB getrennt: Datenstand divergent. User-Decision: Internal-Tester gegen Staging oder schon Prod-Backend?


TODO-Liste sortiert nach Tag

Donnerstag 2026-05-07 (HEUTE — Recon + Doc)

  • RELEASE_READINESS.md schreiben
  • User: Antworten auf Open Questions (siehe unten)
  • User-Bestätigung: TestFlight & Play-Internal-Targeting (Internal-only oder gleich External?)

Freitag 2026-05-08 (Setup + Configs, alles ohne Build-Trigger)

  • zied: eas.json mit production-Profile schreiben (User reviewt vor Commit)
  • zied: app.config.ts cleanup wenn nötig (env-vars für apiUrl)
  • zied: Privacy-Policy + Imprint Stub-Pages (oder im rebreak-backend webroot deployen — Koordination mit rebreak-ops)
  • User: Apple Developer Account-Status verifizieren ($99/Jahr aktiv?)
  • User: ASC-App "ReBreak" erstellen (Bundle org.rebreak.app)
  • User: Play Console App-Entry erstellen + Internal-Test-Track + Tester-Liste
  • User: eas login + eas init (nur User kann sich einloggen)
  • User: Decision EAS-managed Credentials vs eigener Keystore
  • zied: VersionCode-Bump-Pattern dokumentieren

Samstag 2026-05-09 (Build + Submit, alles mit User-Approval)

  • User-Approval + Trigger: eas build --platform ios --profile production-internal
  • User-Approval + Trigger: eas build --platform android --profile production-internal
  • zied: Build-Output validieren (size, sha)
  • User-Approval + Trigger: eas submit --platform ios (TestFlight) + eas submit --platform android --track internal
  • User: TestFlight Tester-Emails einladen via ASC
  • User: Play Console Internal-Tester-Emails einladen
  • zied: Smoke-Test-Plan auf User-Device (Install, Login, Streak, Lyra-Chat 1 Roundtrip)

Sonntag 2026-05-10 (Buffer + Iteration)

  • Bugfix-Round 1 falls Tester-Feedback (rebreak-native-ui handled UI-Bugs)
  • Falls neue Build nötig: versionCode++ → re-upload

Top-5 User-Actions die nicht verschoben werden können

  1. Apple Developer Account login + ASC-App-Entry erstellen (org.rebreak.app, Bundle-ID, App-Name "ReBreak"). Ohne ASC-Entry kein TestFlight.
  2. Play Console App-Entry + Internal-Track aktivieren für org.rebreak.app. Ohne Track kein Internal-Upload.
  3. eas login + eas init im apps/rebreak-native/ ausführen — registriert Projekt + speichert projectId.
  4. Decision EAS-managed-Credentials vs eigener Keystore + ggf. Keystore-Passwort generieren/sichern (User-Custody, NIEMALS commit).
  5. Privacy-Policy + Imprint live unter rebreak.org-URLs — auch für Internal empfohlen (Vermeidet Hick-Up beim späteren External-Switch). Für External strikt Pflicht.

Realistischer Wochenend-Plan — Machbarkeit

Ja, Internal-TestFlight + Play-Internal sind machbar bis Sonntag 2026-05-10, sofern:

  • Apple Dev Account heute/morgen früh reaktiviert/bestätigt
  • User Freitag Mittag verfügbar für eas login + ASC/Play-Console-Setup
  • Keine Apple-Entitlement-Hick-Ups beim ersten iOS-Codesign (NEFilter braucht Entitlement-Approval — falls Apple Account das nicht hat, müssen wir die Plugin-Aktivierung temporär entfernen für Internal Build → V2 mit VPN-Filter)
  • EAS-Build-Quota verfügbar (Free-Tier hat ~30 Builds/Monat — sollte reichen)

Realistischer Risk-Pfad: Falls iOS-NEFilter-Entitlement nicht da ist, Plan B = Internal-TestFlight ohne VPN-Filter-Plugin (1-Line plugin-comment-out) → User-Test der Core-Loop (Streak/Lyra/Posts/Games) ohne Blocker-Feature. VPN-Filter dann V2.

External-Beta (TestFlight Public Link / Play Closed-Test) Wochenend-Ziel = NICHT realistisch. Privacy-Policy-Live + Apple-Review-Process + Sign-In-with-Apple-Implementierung würden mind. 1 weitere Woche brauchen.


3 wichtigste Open Questions an User

Q1 — VPN-Filter im ersten Build dabei oder rauslassen?

Plugins with-rebreak-protection-ios (NEFilter Extension) + with-rebreak-protection-android (VpnService + AccessibilityService) sind aktiv. Risk bei NEFilter: braucht spezielle Apple-Entitlement (Network Extensions Capability), die nicht im Standard-Dev-Account drin ist — muss von Apple separat genehmigt werden (1-2 Wochen Wartezeit historisch). Optionen:

  • (A) NEFilter+VpnService dabei → erstmaliger Build kann an Codesign scheitern, falls Entitlement fehlt
  • (B) Plugins temporär raus (1-Line Comment in app.config.ts), Core-App testflighten, VPN-Filter V2 mit eigenem Build-Cycle
  • (C) Erst Apple-Entitlement-Status prüfen (User-Login ASC), dann entscheiden

Q2 — Backend-API-Pointer für Internal-Tester: Staging oder Prod?

Default apiUrl=https://staging.rebreak.org. Tester schreiben dann in Staging-DB. Wenn Prod-DB schon läuft: Daten-Inkonsistenz. Wenn Test-DB OK: weiter mit Staging. Meine Empfehlung: Internal-Tester auf Staging (klarer Test-Modus, keine Vermischung mit Production-User). Externe Beta dann auf Prod.

Q3 — Keystore-Strategie Android: EAS managed oder eigener Custody?

EAS managed = EAS speichert keystore verschlüsselt, kein User-Custody, automatisch im Build verwendet. Industry-Standard. Recovery via Expo-Account. Eigener = User generiert keystore lokal, hält Passwort, lädt zu EAS hoch via eas credentials. Mehr Kontrolle, mehr Custody-Risk. Meine Empfehlung: EAS managed für Wochenend-Speed, später kann User keystore mit eas credentials --platform android exportieren wenn Custody gewünscht.