# Rebreak — Testing State Audit & Roadmap
Author: Ahmed (QA) · Stand: 2026-05-07 · Status: Initial Audit, READ-ONLY
Dieses Dokument ist eine ehrliche Bestandsaufnahme. Antwort auf User-Frage:
„was und wie testen wir, welche Abdeckungsrate, wo drückt der Schuh".
Kurzfassung in einem Satz: Im neuen `rebreak-monorepo` existiert **null automatisierte
Test-Coverage**. Nicht „wenig" — **Null**. Die alte trucko-Suite (114 Vitest-Tests +
Postman + Playwright) deckt eine andere Architektur (Nuxt + Capacitor) ab und ist
nicht 1:1 portierbar.
---
## 1. Status quo (rebreak-monorepo)
### 1.1 Backend (`backend/`, Nitro standalone, Prisma + Supabase)
| Aspekt | Stand |
| ------------------- | ------------------------------------------------------------ |
| Test-Verzeichnis | nicht vorhanden (`tests/`, `__tests__/`, `*.test.ts` = leer) |
| Test-Framework | nicht installiert |
| Coverage-Tool | keins |
| `package.json` test | kein `test`-Script vorhanden |
| API-Endpoints | 122 Files in `server/api/**` — 0 abgedeckt |
| DB-Layer | 16 Files in `server/db/**` — 0 abgedeckt |
| Utils | 11 Files in `server/utils/**` — 0 abgedeckt |
| Middleware | `cors.ts` — 0 abgedeckt |
**Coverage-Schätzung Backend: 0 %.**
### 1.2 Frontend (`apps/rebreak-native/`, Expo SDK 53 + RN 0.79)
| Aspekt | Stand |
| ------------------- | ---------------------------------------------------------------- |
| Test-Verzeichnis | nicht vorhanden |
| `.maestro/` | nicht vorhanden |
| Test-Framework | weder `jest-expo` noch `@testing-library/react-native` installed |
| `package.json` test | nur `lint` + `typecheck`, kein `test` |
| Components | 58 Files — 0 abgedeckt |
| Hooks | 13 Hooks (`useMe`, `useUserPlan`, …) — 0 abgedeckt |
| Stores | 4 Zustand-Stores (`auth`, `coach`, `community`, `notifications`) — 0 abgedeckt |
| Lib (sosStream, llmProvider, ttsProvider, lyraResponse) | 17 Files — 0 abgedeckt |
| App-Routes | 11 Top-Level (`urge.tsx`, `lyra.tsx`, `auth/*`, `(app)/*`, `profile/*`) — 0 abgedeckt |
**Coverage-Schätzung Frontend: 0 %.**
Native-Module-Pfad `apps/rebreak-native/modules/rebreak-protection/android/src/test`
existiert als leerer Gradle-Skeleton, ohne reale Test-Klassen — Backyard's Scope.
### 1.3 CI / CD
- `.github/workflows/` existiert nicht im rebreak-monorepo.
- Es gibt **keinen** `rebreak-unit`-Job (existierte in trucko-monorepo, wurde nicht migriert).
- `xgit`-Deploy-Pipeline buildet ohne Tests durchzulaufen.
- Pre-commit-Hooks: keine.
- TypeScript ist die einzige stille Schutzlinie (`pnpm typecheck` in beiden Paketen).
### 1.4 Zusammenfassung
> 0 Tests, 0 CI-Gate, 0 Coverage. Die Auth-Middleware-500-Cascade dieser Woche wäre
> mit einem 8-Zeilen-Vitest-Test für `requireUser()` verhindert worden.
---
## 2. Heritage aus trucko-monorepo (was portierbar / inspirierend ist)
Pfad: `~/mono/trucko-monorepo/apps/rebreak/tests/`
### 2.1 Vitest Unit-Suite — gold-wert, ~70 % portierbar
`tests/unit/` — 6 Dateien, 114 Tests, alle grün (geprüft 2026-04-28):
| Datei | Was getestet | Portierbar? |
| --------------------------- | ------------------------------------------------------------- | ------------------------ |
| `cooldown.test.ts` | `signCooldownToken`, `verifyCooldownToken`, DB-Layer | Ja, 1:1 |
| `domain-blocklist.test.ts` | `getBlocklistedDomainsSet` Subdomain-Matching | Ja, 1:1 |
| `domain-limits.test.ts` | Plan-Limit-Enforcement bei Custom-Domains | Ja, 1:1 |
| `domain-validation.test.ts` | Domain-Regex + Sanitisierung | Ja, 1:1 |
| `domain-vote.test.ts` | `castDomainVote` Auto-Approve-Logik | Ja, 1:1 |
| `plan-features.test.ts` | `PLAN_LIMITS`, `getPlanLimits` für free/pro/legend | Ja, mit Tier-Update |
Alle nutzen `vi.mock('../../server/utils/prisma', …)` — keine echte DB nötig, läuft
in Sekunden, kein Secret-Setup. **Quick win:** copy + adjust import-paths
(`apps/rebreak/server/...` → `backend/server/...`).
### 2.2 Postman-Collection — sofort wiederverwendbar
`tests/postman/rebreak.postman_collection.json` deckt 12 Domains (Auth, Profile,
Streaks, Posts, Chat, Lyra, Notifications, Cooldown, Domain-Submissions,
Blocklist, Scores, Sicherheit-401-Sammlung).
Anpassungs-Aufwand:
- `{{baseUrl}}` ist URL-only, funktioniert für Nitro-standalone identisch.
- Auth-Pfad bleibt `POST /api/auth/login` — selbe Route in neuem Backend.
- Token-Auto-Extract-Skript funktioniert, da Backend Bearer-Token zurückgibt.
- Eventuell veraltete Endpoints (`/api/blocklist/*`, `/api/scores/*`) gegen neue
routes der Standalone-API verifizieren.
### 2.3 Playwright Smoke (`tests/e2e/smoke/`)
**Nicht portierbar** für Native-App. Nuxt-DOM-Selektoren, Browser-only, irrelevant
für Expo. `fixtures/auth.ts` (`loginAs(page, …)`) ist konzeptuell wiederverwendbar
für Maestro `JS-onFlowStart` — aber neu schreiben.
### 2.4 Cypress-Suite (`apps/rebreak/cypress/e2e/`)
`01-smoke.cy.ts`, `02-a11y.cy.ts` — Capacitor-Webview, irrelevant für RN. Skip.
---
## 3. Risk-Matrix — Top 10 ungetestete Critical Paths
Bewertung: **Risk = max(DSGVO-Risk, User-Trust-Risk, DiGA-Risk, Recovery-Risk)**.
| # | Pfad | Risk | Why | Empf. Test-Form |
| -- | ------------------------------------------------------ | -------- | ------------------------------------------------------------------------------ | -------------------------------- |
| 1 | `server/utils/auth.ts` → `requireUser()` | KRITISCH | Diese Woche 500-Cascade durch Bug. Jeder Endpoint hängt dran. | Unit (vitest) + supertest |
| 2 | `coach/sos-stream.get.ts` (Tier-LLM-Switch) | KRITISCH | Free/Pro=Groq, Legend=Haiku. Falscher LLM für falschen User = User-Trust-Bruch + Brand-Voice-Bruch. | Integration mit Plan-Mock |
| 3 | `coach/sos-stream.get.ts` (SSE-Stream + Chip-JSON) | KRITISCH | SOS ist Recovery-Schutz. Stream-Bruch oder Chip-Parse-Fail = User in Krise allein. | Integration + Stream-Snapshot |
| 4 | `community/post.post.ts` + `posts.get.ts` (Anonymität) | KRITISCH | DSGVO Art. 9 + Glücksspiel-Stigma. Wenn UI plötzlich `firstName`/`username` statt `nickname` liefert = Disaster. | Unit (DB-select-shape) + e2e |
| 5 | `cooldown/{request,status,cancel}.post/get.ts` | HOCH | DiGA-relevant Recovery-Schutz. Token-Sign/Verify war in trucko getestet — muss in neue Codebase portiert. | Unit (vitest, gemockt) |
| 6 | `urge/index.post.ts` + `lib/sosTtsQueue.ts` | HOCH | Urge-Logging ist Recovery-Kern-Feature. TTS-Queue = aktuell offen-modifiziert (siehe `git status`). | Unit + Component-Test |
| 7 | `auth/login.post.ts` + `auth/me.get.ts`/`me.patch.ts` | HOCH | Profile-Update = Demographics = DiGA-Daten. Bug = falsche Kohorten-Daten in BfArM-Antrag. | Unit (Zod-validate) + Postman |
| 8 | `stripe/webhook.post.ts` + Pro-Trial-Reward-Trigger | HOCH | Pro-Trial-Logik (Phase C, kommt). Missing Test = Free-User bekommen versehentlich Lifetime-Pro oder umgekehrt. | Unit + Integration mit Stripe-mock |
| 9 | `lib/llmProvider.ts` + `lib/sosStream.ts` (Frontend) | HOCH | Resolved-Provider-Logik passt zum Backend. Wenn Drift entsteht, sehen User falschen LLM-Pill (UX-Lüge). | Unit (RN-jest) |
| 10 | `mail/scan.post.ts` + `mail/connect.post.ts` | MITTEL | Mo's Scope, aber Recovery-relevant. Mail-Scan-Bug = User bekommt Casino-Newsletter durchgelassen. | Integration |
Nicht in Top 10 aber erwähnenswert:
- `protection/*` (URL-Filter-Blocklist) — DiGA-relevant, aber binär/idempotent
- `scores/*` (Leaderboard) — Anonymität-Risk via `feedback_anonymity_nickname.md`
- `notifications/*` — Push-Anrede mit `firstName` statt `nickname` = Anonymitäts-Bruch
---
## 4. Roadmap
### 4.1 Pre-TestFlight (Wochenende, Mai 2026) — absolutes Minimum
Ziel: App stürzt im TestFlight nicht beim Launch ab + die zwei kritischsten User-Journeys (Login + SOS-Trigger) funktionieren auf einem echten iPhone-Build.
| Task | Form | Aufwand |
| ----------------------------------------------------------------- | ------------- | ------- |
| Maestro CLI installieren + `apps/rebreak-native/.maestro/` anlegen | Setup | 30 min |
| Smoke-Flow `auth/sign-in.yaml` (Username + Pwd → App-Shell) | Maestro | 1 h |
| Smoke-Flow `sos/start.yaml` (Login → SOS-Button → Chat-Stream sieht 1+ Token) | Maestro | 1.5 h |
| Smoke-Flow `community/feed-loads.yaml` (Login → Feed → 1+ Post sichtbar) | Maestro | 1 h |
| Manueller Postman-Run der 12-Domain-Collection gegen Staging | manuell | 1 h |
| Backend-Sanity: `pnpm build:backend` + curl-Smoke gegen 5 wichtigste Endpoints (`/api/auth/me`, `/api/coach/sos-stream`, `/api/community/posts`, `/api/cooldown/status`, `/api/urge`) | manuell | 30 min |
**Wichtig:** das ist NUR Smoke. Keine Plan-Tier-Permutationen, keine Edge-Cases.
„Stürzt nicht ab + Happy-Path geht durch" ist das einzige Bestehen-Kriterium.
### 4.2 Post-TestFlight (Woche 1-2 nach Wochenend-Cutover)
| Task | Form | Aufwand |
| ------------------------------------------------------------------------------------- | ------------ | ------- |
| Vitest setup im `backend/` (vitest.config.ts, `pnpm add -D vitest @vitest/coverage-v8`) | Setup | 30 min |
| Port `cooldown.test.ts` von trucko nach `backend/tests/unit/` | Port + adjust| 1 h |
| Port `plan-features.test.ts` (mit Tier-Update legend-Pfad) | Port + adjust| 1 h |
| Port `domain-{blocklist,limits,validation,vote}.test.ts` | Port + adjust| 2 h |
| **NEU** `auth-requireUser.test.ts` — Bug-Replikation (Bearer fehlt, Bearer invalid, Plan-Lookup fail) | Unit | 2 h |
| **NEU** `lyraMemoryExtract.test.ts` — Klarnamen-Replacement-Pipeline | Unit | 1 h |
| Supertest-Setup für Integration (Nitro `.output/server` startable im Test) | Setup | 2 h |
| Integration: `auth/login` + `auth/me` Happy + 401-Pfad | Integration | 2 h |
| GitHub Action `rebreak-test.yml` — Job `backend-unit` (vitest run + coverage) | CI | 1 h |
| Postman-Collection nach `backend/tests/postman/` portieren + `{{baseUrl}}` auf staging.rebreak.org | Port | 2 h |
Coverage-Ziel nach Phase 2: **40 % Backend-Statements, 100 % der `utils/`-Files,
100 % `requireUser`-Branches.**
### 4.3 Phase C (Demographics + Pro-Trial) — TDD parallel
User-Auftrag steht: Demographics-Form + 1-Woche-Pro-Trial-Reward. Hier MUSS Test
parallel zur Implementation laufen, weil:
- Reward-Trigger-Bug = Free-Lifetime-Pro oder Trial-nie-revoked (Stripe-revenue-leak)
- DSGVO-Wording-Pflicht („nicht Daten-gegen-Geld")
- DiGA-Daten-Integrität
| Test | Form |
| ----------------------------------------------------------------------- | ----------- |
| `profile/me/demographics.patch.test.ts` — alle 5 Felder gesetzt → Trial | Unit |
| `profile/me/demographics.patch.test.ts` — Free + bereits Trial-used → kein Re-Trial | Unit |
| `profile/me/demographics.patch.test.ts` — Pro/Legend → kein Trial-Trigger | Unit |
| Cron-Test: `pro-trial-revoke.cron.test.ts` — nach 7d zurück auf free, sofern kein Stripe-Abo | Unit |
| Maestro `profile/demographics-fill.yaml` — Free-User füllt alle Felder, sieht Pro-Reward-Banner | E2E |
### 4.4 DiGA-Pathway — Hans-Müller-Frage
BfArM erwartet für DiGA-Approval (laut `hans-mueller.md` Scope):
- **Penetrationstest-Bericht** (jährlich) — externer Anbieter, nicht Ahmed's Scope
- **DSFA-Dokument** (Datenschutz-Folgenabschätzung) — Hans-Müller's Scope
- **ISO 27001 oder BSI-Grundschutz** — DevOps/Backyard's Scope
Was BfArM **nicht direkt** verlangt aber bei Audit fragt:
- „Ist Ihre Software automatisiert getestet? Welche Coverage?"
- „Wie verhindern Sie Regressionen bei Updates?"
- „Wie testen Sie Crisis-Detection-Logik?"
**Ahmed-Empfehlung:** für DiGA-Antrag streben wir an: **70 % Backend-Coverage,
60 % Frontend-Coverage, 100 % Crisis-Detection-Recall (Lyra-Eval-Suite),
dokumentierter Test-Plan + CI-Pipeline-Gate.** Das ist nicht Pflicht aber
glaubwürdigkeits-prägend. **Frage an User: soll Hans-Müller das im DSFA-Dokument
explizit machen?**
---
## 5. Tooling-Empfehlungen
### 5.1 Backend
- **Test-Framework: vitest 2.x.** Schnell (esbuild), TS-nativ, `vi.mock`-Pattern
matched 1:1 unsere trucko-Heritage. Kein Jest (langsamer, schlechtere TS-DX in
Nitro-Welt). Bun-test ist verlockend aber nitro+prisma stack ist node-validiert.
- **Coverage: `@vitest/coverage-v8`.** Built-in, schnell, accurate.
- **Integration-Tests: supertest** gegen ein in-process Nitro-`.output/server`
bundle. Alternativ: `pnpm dev` als Sidecar in CI starten und gegen
`localhost:3001` fetchen.
- **Mocking: Prisma via `vi.mock('../../server/utils/prisma', …)`** wie in trucko.
Supabase-Client per `vi.mock('@supabase/supabase-js', …)`.
- **Test-DB: NICHT setzen** in Phase 1+2. Mock reicht. Wenn später
Migration-Tests gebraucht: Postgres-Container in CI.
### 5.2 Frontend (Native)
- **Component-Tests: `jest-expo` + `@testing-library/react-native`.** Standard
Expo-Stack, gut dokumentiert. Snapshot-Tests sparsam (nur für stabile Strings,
kein i18n-Output).
- **E2E: Maestro.** Bereits in `ahmed.md` als Standard definiert. iOS+Android
YAML-Flows, kein Detox-Maintenance-Hell. Cloud-Run möglich für CI.
**NICHT Detox** — Setup-Aufwand zu hoch für unsere Team-Größe.
- **`testID`-Konvention:** `--`, z.B. `auth-username-input`,
`urge-sos-trigger-btn`. Component-Edits dafür sind erlaubt (in ahmed.md geregelt).
### 5.3 CI
- **GitHub Actions** `.github/workflows/rebreak-test.yml`:
- Job `backend-unit`: `pnpm install` → `pnpm --filter rebreak-backend test` →
Coverage-Upload als Artifact. Läuft auf jedem PR.
- Job `frontend-unit`: `pnpm --filter rebreak-native test`. PR-only.
- Job `maestro-cloud`: nur main-Branch + manuell via `workflow_dispatch`,
Maestro-Cloud-Token aus Secrets, gegen Staging-Build.
- **Coverage-Threshold (vitest):** Phase 2 weich (40/40), Phase C streng
(70 % critical paths in `server/utils/`, `server/api/coach/`, `server/api/auth/`).
---
## 6. Konkrete TODOs nach Priorität
### Hoch (vor TestFlight, Wochenende)
| # | TODO | Aufwand | Owner |
| - | --------------------------------------------------------------------- | ------- | -------------- |
| 1 | Maestro CLI auf Mac + Android-Emulator + iOS-Sim installieren | 30 min | User |
| 2 | `apps/rebreak-native/.maestro/auth/sign-in.yaml` schreiben | 1 h | Ahmed |
| 3 | `.maestro/sos/start.yaml` schreiben (testID's am SOS-Button + LLM-Pill nötig — Edit-Approval) | 1.5 h | Ahmed + UI |
| 4 | `.maestro/community/feed-loads.yaml` schreiben | 1 h | Ahmed |
| 5 | Postman-Collection nach `backend/tests/postman/` kopieren + Staging-Env | 1 h | Ahmed |
| 6 | Manueller Curl-Smoke-Sheet der Top-5-Endpoints + Erwartungs-Status-Codes | 30 min | Ahmed |
### Mittel (Woche 1-2 nach TestFlight)
| # | TODO | Aufwand |
| -- | ------------------------------------------------------------------- | ------- |
| 7 | Vitest setup `backend/` + erste Test `plan-features.test.ts` portiert | 1.5 h |
| 8 | Port der 5 weiteren trucko-unit-Tests | 4 h |
| 9 | Neuer Test `auth-requireUser.test.ts` (Bug-Replikation diese Woche) | 2 h |
| 10 | GitHub Action `rebreak-test.yml` Job `backend-unit` | 1 h |
| 11 | Supertest + Integration-Setup, dann `auth/login.integration.test.ts` | 2 h |
| 12 | jest-expo + `@testing-library/react-native` setup im `apps/rebreak-native` | 1 h |
| 13 | Erster RN-Test: `lib/llmProvider.test.ts` (Plan-Tier-Resolve-Logik) | 1.5 h |
| 14 | Erster Component-Test: `components/profile/ProfileHeader.test.tsx` | 1.5 h |
### Niedrig (Woche 3+)
| # | TODO | Aufwand |
| -- | ------------------------------------------------------------------- | ------- |
| 15 | Lyra-Eval-Suite (Crisis-Detection Golden-Prompts) aus trucko porten | 4 h |
| 16 | Maestro-Flow für Phase-C Demographics + Pro-Trial-Reward | 2 h |
| 17 | Stripe-Webhook-Test mit Stripe-Mock + Test-Mode | 3 h |
| 18 | DSFA-Anhang: Test-Coverage-Statement mit Hans-Müller abstimmen | 1 h |
| 19 | Penetrationstest-Provider auswählen (DiGA-Pflicht, jährlich) | User-Decision |
| 20 | Coverage-Threshold in CI-Gate hochziehen auf 70 % critical paths | 1 h |
---
## 7. Wo der Schuh am stärksten drückt — TL;DR
1. **Auth-Middleware ungeschützt.** Der 500-Cascade dieser Woche war ein Lehrgeld-Bug.
Ein 50-Zeilen-Vitest-File hätte ihn vor Deploy gefangen. Höchste Priorität.
2. **SOS-Stream + Tier-LLM-Routing ungeschützt.** Wenn ein Free-User den falschen
LLM bekommt oder der Stream bricht ab in der Krise — wir verlieren Vertrauen
plus das ist ein DiGA-Recovery-Risk.
3. **Anonymität-Pattern ungeschützt.** Wenn jemand bei einem Refactor versehentlich
`select: { firstName: true }` schreibt statt `{ nickname: true }`, sehen plötzlich
alle User echte Namen. DSGVO Art. 9 + Stigma + DiGA = sofortige Krise.
4. **Pro-Trial-Reward kommt ohne Tests** — Stripe-Revenue-Leak-Risiko, Phase C ist
Pflicht-TDD-Zone.
5. **Kein CI-Gate.** Jeder Push kann grün durchdeployen, auch wenn die Codebase
tot ist. Das muss als erstes nach TestFlight kommen.
---
## 8. Open Questions an User
1. **Maestro Cloud Account oder lokale Runs?** Cloud kostet ~10 EUR/Monat, gibt
parallele iOS+Android-Runs in CI. Lokal ist gratis aber blockt Mac-CPU.
2. **Pen-Test-Provider für DiGA-Pflicht?** Jährlich, ca. 5-15k EUR. Ahmed kann
Vorschläge sammeln (Cure53, SektionEins, CrowdStrike-Partner) — User-Decision.
3. **Demographics + Pro-Trial: TDD oder Test-after?** Empfehlung TDD, weil
Reward-Logik in Stripe + DSGVO-relevante Pfade. Bestätigung gewünscht?
4. **Coverage-Threshold-Strategie:** soft (warning, kein Block) oder hard
(PR-Block bei Drop)? Empfehlung: erste 6 Wochen soft, danach hard auf 60 %.
5. **Hans-Müller-Frage:** Soll die DSFA explizit eine Test-Coverage-Quote für
DiGA-Antrag committen? Wenn ja — dann müssen wir vor BfArM-Submission
beweisbar sein.
---
Ende. — Ahmed