# Goal System Redesign v2.0 **Datum:** 26. MΓ€rz 2026 **Status:** πŸ“‹ KONZEPTION **Anlass:** Fundamentale Design-Probleme in Phase 0a identifiziert --- ## 1. Probleme der aktuellen Implementierung (Phase 0a) ### 1.1 PrimΓ€rziel zu simplistisch **Problem:** - Nur EIN PrimΓ€rziel erlaubt - BinΓ€res System (primΓ€r/nicht-primΓ€r) - Toggle funktioniert nicht richtig beim Update **RealitΓ€t:** - User hat MEHRERE Ziele gleichzeitig mit unterschiedlichen PrioritΓ€ten - Beispiel: 30% Abnehmen, 25% Kraft, 25% Ausdauer, 20% Beweglichkeit **LΓΆsung:** β†’ **Gewichtungssystem** (0-100%, Summe = 100%) --- ### 1.2 Ein Goal Mode zu simpel **Problem:** - User muss sich fΓΌr EINEN Modus entscheiden (weight_loss ODER strength) - In RealitΓ€t: Kombinierte Ziele (Abnehmen + Kraft + Ausdauer gleichzeitig) **RealitΓ€t (User-Zitat):** > "Ich versuche nach einer Operation Kraft und Ausdauer aufzubauen, gleichzeitig Abzunehmen und meine Beweglichkeit und Koordination wieder zu steigern." **LΓΆsung:** β†’ **Multi-Mode mit Gewichtung** statt Single-Mode --- ### 1.3 Fehlende Current Values **Problem:** - `lean_mass` current value = "-" (nicht implementiert) - `strength`, `flexibility` haben keine Datenquellen - VO2Max wirft Internal Server Error **LΓΆsung:** β†’ Alle Goal-Typen mit korrekten Datenquellen verbinden --- ### 1.4 Abstrakte Zieltypen **Problem:** - "Kraft" - was bedeutet das? BankdrΓΌcken? Kniebeuge? Gesamt? - "Beweglichkeit" - welcher Test? Sit-and-Reach? HΓΌftbeugung? - Zu unspezifisch fΓΌr konkrete Messung **LΓΆsung:** β†’ **Konkrete, messbare Zieltypen** mit standardisierten Tests --- ### 1.5 Blutdruck als einzelner Wert **Problem:** - BP braucht ZWEI Werte (systolisch/diastolisch) - Aktuelles Schema: nur ein `target_value` **LΓΆsung:** β†’ **Compound Goals** (Ziele mit mehreren Werten) --- ### 1.6 Keine Guidance fΓΌr User **Problem:** - User muss konkrete Zahlen eingeben ohne Kontext - Was ist ein guter VO2Max Wert? Was ist realistisch? **LΓΆsung:** β†’ **Richtwerte, Normen, Beispiele** in UI --- ## 2. Redesign-Konzept v2.0 ### 2.1 Kern-Prinzipien **Prinzip 1: Gewichtung statt Priorisierung** - Alle Ziele haben eine Gewichtung (0-100%) - Summe aller Gewichtungen = 100% - KI berΓΌcksichtigt Gewichtung in Analysen **Prinzip 2: Multi-dimensional statt Singular** - Kein einzelner "Goal Mode" - Stattdessen: Gewichtete Kombination von Fokus-Bereichen - RealitΓ€tsnah: User hat mehrere Ziele gleichzeitig **Prinzip 3: Konkret statt Abstrakt** - Jedes Ziel hat klare Messbarkeit - Standardisierte Tests wo mΓΆglich - Datenquellen eindeutig definiert **Prinzip 4: Guidance statt Ratlosigkeit** - Richtwerte fΓΌr jedes Ziel - Alters-/Geschlechts-spezifische Normen - Beispiele und ErklΓ€rungen --- ## 3. Neues Datenmodell ### 3.1 Fokus-Bereiche (statt Goal Modes) **Tabelle: `focus_areas` (NEU)** ```sql CREATE TABLE focus_areas ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), profile_id UUID NOT NULL REFERENCES profiles(id) ON DELETE CASCADE, -- Gewichtete Fokus-Bereiche weight_loss_pct INT DEFAULT 0, -- 0-100% muscle_gain_pct INT DEFAULT 0, -- 0-100% endurance_pct INT DEFAULT 0, -- 0-100% strength_pct INT DEFAULT 0, -- 0-100% flexibility_pct INT DEFAULT 0, -- 0-100% health_pct INT DEFAULT 0, -- 0-100% (Erhaltung, kein spezifisches Ziel) -- Constraint: Summe muss 100 sein CONSTRAINT sum_equals_100 CHECK ( weight_loss_pct + muscle_gain_pct + endurance_pct + strength_pct + flexibility_pct + health_pct = 100 ), active BOOLEAN DEFAULT true, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW(), -- Nur ein aktiver Fokus-Mix pro User UNIQUE(profile_id, active) WHERE active = true ); COMMENT ON TABLE focus_areas IS 'Weighted focus distribution - replaces single goal_mode. Example: 30% weight loss + 25% strength + 25% endurance + 20% flexibility = 100%'; ``` **Beispiel-Daten:** ```json // User nach Operation (wie im Feedback beschrieben): { "weight_loss_pct": 30, "muscle_gain_pct": 20, "endurance_pct": 25, "strength_pct": 15, "flexibility_pct": 10, "health_pct": 0 } // User reiner Kraftfokus: { "weight_loss_pct": 0, "muscle_gain_pct": 50, "strength_pct": 40, "endurance_pct": 10, "flexibility_pct": 0, "health_pct": 0 } // User Gewichtsverlust primΓ€r: { "weight_loss_pct": 60, "muscle_gain_pct": 0, "endurance_pct": 20, "strength_pct": 10, "flexibility_pct": 5, "health_pct": 5 } ``` --- ### 3.2 Überarbeitete Goal-Typen **Tabelle: `goals` (ÜBERARBEITET)** **A) Simple Goals (ein Wert):** ```sql goal_type: - 'weight' β†’ kg (aus weight_log) - 'body_fat_pct' β†’ % (aus caliper_log) - 'lean_mass' β†’ kg (berechnet: weight - (weight * bf_pct)) - 'vo2max' β†’ ml/kg/min (aus vitals_baseline) - 'rhr' β†’ bpm (aus vitals_baseline) - 'hrv' β†’ ms (aus vitals_baseline) ``` **B) Test-based Goals (standardisierte Tests):** ```sql goal_type: - 'cooper_test' β†’ Meter (12min Lauf) - 'pushups_max' β†’ Anzahl - 'plank_max' β†’ Sekunden - 'sit_reach' β†’ cm (Beweglichkeit) - 'squat_1rm' β†’ kg (Kraft UnterkΓΆrper) - 'bench_1rm' β†’ kg (Kraft OberkΓΆrper) - 'deadlift_1rm' β†’ kg (Kraft RΓΌcken) ``` **C) Compound Goals (mehrere Werte):** ```sql goal_type: - 'blood_pressure' β†’ systolic/diastolic (mmHg) β†’ Braucht: target_value_secondary ``` **Schema-Erweiterung:** ```sql ALTER TABLE goals ADD COLUMN goal_weight INT DEFAULT 100; -- Gewichtung dieses Ziels (0-100%) -- Summe aller goal_weight fΓΌr einen User sollte ~100% sein ALTER TABLE goals ADD COLUMN target_value_secondary DECIMAL(10,2); -- FΓΌr Compound Goals (z.B. BP diastolisch) ALTER TABLE goals ADD COLUMN current_value_secondary DECIMAL(10,2); -- Aktueller Wert fΓΌr sekundΓ€ren Target ALTER TABLE goals DROP COLUMN is_primary; -- Nicht mehr nΓΆtig (wird durch goal_weight ersetzt) COMMENT ON COLUMN goals.goal_weight IS 'Weight/priority of this goal (0-100%). Higher weight = more important in AI scoring. Sum of all goal_weight should be ~100% per user.'; ``` --- ### 3.3 Datenquellen-Mapping **Korrekte Current-Value Extraktion:** ```python # backend/routers/goals.py - _get_current_value_for_goal_type() GOAL_TYPE_SOURCES = { # Simple values from existing tables 'weight': { 'table': 'weight_log', 'column': 'weight', 'order': 'date DESC' }, 'body_fat_pct': { 'table': 'caliper_log', 'column': 'body_fat_pct', 'order': 'date DESC' }, 'lean_mass': { 'calculation': 'weight - (weight * body_fat_pct / 100)', 'requires': ['weight_log', 'caliper_log'] }, 'vo2max': { 'table': 'vitals_baseline', 'column': 'vo2_max', 'order': 'date DESC' }, 'rhr': { 'table': 'vitals_baseline', 'column': 'resting_hr', 'order': 'date DESC' }, 'hrv': { 'table': 'vitals_baseline', 'column': 'hrv', 'order': 'date DESC' }, # Test-based values from fitness_tests 'cooper_test': { 'table': 'fitness_tests', 'filter': "test_type = 'cooper_12min'", 'column': 'result_value', 'order': 'test_date DESC' }, 'pushups_max': { 'table': 'fitness_tests', 'filter': "test_type = 'pushups_max'", 'column': 'result_value', 'order': 'test_date DESC' }, # ... weitere Tests # Compound goals 'blood_pressure': { 'table': 'blood_pressure_log', 'columns': ['systolic', 'diastolic'], # Beide Werte 'order': 'measured_at DESC' } } ``` --- ## 4. UI/UX Redesign ### 4.1 Fokus-Bereiche Konfigurator **Statt 5 einzelne Cards β†’ Slider-Interface:** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ 🎯 Mein Trainings-Fokus β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ Verschiebe die Regler um deine PrioritΓ€ten zu β”‚ β”‚ setzen. Die Summe muss 100% ergeben. β”‚ β”‚ β”‚ β”‚ πŸ“‰ Gewichtsverlust [====] 30% β”‚ β”‚ Schwerpunkt auf Kaloriendefizit & Fettabbau β”‚ β”‚ β”‚ β”‚ πŸ’ͺ Muskelaufbau [===] 20% β”‚ β”‚ Magermasse steigern, KΓΆrperkomposition β”‚ β”‚ β”‚ β”‚ πŸƒ Ausdauer [====] 25% β”‚ β”‚ VO2Max, aerobe KapazitΓ€t, Pace β”‚ β”‚ β”‚ β”‚ πŸ‹οΈ Maximalkraft [==] 15% β”‚ β”‚ 1RM Steigerung, progressive Belastung β”‚ β”‚ β”‚ β”‚ 🀸 Beweglichkeit [=] 10% β”‚ β”‚ MobilitΓ€t, FlexibilitΓ€t, Koordination β”‚ β”‚ β”‚ β”‚ ❀️ Allgemeine Gesundheit [ ] 0% β”‚ β”‚ Erhaltung, prΓ€ventiv β”‚ β”‚ β”‚ β”‚ ────────────────────────────────────────────────── β”‚ β”‚ Gesamt: 100% βœ“ β”‚ β”‚ β”‚ β”‚ [Speichern] [ZurΓΌcksetzen] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` **Technisch:** - HTML Range Slider (0-100) - Live-Update der Summe - Validierung: Summe muss 100% sein - Auto-Adjust: Wenn User einen Slider erhΓΆht, andere proportional reduzieren --- ### 4.2 Ziele mit Gewichtung **Goal-List mit Gewichtungs-Indikator:** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ 🎯 Konkrete Ziele β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ βš–οΈ Zielgewicht: 82 kg [30%]β”‚ β”‚ β”‚ β”‚ Start: 95 kg β†’ Aktuell: 89 kg β†’ Ziel: 82 kg β”‚ β”‚ β”‚ β”‚ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘ 65% β”‚ β”‚ β”‚ β”‚ βœ“ Voraussichtlich: 15.05.2026 (on track) β”‚ β”‚ β”‚ β”‚ [✏️] [πŸ—‘οΈ] β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ πŸ’ͺ Magermasse: 72 kg [20%]β”‚ β”‚ β”‚ β”‚ Start: 68 kg β†’ Aktuell: 70.5 kg β†’ Ziel: 72 kgβ”‚ β”‚ β”‚ β”‚ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘ 63% β”‚ β”‚ β”‚ β”‚ ⚠ Prognose: 20.06.2026 (5 Tage spΓ€ter) β”‚ β”‚ β”‚ β”‚ [✏️] [πŸ—‘οΈ] β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ [+ Neues Ziel] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ Summe Gewichtungen: 50% (noch 50% verfΓΌgbar) ``` **Γ„nderungen:** - Gewichtung in `[30%]` Badge angezeigt - Summe unten angezeigt - Warnung wenn Summe > 100% --- ### 4.3 Ziel-Editor mit Guidance **Beispiel: VO2Max Ziel erstellen:** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Neues Ziel erstellen β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ Zieltyp β”‚ β”‚ [VO2 Max β–Ό] β”‚ β”‚ β”‚ β”‚ ℹ️ VO2 Max (ml/kg/min) - Maximale Sauerstoffauf- β”‚ β”‚ nahme. Misst die aerobe LeistungsfΓ€higkeit. β”‚ β”‚ β”‚ β”‚ πŸ“Š Richtwerte (MΓ€nner, 35 Jahre): β”‚ β”‚ Sehr gut: > 48 ml/kg/min β”‚ β”‚ Gut: 44-48 ml/kg/min β”‚ β”‚ Durchschn.: 40-44 ml/kg/min β”‚ β”‚ Unterdurch.: 35-40 ml/kg/min β”‚ β”‚ β”‚ β”‚ 🎯 Zielwert β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ [ 46 ] β”‚ ml/kg/minβ”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ Dein aktueller Wert: 42 ml/kg/min (Durchschnitt) β”‚ β”‚ β†’ Ziel liegt in "Gut"-Bereich βœ“ β”‚ β”‚ β”‚ β”‚ πŸ“… Zieldatum (optional) β”‚ β”‚ [2026-06-30] β”‚ β”‚ β”‚ β”‚ βš–οΈ Gewichtung β”‚ β”‚ [==== ] 25% β”‚ β”‚ Wie wichtig ist dir dieses Ziel? β”‚ β”‚ β”‚ β”‚ πŸ’‘ Name (optional) β”‚ β”‚ [Ausdauer fΓΌr Bergwandern ] β”‚ β”‚ β”‚ β”‚ [Ziel erstellen] [Abbrechen] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` **Features:** - Info-Box mit ErklΓ€rung - Alters-/geschlechtsspezifische Richtwerte - Live-Feedback zum eingegebenen Wert - Aktueller Wert automatisch geladen - Gewichtungs-Slider mit Live-Preview --- ### 4.4 Compound Goals (Blutdruck) **Spezial-UI fΓΌr Blutdruck:** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Zieltyp: Blutdruck β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ 🎯 Zielwerte β”‚ β”‚ β”‚ β”‚ Systolisch (oberer Wert) β”‚ β”‚ [ 120 ] mmHg β”‚ β”‚ β”‚ β”‚ Diastolisch (unterer Wert) β”‚ β”‚ [ 80 ] mmHg β”‚ β”‚ β”‚ β”‚ ℹ️ WHO/ISH Klassifikation: β”‚ β”‚ Optimal: < 120/80 mmHg β”‚ β”‚ Normal: 120-129 / 80-84 mmHg β”‚ β”‚ Hoch-norm.: 130-139 / 85-89 mmHg β”‚ β”‚ Hypertonie: β‰₯ 140/90 mmHg β”‚ β”‚ β”‚ β”‚ Dein aktueller Wert: 135/88 mmHg (Hoch-normal) β”‚ β”‚ Dein Ziel: 120/80 mmHg (Optimal) βœ“ β”‚ β”‚ β”‚ β”‚ [Ziel erstellen] [Abbrechen] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` --- ## 5. Scoring-System mit Gewichtung ### 5.1 Score-Berechnung v2.0 **Aktuell (Phase 0a):** ```python # Feste Gewichtung per goal_mode SCORE_WEIGHTS = { "strength": { "body_progress": 0.35, "nutrition": 0.30, # ... } } ``` **Neu (v2.0):** ```python def calculate_weighted_score(profile_id): """ Berechnet Score basierend auf: 1. Focus Areas (Multi-dimensional statt single mode) 2. Goal Weights (individuelle Ziel-Gewichtungen) """ # 1. Hole Focus Areas focus = get_focus_areas(profile_id) # β†’ {weight_loss: 30%, muscle_gain: 20%, endurance: 25%, ...} # 2. Hole alle Ziele mit Gewichtung goals = get_goals_with_weights(profile_id) # β†’ [{type: 'weight', weight: 30%}, {type: 'lean_mass', weight: 20%}, ...] # 3. Berechne Basis-Scores base_scores = { 'body_composition': calculate_body_score(profile_id), 'nutrition': calculate_nutrition_score(profile_id), 'training': calculate_training_score(profile_id), 'recovery': calculate_recovery_score(profile_id) } # 4. Gewichte Scores nach Focus Areas weighted_score = 0 # Weight Loss Focus β†’ Body Composition + Nutrition wichtiger if focus['weight_loss_pct'] > 0: weighted_score += ( base_scores['body_composition'] * 0.4 + base_scores['nutrition'] * 0.4 + base_scores['training'] * 0.1 + base_scores['recovery'] * 0.1 ) * (focus['weight_loss_pct'] / 100) # Muscle Gain Focus β†’ Body + Nutrition + Training if focus['muscle_gain_pct'] > 0: weighted_score += ( base_scores['body_composition'] * 0.35 + base_scores['nutrition'] * 0.35 + base_scores['training'] * 0.25 + base_scores['recovery'] * 0.05 ) * (focus['muscle_gain_pct'] / 100) # Endurance Focus β†’ Training + Recovery if focus['endurance_pct'] > 0: weighted_score += ( base_scores['training'] * 0.50 + base_scores['recovery'] * 0.30 + base_scores['body_composition'] * 0.10 + base_scores['nutrition'] * 0.10 ) * (focus['endurance_pct'] / 100) # ... weitere Focus Areas return { 'overall_score': round(weighted_score, 1), 'base_scores': base_scores, 'focus_weights': focus, 'goal_weights': [g['weight'] for g in goals] } ``` **Beispiel:** ```python User: 30% Weight Loss + 25% Endurance + 20% Muscle Gain + 25% Strength Base Scores: - Body Composition: 75/100 - Nutrition: 80/100 - Training: 70/100 - Recovery: 65/100 Calculation: Weight Loss (30%): = (75*0.4 + 80*0.4 + 70*0.1 + 65*0.1) * 0.30 = 69.5 * 0.30 = 20.85 Endurance (25%): = (70*0.50 + 65*0.30 + 75*0.10 + 80*0.10) * 0.25 = 69.0 * 0.25 = 17.25 Muscle Gain (20%): = (75*0.35 + 80*0.35 + 70*0.25 + 65*0.05) * 0.20 = 74.0 * 0.20 = 14.80 Strength (25%): = (70*0.40 + 80*0.30 + 75*0.20 + 65*0.10) * 0.25 = 72.5 * 0.25 = 18.13 Overall Score = 20.85 + 17.25 + 14.80 + 18.13 = 71.03/100 ``` --- ## 6. Migration-Strategie ### 6.1 Daten-Migration von Phase 0a **Bestehende Daten:** - `profiles.goal_mode` (single mode) - `goals` mit `is_primary` **Migrations-Logik:** ```sql -- Migration 023: Goal System Redesign v2.0 -- 1. Erstelle focus_areas Tabelle CREATE TABLE focus_areas (...); -- 2. Migriere bestehende goal_mode β†’ focus_areas INSERT INTO focus_areas (profile_id, weight_loss_pct, muscle_gain_pct, ...) SELECT id, CASE goal_mode WHEN 'weight_loss' THEN 70 -- 70% Weight Loss + 15% Health + 15% Endurance WHEN 'strength' THEN 0 -- ... END as weight_loss_pct, CASE goal_mode WHEN 'strength' THEN 60 WHEN 'recomposition' THEN 30 -- ... END as muscle_gain_pct, -- ... weitere FROM profiles WHERE goal_mode IS NOT NULL; -- 3. Erweitere goals Tabelle ALTER TABLE goals ADD COLUMN goal_weight INT DEFAULT 100; ALTER TABLE goals ADD COLUMN target_value_secondary DECIMAL(10,2); ALTER TABLE goals ADD COLUMN current_value_secondary DECIMAL(10,2); -- 4. Migriere is_primary β†’ goal_weight UPDATE goals SET goal_weight = 100 WHERE is_primary = true; UPDATE goals SET goal_weight = 50 WHERE is_primary = false; -- 5. Cleanup (spΓ€ter) -- ALTER TABLE profiles DROP COLUMN goal_mode; -- nach Verifikation -- ALTER TABLE goals DROP COLUMN is_primary; -- nach Verifikation ``` --- ## 7. Implementierungs-Phasen ### Phase 1: Konzeption βœ… (DIESES DOKUMENT) **Dauer:** - **Ziel:** VollstΓ€ndiges Redesign-Konzept ### Phase 2: Backend Redesign (6-8h) - Migration 023 erstellen - `focus_areas` Tabelle + CRUD - `goals` erweitern (weight, secondary values) - Datenquellen-Mapping korrigieren (lean_mass, VO2Max fix, etc.) - Scoring-System v2.0 implementieren ### Phase 3: Frontend Redesign (8-10h) - Fokus-Bereiche Slider-UI - Ziel-Editor mit Guidance (Richtwerte, Normen) - Gewichtungs-System in Goal-Liste - Compound Goals UI (Blutdruck zwei Werte) - Neue Goal-Typen (Tests) integrieren ### Phase 4: Testing & Refinement (2-3h) - Migration testen (Phase 0a β†’ v2.0) - Scoring-Logik verifizieren - UI/UX Testing - Edge Cases (Summe β‰  100%, keine Ziele, etc.) **Total: 16-21h** --- ## 8. Offene Fragen / Entscheidungen ### 8.1 Focus Areas vs Goals Weight **Frage:** Brauchen wir BEIDE Gewichtungssysteme? - Focus Areas (Weight Loss 30%, Strength 25%, ...) - Goal Weights (Ziel "82kg" = 30%, Ziel "VO2Max 46" = 25%, ...) **Option A:** NUR Focus Areas - Einfacher - Weniger Redundanz - Aber: Weniger granular **Option B:** BEIDE Systeme - Focus Areas = Strategisch (Richtung) - Goal Weights = Taktisch (konkrete PrioritΓ€ten) - Komplexer, aber flexibler **Empfehlung:** Option B - beide Systeme ergΓ€nzen sich --- ### 8.2 Konkrete vs Abstrakte Tests **Frage:** Wie konkret sollen Strength-Goals sein? **Option A:** Sehr konkret - `bench_press_1rm`, `squat_1rm`, `deadlift_1rm` - Vorteil: PrΓ€zise, messbar - Nachteil: Viele Goal-Typen **Option B:** Abstrakt mit Kontext - `strength` mit Sub-Type (Bench/Squat/Deadlift) - Vorteil: Flexibler - Nachteil: Komplizierteres Schema **Empfehlung:** Option A - konkrete Typen, dafΓΌr klare Messbarkeit --- ### 8.3 Auto-Update von Current Values **Frage:** Wie oft sollen current_value aktualisiert werden? **Option A:** On-Demand (beim Laden der Goals-Seite) - Vorteil: Keine Background-Jobs - Nachteil: Kann verzΓΆgert sein **Option B:** Trigger-basiert (bei neuem Messwert) - Vorteil: Immer aktuell - Nachteil: Mehr KomplexitΓ€t **Empfehlung:** Option A fΓΌr MVP, Option B spΓ€ter --- ## 9. NΓ€chste Schritte ### User-Feedback einholen: 1. βœ… LΓΆst das Redesign alle genannten Probleme? 2. βœ… Ist die Fokus-Bereiche UI verstΓ€ndlich? 3. βœ… Sind die konkreten Goal-Typen sinnvoll? 4. βœ… Brauchen wir beide Gewichtungssysteme? 5. βœ… Fehlt noch etwas? ### Nach Freigabe: 1. Migration 023 schreiben 2. Backend implementieren 3. Frontend implementieren 4. Testing --- **Erstellt:** 26. MΓ€rz 2026 **Status:** πŸ“‹ WARTET AUF FEEDBACK **NΓ€chster Schritt:** User-Review & Freigabe