# 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)
- [x] `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.
