# LevelRep – Implementation Plan > Stand: 25.08.2026 · abgeleitet aus `offene-fragen.md` & `offene-fragen-v2.md` > > **Zweck:** Diesen Plan Schritt für Schritt durchgehen. Jede Task ist klein > genug, um in einer Session abgeschlossen zu werden. Keine parallelen > Branches, keine halben Sachen. > > **Hinweis:** Stand 25.08.2026 ist **bewusst noch kein Code** im Repo — > nur Dokumentation. Sobald du grünes Licht zum Coden gibst, starten wir > mit **M1 Task 1.2 (Flutter-Projekt anlegen)**. > > **Stack-Realität:** Flutter · Drift+SQLite · Riverpod · go_router · > sensors_plus · flutter_local_notifications · audioplayers · > font_awesome_flutter. Diese Festlegungen stammen aus `offene-fragen.md` > Block 9 und werden hier **nicht erneut diskutiert**. > > **Reihenfolge:** M1 → M2 → M3 → M4 → M5 → M6 → M7. Jeder Meilenstein > produziert eine **lauffähige App**, auch wenn Features noch fehlen. --- ## M1 – App-Grundgerüst (Foundation) > **Ziel:** App startet, Profile können angelegt/gewählt werden, Navigation > und Theme funktionieren, lokale Datenbank steht mit Schema v1, lokale > Einstellungen sind speicherbar. Noch **kein** Training, **keine** Sensorik. ### Tasks * **1.1 Android-Versionen festlegen** ✅ENTSCHIEDEN * **LevelRep läuft ausschließlich auf Android 16+** (kein Backport). * **Google-Play-Pflicht** (Stand Aug 2026): * `targetSdk` = **36** (Android 16) — Pflicht ab **31.08.2026** für neue Apps und Updates; Verlängerung bis 01.11.2026 auf Anfrage möglich. * **Festlegung LevelRep**: | Property | Wert | Warum | |---|---|---| | `compileSdk` | **36** | muss ≥ `targetSdk` sein | | `targetSdk` | **36** | Play-Store-Pflicht | | `minSdk` | **36** | bewusste Entscheidung: nur Android 16+; keine Deprecated-API-Kompromisse, einfacheres Testing | | `ndkVersion` | 27.0.12077973 | AGP-Default, kompatibel mit sensors_plus | * **Konsequenzen / Was sich vereinfacht**: * `flutter_local_notifications` und `sensors_plus` haben keine `minSdk`-Bremse mehr — beide laufen problemlos. * Volle Edge-to-Edge-Unterstützung ohne `WindowCompat`-Workarounds. * Predictive-Back-Gesture, neue Permissions-API etc. ohne Fallback. * Trade-off: Geräte mit Android ≤15 können LevelRep nicht installieren (Marktanteil 2026 <25 %, für Hobby-Projekt akzeptabel). * **TODO vor M7 Release**: prüfen, ob `flutter_local_notifications` in der final genutzten Version `minSdk = 36` deklariert; falls nicht, explizit in `android/app/build.gradle.kts` setzen (`defaultConfig.minSdk = 36`). * → in `offene-fragen-v2.md` Punkt 5 als gelöst markieren. * **1.2 Flutter-Projekt anlegen** * `flutter create --org de.mexx.levelrep --platforms=android levelrep` * minSdk/targetSdk in `android/app/build.gradle.kts` setzen. * App-Name **LevelRep**, Icon-Placeholder. * **1.3 Dependencies pinnen** (alle aus Block 9): * flutter_riverpod, riverpod_annotation * go_router * drift, drift_dev, sqlite3_flutter_libs, path_provider, path * sensors_plus * flutter_local_notifications, timezone * audioplayers * font_awesome_flutter * shared_preferences (für kleine Settings) * build_runner, riverpod_generator (dev) * **1.4 Projektstruktur (lib/)** ``` lib/ app/ # MaterialApp, Theme, RouterConfig core/ # Konstanten, Extensions, Utils data/ db/ # Drift-Database, DAOs, Schema-Migrations models/ # Plain DTOs repositories/ # CRUD-Wrapper um DAOs features/ profile/ # Profilauswahl, -erstellung settings/ # Theme, Sound, Vibration, Reminder ui/ # gemeinsame Widgets, Farben, Typo ``` * **1.5 Theme** * System folgen + Override Hell/Dunkel. * Farben als Konstanten aus `idee.md` (Rot/Blau/Grün/Gelb) ableiten. * Font Awesome Free als globaler Icon-Set. * **1.6 Drift-Datenbank v1 – nur Profile** * Tabelle `Profiles` (id, name, heightCm, weightKg, activityLevel, avatarEmoji, createdAt, schemaVersion). * Schema-Versionierung eingebaut, Migration-Stub vorhanden (für Block 10 wichtig). * **1.7 Navigation (go_router)** * Routen: `/` (Profile-Auswahl), `/profile/new`, `/home`, `/settings`, `/settings/theme`. * Empty-State für `/home` (Platzhalter "Übungsauswahl kommt in M2"). * **1.8 Profil-Features (CRUD)** * Liste vorhandener Profile auf Startseite. * Neues Profil anlegen (Name, Größe, Gewicht, Aktivitätslevel, Emoji-Avatar aus Vorauswahl). * Löschen mit Bestätigungsdialog, Umbenennen, Wechsel. * Aktivitätslevel: 4 Werte gemäß Block 5. * **1.9 Lokale Einstellungen** * Theme (System / Hell / Dunkel), Sound, Vibration, Reminder-Uhrzeit (default 18:00). * Persistierung via `shared_preferences`. * **1.10 Verifikation M1** * App startet im Emulator, Profil anlegen → erscheint in Liste. * App neu starten → Profil ist noch da. * Theme-Switch funktioniert. * Drift-Schema-Inspect via `drift_dev` zeigt Tabelle `Profiles`. --- ## M2 – Erste komplette Übung (Liegestütze) > **Ziel:** Eine Übung (Liegestütze) ist **komplett** spielbar: Kalibrierung, > Trainingseinheit, Satzsystem, Pausen, Max-Rep, Speicherung. Noch ohne > Tier-/Level-System. ### Tasks * **2.1 Übungs-Katalog als Code** * Enum / Konstante `Exercise { pushup, squat, pullup, situp }`. * Farben, Display-Namen, Piktogramm-Asset-Slots pro Übung. * v1.0: nur `pushup` aktiv geschaltet, andere als "Coming Soon". * **2.2 Smartphone-Positions-Piktogramm (Liegestütze)** * Eigenes Asset `assets/piktograms/pushup_position.png`. * Wird vor Kalibrierung und vor jedem Training angezeigt (Block 8). * **2.3 Kalibrierungs-Flow** * Beim ersten Öffnen einer Übung (per Profile → Übung) Pflicht-Kalibrierung (Block 3). * 5 Referenzwiederholungen, **kein Skip**. * Anleitungstext + Piktogramm, dann Live-Sensor-Recording. * Bei Fehlschlag konkrete UI-Anweisung (Block 3 – Fehlschlag-Handling). * Speicherung: Tabelle `Calibrations` (profileId, exerciseId, accelerometerProfile, gyroscopeProfile, createdAt). * **2.4 Sensor-Aufnahme (sensors_plus)** * Accelerometer + Gyroskop Stream mit ~50 Hz. * Pro Wiederholung: Peak-/Trough-Detektion für Liegestütze. * Sensor-Daten werden **nur zur Laufzeit** gehalten, nicht dauerhaft gespeichert (DSGVO – Block 10). * **2.5 Trainingseinheit-Datenmodell (Drift)** * Tabellen: * `Units` (id, profileId, exerciseId, tier, unitNumber, status, startedAt, completedAt) * `Sets` (id, unitId, setIndex, targetReps, actualReps, status, startedAt, completedAt) * `MaxReps` (id, unitId, reps, durationSec, createdAt) * Schema-Version 2 → Migration 1→2 ergänzen (Block 10). * **2.6 Tier-Auswahl (UI-only, keine Logik)** * Tier-Wahl (Beginner/Fortgeschritten/Pro) vor jeder Einheit. * Aktuell: Speichert nur die Wahl, Logik für Sperre kommt in M3. * **2.7 Einheit laden** * Aus `progress.md` (Liegestütze-Spalte passend zum Tier + Unit-Nummer). * Fortschritt: `unitsPlanned = 13`, pro Einheit nächste Unit-Number berechnen. * **2.8 Trainings-Screen** * Zeigt aktuelle Satzziele (z. B. `2 - 3 - 2 - 2`). * Live-Rep-Counter via Sensorik. * Manuelle Korrektur `+1` / `−1` am Satzende (Block 6). * Satz bestanden = Ziel erreicht → Pause startet. * **2.9 Pausen-Timer** * Default 60 s, manuell bis auf 5 s reduzierbar (Block 6). * Countdown + Tick in letzten 5 s + Vibration am Ende. * Sound + Haptik via Settings toggelbar. * **2.10 Max-Rep** * Nach letztem regulären Satz: "Max-Rep starten?" (optional). * Sensor- oder manuelle Rep-Erfassung. * Speicherung in `MaxReps`. * **2.11 Auto-Save nach jedem Satz** (Block 13) * Nach Set-Abschluss sofort in DB persistieren. * Bei Crash: abgeschlossene Sätze bleiben, laufender Satz geht verloren. * **2.12 Verifikation M2** * Pushup-Einheit komplett durchspielbar im Emulator. * Kalibrierung wird einmal erzwungen, danach übersprungen. * Auto-Save überlebt App-Force-Stop. * Manuelle Korrektur funktioniert. * Sensor-Fallback (manueller Counter) bei deaktiviertem Sensor vorhanden (Block 8). --- ## M3 – Trainingssystem (Tier, EXP, Level) > **Ziel:** Tier-Wechsel, Level-Berechnung und EXP-Vergabe laufen. > EXP-Kurve wird **nach M3-Daten** final festgelegt (Punkt 1 aus > `offene-fragen-v2.md`). ### Tasks * **3.1 Tier-Status-Tabelle** * `ProfileTierProgress` (profileId, exerciseId, tier, level, exp, lastUnitNumber, maxRepRecord, updatedAt). * Pro Übung drei Zeilen pro Profil (für die drei Tiers) — eine davon aktiv. * **3.2 Tier-Wechsel-Logik** (Block 2) * Freischaltung, wenn: 1. alle 13 Einheiten des aktuellen Tiers bestanden **und** 2. Level-Cap erreicht (Beginner 25, Fortgeschritten 50) **und** 3. übungsspezifischer Max-Rep-Zielwert bei ≥ 3 der letzten 5 Einheiten erreicht. * UI zeigt "Tier-Up verfügbar", User bestätigt manuell. * Beim Wechsel: Level = 0 (Block 1). * **3.3 EXP-Vergabe** (Block 1) * 1 EXP pro regulärer Wiederholung. * 2 EXP pro Max-Rep-Wiederholung. * Bonus beim vollständig abgeschlossenen Satz: +5 / +10 / +15 (Beginner / Fortgeschritten / Pro). * Bei Nichtbestehen: keine Satz-Bonus-EXP, aber gezählte Reps bleiben. * **3.4 EXP-Kurve** ⚠️ENTSCHEIDUNG * Vorschlag: quadratisch pro Tier-Index `t ∈ {0,1,2}`: `expNeeded(level, t) = 100 × (level+1) × (t+1)`. * → nach 2 Wochen Praxistests anhand realer EXP-Werte kalibrieren und in `offene-fragen-v2.md` Punkt 1 mit konkreter Tabelle fixieren. * **3.5 Max-Rep-Zielwerte pro Übung/Tier** ⚠️ENTSCHEIDUNG * Vorschlag Startwerte (zu verifizieren in M4-Praxistests): | Übung | Beg | Fort | Pro | |-------|-----|------|-----| | Pushup | 12 | 25 | 50 | | Squat | 20 | 40 | 75 | | Pullup | 4 | 10 | 20 | | Situp | 25 | 50 | 80 | * → nach M4 in `offene-fragen-v2.md` Punkt 2 final dokumentieren. * **3.6 Tier-Up UI** ⚠️ENTSCHEIDUNG * Modal/Bottomsheet "Tier-Up verfügbar!" mit kurzer Animation (z. B. Tier-Farbe aufblitzt). * Buttons: "Jetzt aufsteigen" / "Später". * Konkrete Visualisierung wird in M5 finalisiert (Punkt 3 aus `offene-fragen-v2.md`). * **3.7 Verifikation M3** * Beginner-Tier komplett durchspielen → Tier-Up wird angeboten. * Level steigt sichtbar nach jedem Satz. * Wechsel auf Fortgeschritten → Level = 0, neue Progression aktiv. --- ## M4 – Alle vier Übungen > **Ziel:** Kniebeugen, Klimmzüge, Sit-ups komplett spielbar mit eigener > Sensorlogik und Piktogrammen. ### Tasks * **4.1 Sensorprofile pro Übung** * Eigenes Detection-Modul pro Übung: * Kniebeugen: Vertikalbeschleunigung am Oberschenkel. * Klimmzüge: vertikale Hub-Bewegung + Gyro-Stabilität. * Sit-ups: Winkel-Kippen am Bauch. * Erkennungs-Algorithmus als isolierte Klasse (`_detector.dart`). * **4.2 Piktogramme für jede Übung** * `squat_position.png`, `pullup_position.png`, `situp_position.png`. * Werden vor Kalibrierung und vor jedem Training gezeigt. * **4.3 Progressionen** * Kniebeugen / Klimmzüge / Sit-ups aus `progress.md` (Blau/Grün/Gelb) implementiert. * **4.4 Übungs-Auswahl-Screen** * Vier Kacheln mit Farbe + Icon + aktuellem Level + Tier. * Nicht-kalibrierte Übungen mit Hinweis-Badge. * **4.5 Praxistests & Sensor-Feintuning** * Für jede Übung: 5× Kalibrierung + 5× Trainingseinheit, Aufnahme-Confidence loggen. * Schwellwerte anpassen bis Confidence ≥ 70 % im Schnitt. * Wenn nach 2 Einheiten < 70 %: Re-Kalibrierungs-Empfehlung (Block 3). * **4.6 Sensor-Schwellwerte dokumentieren** ⚠️ENTSCHEIDUNG * Pro Übung konkrete Accelerometer-/Gyro-Schwellwerte als JSON-Asset ablegen (`assets/calibration_thresholds.json`). * → Punkt 4 in `offene-fragen-v2.md` bei Abschluss dokumentieren. * **4.7 Verifikation M4** * Alle vier Übungen komplett durchspielbar. * Übungswechsel ohne Profilwechsel möglich. * Sensor-Fallback aktiv für jede Übung. --- ## M5 – Gamification & Statistik > **Ziel:** Achievements, Streaks, Charts, Wochenziele, Tier-Up-Visualisierung. ### Tasks * **5.1 Statistik-Tabellen (Drift)** * `Achievements` (id, profileId, code, unlockedAt) * `WeeklyGoals` (profileId, weekIso, targetUnits, achievedUnits) * **5.2 Achievement-Engine** (Block 12) * Liste der ~14 Achievements als Code-Konstanten. * Triggerpunkte: nach jedem Trainingsabschluss / Satz. * Push-Dialog "Achievement freigeschaltet!". * **5.3 Streak-Tracking** (Block 11) * Pro Profil + Übung. * Basiert auf geplanten Trainingseinheiten (Block 11). * Restday skippen / einlegen → bricht Streak nicht. * Auslassen eines geplanten Trainingstags → Streak = 0. * **5.4 Wochenziele** (Block 12) * Default: 3 Einheiten / Woche (pro Profil, übergreifend). * Wöchentlicher Reset, Anzeige im Home-Screen. * **5.5 Charts** (Block 11) * Pro Übung: Wiederholungen / Volumen / Max-Rep / EXP-Verlauf. * Library: `fl_chart`. * Default-Zeitraum: letzte 30 Einheiten. * **5.6 Tier-Up-Visualisierung** ⚠️ENTSCHEIDUNG * Konfetti-Animation (`confetti`-Package) + kurze Tier-Farbe-Füllung + Sound "level_up.mp3". * → Punkt 3 in `offene-fragen-v2.md` als gelöst markieren. * **5.7 Persönliche Rekorde** (Block 11) * Höchster Max-Rep, höchste Wiederholungszahl/Einheit, Gesamtwiederholungen, längste Streak. * Eigener Screen "Rekorde". * **5.8 Verifikation M5** * Achievement "Erste Einheit" wird ausgelöst. * Streak steigt nach geplantem Training, sinkt nach Überspringen. * Charts rendern mit echten Daten aus M2–M4. --- ## M6 – Stabilisierung > **Ziel:** App ist robust gegen Crashes, Sensor-Ausfall, Akku-Warnung, > Datenmigration. Backup funktioniert. ### Tasks * **6.1 Crash-Recovery** (Block 13) * Nach App-Neustart Dialog "Training fortsetzen?" mit den drei Optionen aus Block 13. * Bereits abgeschlossene Sätze bleiben erhalten. * **6.2 Sensor-Fallback** * Bei Sensor-Stream-Error → manueller Rep-Counter als Default-Modus für aktuellen Satz. * Visueller Hinweis: "Manueller Modus aktiv". * **6.3 Akku-Warnung** (Block 13) * Bei <15 % Akku: Bottom-Sheet mit Auswahl "Weitertrainieren" / "Manueller Modus". * Kein automatisches Umschalten. * **6.4 Re-Kalibrierung mid-workout** (Block 13) * Bereits abgeschlossene Sätze bleiben gültig. * Aktueller Satz wird verworfen, nach Re-Kal neu gestartet. * **6.5 Sensor-Schwellwerte final** * Aus M4-Praxistests + M6-Re-Tests konkrete Werte in `calibration_thresholds.json` fixieren. * → Punkt 4 in `offene-fragen-v2.md` final dokumentieren. * **6.6 JSON-Export / Import** (Block 5, 10) * Settings-Screen: "Daten exportieren" (Teilen via Android Share-Sheet). * "Daten importieren" mit Konflikt-Handling (überschreiben / zusammenführen / neues Profil). * Schema-Version im Export-Header. * **6.7 Datenbank-Migrationen absichern** (Block 10) * Migration-Tests für v1 → v2 → v3 → v4 → v5. * App-Update darf Nutzerdaten niemals löschen. * **6.8 Reminder-Notification** * Täglich zur eingestellten Uhrzeit. * Nur wenn heute Training geplant ist. * Block 9 – lokale Notification. * **6.9 UI-/UX-Feinschliff** * Empty-States, Error-States, Loading-States überall. * Animationen sparsam, alles unter 200 ms. * **6.10 Verifikation M6** * Force-Stop mid-Training → Wiederherstellung ok. * Import/Export-Roundtrip mit zwei Geräten. * Akku <15 % triggert Warnung. * Reminder kommt zur eingestellten Zeit. --- ## M7 – v1.0 Release > **Ziel:** Play-Store-reifes APK, kein "Experimental"-Badge mehr, alle > Entscheidungen aus `offene-fragen.md` ✅ abgehakt. ### Tasks * **7.1 Letzte offene ⚠️-Punkte abarbeiten** * `offene-fragen-v2.md` sollte zu diesem Zeitpunkt **leer** sein. * Jeder noch offene Punkt = Release-Blocker. * **7.2 App-Icon & Splashscreen final** * **7.3 App-Name, Kurzbeschreibung, lange Beschreibung (DE)** * **7.4 Datenschutzerklärung / Impressum-Hinweis im App-Menü** (DSGVO) * Da keine Cloud, keine Telemetrie: kurzer, klarer Text. * **7.5 Store-Listing (Play Store)** * Screenshots (4 Übungen + Profil + Statistik) * Feature-Liste, Versionshinweise. * **7.6 Release-Build signieren** * Keystore erstellen, `key.properties` pflegen, `flutter build apk --release`. * **7.7 QA-Pass** * 10 vollständige Trainingsläufe über alle 4 Übungen × 3 Tiers. * Mindestens 1 Kalibrierungs-Reject-Edgecase pro Übung. --- ## v1.x – danach | Slot | Inhalt | |------|--------| | Dips | erste zusätzliche Übung (Block 7) | | Weitere Übungen | offen, App-/Code-Update | | Trainings-Tagebuch | Block 12 – v1.x | | Weitere Achievements | leicht ergänzbar in M5 | | Sensor-Feintuning | iterativ, basierend auf User-Feedback | | Backup-Funktionen | ggf. Auto-Backup-Datei, optional Sync via Datei-Picker | --- ## Cross-Cutting-Anforderungen (für jeden Meilenstein) * **Auto-Save** nach jedem Satz (Block 13). * **Keine Online-Calls**, keine Telemetrie, keine Analytics (Block 9, 10). * **DSGVO-clean** — Trainingsdaten verlassen niemals das Gerät. * **Satzpause 60 s** Standard, manuell bis 5 s reduzierbar (Block 6). * **Profile** jederzeit löschbar mit Bestätigungsdialog (Block 5). * **Schema-Migration** sauber versioniert (Block 10). * **Sensor-Fallback** manueller Rep-Counter (Block 8). * **Sounds & Haptik** global deaktivierbar (Block 9). --- ## Tracking * Jede abgeschlossene Task bekommt ein ✅ in der Commit-Message. * Offene ⚠️-Punkte → `offene-fragen-v2.md`. * Gelöste ⚠️-Punkte → Antwort hier in `ENTSCHEIDUNG`-Zeile dokumentieren **und** in `offene-fragen-v2.md` als gelöst markieren.