Files
LevelRep/implementation-plan.md
T
HermesAI-Bot 2154077d95 minSdk auf 36 (nur Android 16+)
Bewusste Entscheidung: LevelRep laeuft ausschliesslich auf Android 16+.
Damit keine Deprecated-API-Kompromisse und einfacheres Testing.
flutter_local_notifications-Bremse entfaellt komplett.
2026-08-25 11:01:55 +00:00

461 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.
>
> **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 (`<exercise>_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.