# Phase 0b Placeholder Improvements & Missing Values

> **Status:** 🔴 Draft - User Input in Progress
> **Datum:** 29.03.2026
> **Zweck:** Sammlung fehlender Platzhalter und Verbesserungspotenziale nach Phase 0b

---

## Executive Summary: Zwei Kritische Gaps (29.03.2026)

### 🚨 Gap #1: Quality Label wird nicht berücksichtigt
**Activity Platzhalter berücksichtigen `quality_label` nicht!**

- ❌ **Alle** activity-bezogenen Platzhalter nutzen ALLE Trainings (inkl. poor/excluded)
- ⚠️ **Betroffene Platzhalter:** `{{activity_summary}}`, `{{activity_detail}}`, `{{trainingstyp_verteilung}}`, `{{training_minutes_week}}`, `{{training_frequency_7d}}`, `{{ability_balance_*}}`, etc.
- ✅ **Einzige Ausnahme:** `{{quality_sessions_pct}}` (zählt nur excellent/good)
- 🔧 **Infrastruktur vorhanden:** `quality_filter.py` existiert bereits, wird aber NICHT genutzt

**Auswirkung:** Standard-Auswertungen in KI-Prompts zählen schlechte/ausgeschlossene Trainings mit → **verfälschte Analysen**!

**Empfohlene Lösung:**
1. Quality-Filter in `data_layer/activity_metrics.py` einbauen (6-8h)
2. Neue Platzhalter für Evaluation-Breakdown (3h)
3. Quality-Weighted Metrics (2h)
**Teilsumme:** 11-13h

---

### 🚨 Gap #2: Keine Trainingstyp-spezifischen Platzhalter
**KI kann nicht nach Trainings-Kategorien differenzieren!**

- ❌ **Keine Kategorie-spezifischen Platzhalter** (Kraft, Cardio, Kampfsport getrennt)
- ❌ **Keine Subcategory-Differenzierung** (Hypertrophie vs. Maximalkraft vs. Kraftausdauer)
- ❌ **Keine Ruhepausen-Analyse** nach Trainingstyp (48h zwischen Kraft-Einheiten?)
- ❌ **Keine Muskelerhalt-Logik** (mind. 2x/Woche Kraft?)
- ❌ **Keine Balance-Analysen** (Cardio:Kraft Ratio, fehlende Kategorien)
- ✅ **Was existiert:** `{{trainingstyp_verteilung}}` (nur Top 3 Kategorien), `{{ability_balance_*}}`

**Auswirkung:** KI kann NICHT coachen zu:
- "Zu wenig Krafttraining für Muskelerhalt" (kein `{{strength_frequency}}`)
- "48h Pause zwischen Kraft-Einheiten" (kein `{{days_since_last_strength}}`)
- "Zu cardio-lastig, mehr Kraft empfohlen" (kein `{{cardio_to_strength_ratio}}`)
- "Kein Mobility-Training in 30 Tagen" (kein `{{missing_categories}}`)

**Empfohlene Lösung:**
1. Kategorie-spezifische Count/Minutes Platzhalter (4-5h)
2. Ruhepausen-Analyse nach Kategorie (3h)
3. Balance-Scores & Ratios (2-3h)
4. Subcategory-Analysen (2h)
**Teilsumme:** 11-13h

---

**GESAMT:** 22-26h Implementierung für beide Gaps

---

## 0. Governance-Anforderungen & Fit/Gap-Analyse (User Requirements)

> **Quelle:** `placeholder_requirements_for_development.md` (29.03.2026)
> **Zweck:** Professionelle Placeholder-Governance für Prompt-Bibliothek V1

### Governance-Prinzipien (verbindlich):

1. **Platzhalter = API-Verträge** - keine Ad-hoc-Erfindungen in Prompts
2. **Keine stillschweigenden Änderungen** - Semantik, Zeitfenster, Einheit stabil
3. **Fehlende Werte explizit** - `null` oder strukturierter Status, nicht "nicht verfügbar"
4. **Atomare Platzhalter bevorzugt** - einzelne Felder statt Freitext-Blobs
5. **Zeitbezug immer eindeutig** - `*_7d`, `*_28d`, `*_90d` im Namen
6. **JSON vor Freitext** - strukturierte Objekte für komplexe Daten
7. **Verfügbarkeit trennen** - `*_available` Flags für kritische Felder
8. **Zwei-Stufen-Architektur** - Komplexe Interpretationen via KI statt hardcodiert ⭐ NEU

### Placeholder-Typen (Architektur):

#### Typ 1: Atomic Placeholders
- **Direkt aus Daten** (keine Interpretation)
- Beispiel: `{{weight_aktuell}}`, `{{training_frequency_7d}}`
- Implementierung: Python-Funktion → direkter Wert

#### Typ 2: Raw Data Placeholders
- **Strukturierte JSONs für KI-Input** (keine Interpretation)
- Beispiel: `{{goal_priority_raw_data}}`, `{{constraints_raw_data}}`
- Implementierung: Python aggregiert Rohdaten → JSON
- Verwendung: Input für Basis-Prompts

#### Typ 3: Interpreted Placeholders
- **Von KI generiert** (via Basis-Prompt)
- Beispiel: `{{goal_weighted_priority}}`, `{{main_constraint}}`
- Implementierung: Basis-Prompt interpretiert Raw Data → strukturierter Output
- Verwendung: In übergeordneten Prompts

### Priorisierte Anforderungen (Sprint 1-3):

**Sprint 1 (Must-Have für V1):** 10 Items (P1-P10 + strukturelle)
**Sprint 2 (Diagnose-Ebene):** 7 Items (P21-P27)
**Sprint 3 (Verfeinerung):** 6 Items (niedrigere Priorität)

---

## 0.1 Fit/Gap-Analyse: P1-P27 vs. Aktuelle Datenstruktur

### ✅ Vollständig möglich (mit aktueller Struktur):

#### P1. `goal_summary_json` ✅
- **Datenquelle:** `goals` table (Migration 022)
- **Struktur vorhanden:** id, name, goal_type, status, start_value, target_value, current_value, progress_percentage, target_date, is_primary, focus_contributions
- **Implementierung:** Neue data_layer Funktion `get_goal_summary_data()` → JSON formatieren
- **Aufwand:** 2h (Funktion + Platzhalter)

#### P2. `focus_area_summary_json` ✅
- **Datenquelle:** `focus_area_definitions` + `user_focus_area_weights` + `goal_focus_contributions`
- **Struktur vorhanden:** name, category, user_weight, goal_count, progress per focus area
- **Implementierung:** Neue data_layer Funktion `get_focus_area_summary_data()`
- **Aufwand:** 2h

#### P3-P4. `*_score_available` Flags ✅
- **Datenquelle:** Berechnete Scores
- **Implementierung:** Prüfen ob Score berechnet werden konnte (nicht None)
- **Aufwand:** 1h (alle Score-Platzhalter erweitern)

#### P5. `domain_availability_json` ✅
- **Datenquelle:** Alle Domain-Tabellen (weight_log, nutrition_log, activity_log, sleep_log, etc.)
- **Berechnung:**
  ```python
  {
    "body": {"available": true, "confidence": "high", "last_entry": "2026-03-29", "days_coverage_28d": 25},
    "nutrition": {"available": true, "confidence": "medium", "last_entry": "2026-03-28", "days_coverage_28d": 18},
    "activity": {"available": true, "confidence": "high", "last_entry": "2026-03-29", "days_coverage_28d": 12},
    "sleep": {"available": true, "confidence": "low", "last_entry": "2026-03-15", "days_coverage_28d": 8},
    "vitals": {"available": true, "confidence": "medium", "last_entry": "2026-03-27", "days_coverage_28d": 15},
    "goals": {"available": true, "confidence": "high", "active_goals": 3},
    "focus_areas": {"available": true, "confidence": "high", "weighted_areas": 5}
  }
  ```
- **Implementierung:** Neue Funktion `calculate_domain_availability()`
- **Aufwand:** 3-4h (alle Domains prüfen)

#### P8-P11. Body Change Availability Flags ✅
- **Datenquelle:** `weight_log`, `caliper_log`, `circumference_log`
- **Implementierung:** Prüfen ob genug Datenpunkte für Trend (mind. 2 Messungen, 28d Zeitfenster)
- **Aufwand:** 1h

#### P12. `body_change_summary_json` ✅
- **Datenquelle:** Phase 0c data_layer/body_metrics.py Funktionen
- **Struktur:**
  ```python
  {
    "weight_trend_28d": {"delta_kg": -2.5, "slope": -0.089, "confidence": "high"},
    "fm_change_28d": {"delta_kg": -3.1, "available": true, "confidence": "medium"},
    "lbm_change_28d": {"delta_kg": 0.6, "available": true, "confidence": "medium"},
    "waist_delta_28d": {"delta_cm": -2.5, "available": true},
    "hip_delta_28d": {"delta_cm": -1.2, "available": true},
    "waist_hip_ratio": 0.85,
    "recomposition_quadrant": "fat_loss_muscle_gain"
  }
  ```
- **Implementierung:** Aggregation bestehender Funktionen
- **Aufwand:** 2h

#### P13. `activity_structure_json` ✅
- **Datenquelle:** Phase 0c data_layer/activity_metrics.py Funktionen
- **Struktur:**
  ```python
  {
    "volume_weekly_min": 180,
    "frequency_7d": 4,
    "type_distribution": {"cardio": 45, "strength": 35, "mobility": 10, "recovery": 10},
    "quality_sessions_pct": 75,
    "proxy_load_7d": 450,
    "monotony_score": 1.2,
    "strain_score": 540,
    "rest_day_compliance_pct": 85,
    "patterns": ["cardio-heavy", "good-recovery-compliance"]
  }
  ```
- **Implementierung:** Aggregation bestehender Funktionen
- **Aufwand:** 2h

#### P16. `sleep_summary_json` ✅
- **Datenquelle:** `sleep_log` (Migration 009), Phase 0c recovery_metrics.py
- **Struktur vorhanden:** duration, segments (deep, rem, light, awake)
- **Implementierung:** Neue Funktion `get_sleep_summary_data()`
- **Aufwand:** 2h

#### P17. `recovery_summary_json` ✅
- **Datenquelle:** `vitals_baseline` (RHR, HRV), `sleep_log`, `rest_days`, `activity_log` (load)
- **Struktur:**
  ```python
  {
    "recovery_score": 75,
    "main_drivers": ["good_sleep", "hrv_above_baseline"],
    "rhr_status": "normal",
    "hrv_status": "above_baseline",
    "hrv_vs_baseline_pct": 5.2,
    "rhr_vs_baseline_pct": -3.1,
    "recent_load_interaction": "balanced",
    "confidence": "high"
  }
  ```
- **Implementierung:** Aggregation bestehender recovery_metrics Funktionen
- **Aufwand:** 3h

#### P18. `vitals_summary_json` ✅
- **Datenquelle:** `vitals_baseline` (Migration 015)
- **Struktur vorhanden:** resting_hr, hrv, vo2_max, spo2, respiratory_rate
- **Implementierung:** Neue Funktion `get_vitals_summary_data()`
- **Aufwand:** 1-2h

#### P19-P20. HRV/RHR Availability Flags ✅
- **Datenquelle:** `vitals_baseline`
- **Implementierung:** Prüfen ob Baseline berechnet werden kann (mind. 7 Messungen)
- **Aufwand:** 30min

#### P21. `correlation_summary_json` ✅
- **Datenquelle:** Phase 0c correlations.py Funktionen
- **Struktur:**
  ```python
  {
    "energy_weight_lag": {"best_lag_days": 7, "correlation": 0.68, "confidence": "high"},
    "protein_lbm": {"correlation": 0.52, "confidence": "medium"},
    "load_hrv_lag": {"best_lag_days": 3, "correlation": -0.45, "confidence": "medium"},
    "load_rhr_lag": {"best_lag_days": 2, "correlation": 0.38, "confidence": "low"},
    "sleep_recovery": {"correlation": 0.61, "confidence": "high"}
  }
  ```
- **Implementierung:** Aggregation bestehender Korrelationsfunktionen
- **Aufwand:** 2h

#### P22-P24. Plateau & Drivers ✅
- **Datenquelle:** Phase 0c correlations.py (`detect_plateau_periods()`, `identify_top_drivers()`)
- **Struktur:**
  ```python
  {
    "plateau_status": "likely",  # likely / possible / not_detected / insufficient_data
    "plateau_detected_at": "2026-03-15",
    "plateau_duration_days": 14,
    "top_drivers_positive": [
      {"driver": "protein_adequacy", "impact_score": 0.72},
      {"driver": "sleep_quality", "impact_score": 0.65}
    ],
    "top_drivers_negative": [
      {"driver": "training_monotony", "impact_score": -0.58},
      {"driver": "insufficient_strength_volume", "impact_score": -0.42}
    ],
    "confidence": "medium"
  }
  ```
- **Implementierung:** Wrapper um bestehende Funktionen + Klassifikation
- **Aufwand:** 2-3h

#### P25-P27. Underfueling Risk ✅
- **Datenquelle:** `nutrition_log` (kcal), `activity_log` (kcal_active), `weight_log` (trend)
- **Berechnung:**
  ```python
  # Energy Availability = (intake - training_expenditure) / lean_body_mass
  # RED-S Risk: EA < 30 kcal/kg LBM/day
  {
    "underfueling_risk_flag": true,
    "underfueling_risk_reason": "ea_below_threshold",
    "energy_availability_summary": {
      "intake_avg_7d": 1800,
      "training_expenditure_avg_7d": 600,
      "net_availability": 1200,
      "ea_per_kg_lbm": 25.5,  # kcal/kg/day
      "deficit_magnitude": "moderate",
      "load_context": "high",
      "recovery_context": "impaired",
      "warning_level": "high",
      "confidence": "medium"
    }
  }
  ```
- **Implementierung:** Neue Funktion `calculate_energy_availability()`
- **Aufwand:** 3-4h (RED-S Logik komplex)

---

### ⚠️ Teilweise möglich (braucht Erweiterung):

#### P7. `critical_missing_fields_json` ⚠️
- **Problem:** Braucht Meta-Tracking welche Felder wann erfasst wurden
- **Was fehlt:** Keine Tabelle die "expected fields" vs. "captured fields" trackt
- **Lösung:** Heuristik basierend auf entry counts pro Domain
- **Beispiel:**
  ```python
  {
    "critical_missing": [
      {"field": "body_fat_measurements", "last_entry": "2026-02-15", "days_ago": 42, "impact": "high"},
      {"field": "hrv_measurements", "last_entry": null, "days_ago": null, "impact": "medium"},
      {"field": "sleep_tracking", "coverage_28d": 8, "expected": 28, "impact": "medium"}
    ],
    "recommendation_priority": ["body_fat_measurements", "hrv_measurements", "sleep_tracking"]
  }
  ```
- **Aufwand:** 3h (Heuristik-Logik)

#### P14. `training_quality_score` ⚠️
- **Was existiert:** `quality_label` per Activity, `quality_sessions_pct` Platzhalter
- **Was fehlt:** Aggregierter Quality-Score über alle Sessions (gewichtet)
- **Berechnung:**
  ```python
  # Weighted average: excellent=100, good=80, acceptable=60, poor=30, excluded=0
  quality_score = sum(quality_weight × duration) / total_duration
  ```
- **Aufwand:** 1h

#### P15. `load_balance_class` ⚠️
- **Was existiert:** `proxy_internal_load_7d` Platzhalter
- **Was fehlt:** Klassifikation in low/moderate/high/strained
- **Berechnung:**
  ```python
  if load < 300: "low"
  elif load < 600: "moderate"
  elif load < 900: "high"
  else: "strained"
  ```
- **Aufwand:** 30min

---

### ✅ Möglich mit Zwei-Stufen-Architektur (Data + KI Interpretation):

#### P31. `goal_weighted_priority` ✅ (2-Stufen)
- **Was existiert:** Goals + Focus Areas + Priorisierungssystem
- **Architektur:**
  - **Stufe 1 (Data Layer):** `get_goal_priority_raw_data()` → strukturiertes JSON
    ```python
    {
      "goals": [
        {
          "id": 1,
          "name": "Gewichtsverlust 85kg",
          "progress_pct": 42,
          "behind_schedule_days": 5,
          "focus_contributions": [
            {"focus_area": "Körpergewicht", "weight": 40}
          ],
          "total_focus_weight": 75
        }
      ],
      "focus_area_weights": {"Körper": 75, "Aktivität": 20},
      "context": {...}
    }
    ```
  - **Stufe 2 (KI-Prompt):** Basis-Prompt "Goal Priority Interpreter" interpretiert Rohdaten
    - Input: `{{goal_priority_raw_data}}`
    - Output: `{{goal_weighted_priority}}` (strukturiertes JSON mit Prioritäten + Rationale)
- **Aufwand:** 3h (2h Data Layer + 1h Basis-Prompt)

#### P32. `main_constraint` ✅ (2-Stufen)
- **Was existiert:** Activity patterns, frequency, gaps
- **Architektur:**
  - **Stufe 1:** `get_constraints_raw_data()` → JSON
    ```python
    {
      "time_budget": {
        "avg_sessions_per_week": 3.2,
        "longest_gap_days": 4,
        "typical_session_duration_min": 45
      },
      "activity_patterns": {
        "weekday_sessions": 2.5,
        "weekend_sessions": 0.7
      },
      "missing_categories": ["mobility", "recovery"],
      "data_gaps": {...}
    }
    ```
  - **Stufe 2:** Basis-Prompt "Constraint Identifier"
    - Input: `{{constraints_raw_data}}`
    - Output: `{{main_constraint}}` (Haupteinschränkung + Typ)
- **Aufwand:** 2-3h (2h Data Layer + 1h Basis-Prompt)

#### P33. `main_strength` ✅ (2-Stufen)
- **Was existiert:** Tracking compliance, consistency scores, quality metrics
- **Architektur:**
  - **Stufe 1:** `get_strengths_raw_data()` → JSON
    ```python
    {
      "tracking_compliance": {
        "weight_entries_28d": 28,
        "nutrition_entries_28d": 26,
        "activity_entries_28d": 12
      },
      "consistency_scores": {
        "macro_consistency": 85,
        "training_frequency_stability": 92
      },
      "quality_metrics": {
        "quality_sessions_pct": 78,
        "sleep_regularity": 0.85
      },
      "standout_values": [
        {"metric": "protein_adequacy", "value": 95, "percentile": "top_10"}
      ]
    }
    ```
  - **Stufe 2:** Basis-Prompt "Strength Identifier"
    - Input: `{{strengths_raw_data}}`
    - Output: `{{main_strength}}` (Hauptstärke + Begründung)
- **Aufwand:** 2-3h (2h Data Layer + 1h Basis-Prompt)

#### P34. `next_best_actions` ⚠️ (2-Stufen, teilweise)
- **Was existiert:** Gaps, low scores, fehlende Kategorien
- **Architektur:**
  - **Stufe 1:** `get_improvement_opportunities_raw_data()` → JSON
    ```python
    {
      "gaps": [
        {"domain": "activity", "gap": "no_strength_training_7d", "severity": "high"},
        {"domain": "nutrition", "gap": "protein_below_target", "severity": "medium"}
      ],
      "low_scores": [
        {"metric": "mobility_sessions_28d", "value": 0, "target": 4}
      ],
      "quick_wins": [
        {"opportunity": "add_1_strength_session", "effort": "low", "expected_impact": "medium"}
      ],
      "high_impact": [
        {"opportunity": "increase_protein_20g", "effort": "medium", "expected_impact": "high"}
      ]
    }
    ```
  - **Stufe 2:** Basis-Prompt "Action Recommender"
    - Input: `{{improvement_opportunities_raw_data}}`
    - Output: `{{next_best_actions}}` (Top 3 Actions mit Begründung)
- **Problem:** Braucht domänenspezifisches Wissen (z.B. welche Proteinmenge sinnvoll)
- **Aufwand:** 3-5h (3h Data Layer + 2h Basis-Prompt mit Domänen-Wissen)

---

### ❌ Nicht möglich / Redundant:

#### P6. `domain_confidence_json` ❌ REDUNDANT
- **Problem:** Überschneidung mit P5 `domain_availability_json`
- **Lösung:** In P5 integrieren (bereits confidence per domain)
- **Aufwand:** 0h

#### P30. `blood_pressure_summary_json` ⚠️ OPTIONAL (Sprint 3)
- **Was existiert:** `blood_pressure_log` table (Migration 015)
- **Was fehlt:** Aggregationsfunktion für BP summary
- **Berechnung:**
  ```python
  {
    "mean_systolic_28d": 125,
    "mean_diastolic_28d": 82,
    "category": "elevated",  # WHO/ISH classification
    "contexts": {"nüchtern": 15, "nach_essen": 8, "nach_training": 5},
    "trend_28d": "stable",
    "irregularity_count": 2,
    "afib_detected": false,
    "confidence": "high"
  }
  ```
- **Aufwand:** 2h (neue data_layer Funktion)
- **Empfehlung:** Sprint 3 (niedrigere Priorität als P31-P34)

---

### 📊 Zusammenfassung Fit/Gap (aktualisiert):

| Kategorie | Anzahl | Aufwand | Details |
|-----------|--------|---------|---------|
| ✅ Vollständig möglich (direkt) | 20 Items | 35-40h | P1-P5, P8-P13, P16-P27 |
| ✅ Möglich (2-Stufen-Architektur) | 4 Items | 10-14h | P31-P34 (Data Layer + KI) |
| ⚠️ Teilweise möglich | 3 Items | 4-5h | P7, P14, P15 |
| ❌ Redundant / Optional | 2 Items | 2h | P6 (redundant), P30 (optional) |
| **TOTAL MÖGLICH** | **27 Items** | **49-59h** | **Alle User Requirements umsetzbar!** |

**Architektur-Verbesserung durch 2-Stufen-Ansatz:**
- ✅ **P31-P34 von "nicht möglich" → "möglich"** durch intelligente Architektur
- ✅ **Gleicher Aufwand** wie ursprünglich geschätzt (10-14h)
- ✅ **Bessere Qualität:** Flexibler, wartbarer, erweiterbarer
- ✅ **Nutzt bestehendes System:** Unified Prompt System + Basis-Prompts

---

## 0.2 Governance-Implementierung

### Konkrete Maßnahmen für Governance-Regeln:

#### G1-G2: API-Stabilität & Keine Semantikänderungen
**Maßnahme:** Placeholder Versioning System einführen
```python
PLACEHOLDER_MAP_V1 = {
    '{{weight_aktuell}}': {
        'resolver': get_latest_weight,
        'version': '1.0.0',
        'semantic': 'latest weight entry, no averaging',
        'unit': 'kg',
        'timeframe': 'latest',
        'fallback': 'nicht verfügbar'
    },
    # ...
}
```
**Aufwand:** 3h (Metadata-System + alle Platzhalter dokumentieren)

#### G3: Fehlende Werte explizit
**Maßnahme 1:** Alle "nicht verfügbar" Strings durch `null` ersetzen
**Maßnahme 2:** Neue Platzhalter mit `*_available` Flags
```python
'{{goal_progress_score}}': 75,
'{{goal_progress_score_available}}': true,
'{{goal_progress_score_reason}}': null  # or "insufficient_goals"
```
**Aufwand:** 2h (alle betroffenen Platzhalter umstellen)

#### G4: JSON vor Freitext
**Maßnahme:** Alle Summary-Felder erhalten strukturierte JSON-Pendants
- `{{activity_summary}}` bleibt → + `{{activity_structure_json}}`
- `{{caliper_summary}}` bleibt → + `{{body_change_summary_json}}`
**Aufwand:** Bereits in P1-P27 enthalten

#### G5: Zeitfenster im Namen
**Maßnahme:** Alle zeitabhängigen Platzhalter prüfen und ggf. umbenennen
```python
# ❌ Unklar:
'{{weight_trend}}'  # 7d? 28d? 90d?

# ✅ Klar:
'{{weight_trend_28d}}'
'{{weight_slope_28d}}'
```
**Aufwand:** 2h (Audit + Renaming + Migration)

#### G6: Verfügbarkeit trennen
**Maßnahme:** Systematisch alle kritischen Platzhalter mit Flags ergänzen
- Body: `{{fm_28d_change_available}}`, `{{lbm_28d_change_available}}`, etc.
- Vitals: `{{hrv_vs_baseline_available}}`, `{{rhr_vs_baseline_available}}`
- Goals: `{{goal_progress_score_available}}`
**Aufwand:** Bereits in P3-P4, P8-P11, P19-P20 enthalten

#### G7: Keine Ad-hoc-Platzhalter
**Maßnahme:** Placeholder Approval Process einführen
1. Neuer Platzhalter → Request in PHASE_0B_IMPROVEMENTS.md
2. Bewertung gegen Governance-Regeln
3. Implementierung nur nach Approval
4. Dokumentation in placeholder_catalog aktualisieren
**Aufwand:** 1h (Process-Dokumentation)

#### G8: Zwei-Stufen-Architektur für komplexe Interpretationen ⭐ NEU
**Maßnahme:** Komplexe Logik NICHT hardcoded, sondern via KI-Interpretation

**Wann Zwei-Stufen-Ansatz nutzen:**
- Interpretation braucht Kontext-Verständnis
- Logik ist nicht eindeutig regelbasiert
- Flexibilität wichtiger als Performance
- Domänen-Wissen erforderlich

**Implementierungs-Pattern:**
1. **Data Layer:** `get_<topic>_raw_data()` → strukturiertes JSON (Typ 2 Placeholder)
2. **Basis-Prompt:** Interpretiert Rohdaten → strukturierter Output (Typ 3 Placeholder)
3. **Verwendung:** Übergeordnete Prompts nutzen Typ 3 Placeholder

**Beispiel:**
```python
# Data Layer (Python)
def get_goal_priority_raw_data(profile_id):
    return {
        "goals": [...],
        "focus_weights": {...},
        "context": {...}
    }

# Platzhalter Typ 2 (Raw Data)
'{{goal_priority_raw_data}}': lambda pid: json.dumps(get_goal_priority_raw_data(pid))

# Basis-Prompt (KI)
Name: "Goal Priority Interpreter"
Input: {{goal_priority_raw_data}}
Output: JSON mit priority_ranking

# Platzhalter Typ 3 (Interpreted)
'{{goal_weighted_priority}}': <von KI generiert via Basis-Prompt>
```

**Aufwand:** 0h (bereits in P31-P34 enthalten)

**Vorteile:**
- ✅ Flexibler: Prompt-Änderung ohne Code-Deploy
- ✅ Wartbarer: Klare Trennung Data vs. Interpretation
- ✅ Erweiterbarer: Gleiche Rohdaten für mehrere Prompts nutzbar
- ✅ Testbarer: Rohdaten-Struktur separat testbar

---

## 0.3 Sprint-Planung (User Requirements integriert)

### Sprint 1: Must-Have für V1 (20 Items, 35-40h)

**Governance & Infrastructure (8h):**
1. Placeholder Versioning System (3h)
2. "nicht verfügbar" → null Migration (2h)
3. Zeitfenster-Audit & Renaming (2h)
4. Approval Process Dokumentation (1h)

**Strukturierte JSONs (15-18h):**
- P1: goal_summary_json (2h)
- P2: focus_area_summary_json (2h)
- P5: domain_availability_json (3-4h)
- P12: body_change_summary_json (2h)
- P13: activity_structure_json (2h)
- P16: sleep_summary_json (2h)
- P17: recovery_summary_json (3h)
- P18: vitals_summary_json (1-2h)

**Availability Flags (3h):**
- P3-P4: Score availability flags (1h)
- P8-P11: Body change availability (1h)
- P19-P20: HRV/RHR availability (30min)
- P7: critical_missing_fields_json (3h) - teilweise

**Diagnose & Correlation (5-6h):**
- P21: correlation_summary_json (2h)
- P22-P24: plateau_status + drivers (2-3h)
- P14: training_quality_score (1h) - teilweise
- P15: load_balance_class (30min) - teilweise

**Energy Availability (3-4h):**
- P25-P27: underfueling risk + energy_availability_summary (3-4h)

**Sprint 1 Gesamt:** 34-41h

---

### Sprint 2: Quality Label + Training Categories (16-19h + 10-13h = 26-32h)

**Quality Label Gap (bereits definiert in Sektion 7):**
- Quality-Filter in activity_metrics.py (6-8h)
- Evaluation-Breakdown (1h)
- Placeholder-Updates (2h)
- Dedizierte Quality-Platzhalter (2h)
- Poor Sessions Warning (1h)

**Training Categories Gap (bereits definiert in Sektion 7):**
- Category-Specific Metrics (2h)
- Kategorie-spezifische Platzhalter (3h)
- Days Since Last Training (2h)
- Training Balance Calculator (2-3h)
- Weitere Kategorie-Platzhalter (2h)
- Subcategory Distribution (3h)

**Sprint 2 Gesamt:** 26-32h

---

### Sprint 3: Zwei-Stufen-Platzhalter + Optional (10-16h)

**P31-P34: Zwei-Stufen-Architektur (10-14h):**
- P31: goal_weighted_priority (3h) - Data Layer + Basis-Prompt
- P32: main_constraint (2-3h) - Data Layer + Basis-Prompt
- P33: main_strength (2-3h) - Data Layer + Basis-Prompt
- P34: next_best_actions (3-5h) - Data Layer + Basis-Prompt (komplex)

**Optional (falls gewünscht, 2h):**
- P30: blood_pressure_summary_json (2h)

**Sprint 3 Gesamt:** 12-16h

**Besonderheit Sprint 3:**
- Nutzt Unified Prompt System für KI-Interpretation
- Basis-Prompts sind wiederverwendbar
- Flexibler als hardcodierte Logik
- Kann iterativ verfeinert werden (Prompt-Änderung ohne Code-Deploy)

---

### Gesamtaufwand (alle 3 Sprints):

| Sprint | Inhalt | Aufwand |
|--------|--------|---------|
| Sprint 1 | User Requirements P1-P27 + Governance | 34-41h |
| Sprint 2 | Quality Label + Training Categories | 26-32h |
| Sprint 3 | Blood Pressure + Goal-Weighted (optional) | 12-16h |
| **TOTAL** | **Alle Requirements + Beide Gaps** | **72-89h** |

---

## 1. Fehlende Platzhalter

### Kategorie: Körper (Body Metrics)

#### `{{placeholder_name}}`
- **Zweck:** Wofür wird der Wert benötigt?
- **Datenquelle:** Tabelle/Funktion (z.B. `weight_log`, `body_metrics.py`)
- **Berechnung:** Wie soll er ermittelt werden?
- **Format:** Beispiel-Output (z.B. "4.5 kg", "85%", "nicht verfügbar")
- **Use Case:** In welchem Prompt wird das benötigt?

---

### Kategorie: Ernährung (Nutrition)

#### `{{placeholder_name}}`
- **Zweck:**
- **Datenquelle:**
- **Berechnung:**
- **Format:**
- **Use Case:**

---

### Kategorie: Training / Aktivität

#### `{{activity_summary_acceptable_plus}}`
- **Zweck:** Aktivitäts-Zusammenfassung nur mit mindestens "acceptable" Qualität
- **Datenquelle:** `activity_log` WHERE quality_label IN ('excellent', 'good', 'acceptable')
- **Berechnung:** Wie aktuelles `{{activity_summary}}`, aber mit quality_filter
- **Format:** "8 Einheiten in 14 Tagen (Ø 45 min/Einheit, 2400 kcal gesamt)"
- **Use Case:** Standard-Auswertungen, die nur valide Trainings berücksichtigen

#### `{{activity_summary_excellent}}`
- **Zweck:** Aktivitäts-Zusammenfassung nur mit "excellent" Qualität
- **Datenquelle:** `activity_log` WHERE quality_label = 'excellent'
- **Berechnung:** Wie aktuelles `{{activity_summary}}`, aber nur excellent
- **Format:** "3 Einheiten in 14 Tagen (Ø 60 min/Einheit, 1200 kcal gesamt)"
- **Use Case:** Analyse von Top-Trainings, Benchmark für Qualität

#### `{{poor_sessions_count}}`
- **Zweck:** Anzahl schlechter/ausgeschlossener Trainings
- **Datenquelle:** `activity_log` WHERE quality_label IN ('poor', 'excluded')
- **Berechnung:** COUNT(*) der poor/excluded sessions (7d oder 28d)
- **Format:** "2 Sessions" oder "keine schlechten Sessions"
- **Use Case:** Warnung bei zu vielen schlechten Trainings

#### `{{evaluation_breakdown}}`
- **Zweck:** Verteilung der Trainings nach Evaluation-Stufen
- **Datenquelle:** `activity_log` GROUP BY quality_label
- **Berechnung:** COUNT(*) pro quality_label mit Prozentangaben
- **Format:** "Excellent: 3 (25%), Good: 5 (42%), Acceptable: 3 (25%), Poor: 1 (8%)"
- **Use Case:** Qualitäts-Übersicht in Coaching-Prompts

#### `{{training_minutes_quality}}`
- **Zweck:** Trainingsminuten nur mit acceptable+ Qualität
- **Datenquelle:** `activity_log` WHERE quality_label IN ('excellent', 'good', 'acceptable')
- **Berechnung:** SUM(duration_min) mit quality_filter (7d)
- **Format:** "180 Minuten" (nur valide Trainings)
- **Use Case:** WHO-Empfehlung Vergleich (150-300 min/Woche)

---

### Kategorie: Training / Aktivität - Trainingstyp-spezifisch ⚠️ NEU

#### `{{strength_training_count_7d}}`
- **Zweck:** Anzahl Krafttrainings in letzten 7 Tagen
- **Datenquelle:** `activity_log` WHERE training_category = 'strength'
- **Berechnung:** COUNT(*) mit quality='quality' filter (7d)
- **Format:** "3 Einheiten" oder "keine Krafttrainings"
- **Use Case:** Muskelerhalt-Check (mind. 2x/Woche empfohlen)

#### `{{strength_training_minutes_7d}}`
- **Zweck:** Trainingsminuten Kraft in letzten 7 Tagen
- **Datenquelle:** `activity_log` WHERE training_category = 'strength'
- **Berechnung:** SUM(duration_min) mit quality='quality' filter (7d)
- **Format:** "135 Minuten" oder "0 Minuten Krafttraining"
- **Use Case:** Volumen-Check für Muskelerhalt

#### `{{cardio_training_count_7d}}`
- **Zweck:** Anzahl Cardio-Trainings in letzten 7 Tagen
- **Datenquelle:** `activity_log` WHERE training_category = 'cardio'
- **Berechnung:** COUNT(*) mit quality='quality' filter (7d)
- **Format:** "4 Einheiten"
- **Use Case:** WHO-Empfehlung (3-5x/Woche Cardio)

#### `{{cardio_training_minutes_7d}}`
- **Zweck:** Trainingsminuten Cardio in letzten 7 Tagen
- **Datenquelle:** `activity_log` WHERE training_category = 'cardio'
- **Berechnung:** SUM(duration_min) mit quality='quality' filter (7d)
- **Format:** "180 Minuten"
- **Use Case:** WHO-Empfehlung (150-300 min/Woche)

#### `{{martial_arts_frequency_28d}}`
- **Zweck:** Kampfsport-Frequenz (Sessions/Woche durchschnittlich über 28d)
- **Datenquelle:** `activity_log` WHERE training_category = 'martial_arts'
- **Berechnung:** COUNT(*) / 4 Wochen
- **Format:** "2.5 Einheiten/Woche" oder "kein Kampfsport in 28 Tagen"
- **Use Case:** Kampfsport-spezifisches Coaching

#### `{{recovery_sessions_count_28d}}`
- **Zweck:** Anzahl aktiver Erholungseinheiten
- **Datenquelle:** `activity_log` WHERE training_category = 'recovery'
- **Berechnung:** COUNT(*) (28d)
- **Format:** "3 Erholungseinheiten"
- **Use Case:** Regenerations-Balance prüfen

#### `{{mobility_sessions_count_28d}}`
- **Zweck:** Anzahl Mobility/Dehnung Sessions
- **Datenquelle:** `activity_log` WHERE training_category = 'mobility'
- **Berechnung:** COUNT(*) (28d)
- **Format:** "2 Mobility-Einheiten" oder "keine Mobility-Trainings"
- **Use Case:** Mobility-Warnung bei 0 Sessions

#### `{{days_since_last_strength}}`
- **Zweck:** Tage seit letzter Krafteinheit
- **Datenquelle:** `activity_log` WHERE training_category = 'strength'
- **Berechnung:** CURRENT_DATE - MAX(date)
- **Format:** "2 Tage" oder ">7 Tage (kritisch!)"
- **Use Case:** Ruhepausen-Check / Muskelerhalt-Warnung

#### `{{days_since_last_cardio}}`
- **Zweck:** Tage seit letzter Cardio-Einheit
- **Datenquelle:** `activity_log` WHERE training_category = 'cardio'
- **Berechnung:** CURRENT_DATE - MAX(date)
- **Format:** "1 Tag" oder ">5 Tage"
- **Use Case:** Ausdauer-Kontinuität prüfen

#### `{{days_since_last_martial_arts}}`
- **Zweck:** Tage seit letzter Kampfsport-Einheit
- **Datenquelle:** `activity_log` WHERE training_category = 'martial_arts'
- **Berechnung:** CURRENT_DATE - MAX(date)
- **Format:** "3 Tage" oder ">14 Tage"
- **Use Case:** Technik-Kontinuität prüfen

#### `{{cardio_to_strength_ratio}}`
- **Zweck:** Verhältnis Cardio zu Kraft (Minuten-basiert, 28d)
- **Datenquelle:** `activity_log` WHERE training_category IN ('cardio', 'strength')
- **Berechnung:** cardio_minutes / strength_minutes
- **Format:** "3:1 (cardio-lastig)" oder "1:2 (kraft-lastig)" oder "balanced"
- **Use Case:** Balance-Coaching

#### `{{training_balance_score}}`
- **Zweck:** Balance-Score 0-100 basierend auf Kategorie-Verteilung
- **Datenquelle:** `activity_log` (alle Kategorien)
- **Berechnung:** Score = 100 - std_dev(category_percentages) × 2
- **Format:** "75" (Zahl 0-100)
- **Use Case:** Gesamtbalance bewerten

#### `{{missing_training_categories}}`
- **Zweck:** Liste fehlender Trainings-Kategorien (28d)
- **Datenquelle:** `activity_log` (alle Kategorien)
- **Berechnung:** Vergleich [cardio, strength, mobility, recovery] mit tatsächlichen
- **Format:** "Fehlt: Mobility, Recovery" oder "Alle Kategorien abgedeckt"
- **Use Case:** Lücken-Identifikation

#### `{{strength_frequency_adequate}}`
- **Zweck:** Ja/Nein Check für Muskelerhalt (mind. 2x/Woche Kraft)
- **Datenquelle:** `activity_log` WHERE training_category = 'strength'
- **Berechnung:** COUNT(*) >= 2 in 7d?
- **Format:** "Ja" oder "Nein (nur 1x Kraft/Woche - Risiko Muskelabbau)"
- **Use Case:** Direkter Muskelerhalt-Check

#### `{{muscle_preservation_risk}}`
- **Zweck:** Warnung bei zu wenig Krafttraining
- **Datenquelle:** `activity_log` WHERE training_category = 'strength'
- **Berechnung:** IF strength_count_7d < 2 THEN "Risiko: nur Xx Kraft"
- **Format:** "Kein Risiko" oder "Risiko: nur 1x Kraft in 7d"
- **Use Case:** Explizite Warnung für KI-Prompt

#### `{{strength_type_distribution}}`
- **Zweck:** Verteilung innerhalb Krafttraining (Subcategories)
- **Datenquelle:** `activity_log` JOIN `training_types` WHERE category = 'strength'
- **Berechnung:** COUNT(*) per subcategory (hypertrophy, maxstrength, endurance)
- **Format:** "Hypertrophie: 60%, Maximalkraft: 30%, Kraftausdauer: 10%"
- **Use Case:** Periodisierungs-Analyse

#### `{{hypertrophy_vs_maxstrength_ratio}}`
- **Zweck:** Verhältnis Hypertrophie zu Maximalkraft
- **Datenquelle:** `activity_log` WHERE subcategory IN ('hypertrophy', 'maxstrength')
- **Berechnung:** hypertrophy_count / maxstrength_count (28d)
- **Format:** "3:1" oder "nur Hypertrophie" oder "nur Maximalkraft"
- **Use Case:** Kraft-Periodisierungs-Check

#### `{{technique_vs_sparring_balance}}`
- **Zweck:** Technik vs. Kampf im Kampfsport (Subcategories)
- **Datenquelle:** `activity_log` WHERE subcategory IN ('technique', 'sparring')
- **Berechnung:** Verhältnis technique / sparring (28d)
- **Format:** "2:1 (technik-lastig)" oder "balanced"
- **Use Case:** Kampfsport-spezifisches Coaching

---

### Kategorie: Erholung / Vitalwerte

#### `{{placeholder_name}}`
- **Zweck:**
- **Datenquelle:**
- **Berechnung:**
- **Format:**
- **Use Case:**

---

### Kategorie: Ziele (Goals)

#### `{{placeholder_name}}`
- **Zweck:**
- **Datenquelle:**
- **Berechnung:**
- **Format:**
- **Use Case:**

---

### Kategorie: Korrelationen

#### `{{placeholder_name}}`
- **Zweck:**
- **Datenquelle:**
- **Berechnung:**
- **Format:**
- **Use Case:**

---

## 2. Verbesserungspotenziale bei existierenden Platzhaltern

### `{{activity_summary}}` ⚠️ KRITISCH
- **Aktuelles Verhalten:** Zeigt ALLE Aktivitäten ohne Rücksicht auf quality_label
- **Problem:** Schlechte/ausgeschlossene Trainings werden mitgezählt → verfälscht Auswertungen
- **Vorschlag:**
  - **Option A:** Default auf quality='acceptable_plus' ändern (Breaking Change)
  - **Option B:** Neuen Parameter `quality_level` hinzufügen, default='all' (Non-Breaking)
  - **Option C:** Neuer Platzhalter `{{activity_summary_quality}}`, alter bleibt (Redundanz)
- **Breaking Change:** Ja (Option A), Nein (Option B+C)
- **Use Case:** ALLE Standard-Coaching-Prompts sollten nur valide Trainings nutzen

### `{{activity_detail}}` ⚠️ KRITISCH
- **Aktuelles Verhalten:** Listet ALLE Aktivitäten ohne quality_label Berücksichtigung
- **Problem:** Schlechte Trainings erscheinen in Detail-Liste ohne Kennzeichnung
- **Vorschlag:**
  - Entweder quality_filter hinzufügen (nur acceptable+)
  - Oder quality_label als Badge in Output aufnehmen: "30.03. Laufen (60 min) [excellent]"
- **Breaking Change:** Teilweise (Format-Änderung)
- **Use Case:** Detail-Analyse sollte Qualität pro Training zeigen

### `{{trainingstyp_verteilung}}` ⚠️
- **Aktuelles Verhalten:** Zeigt Verteilung ALLER Trainingstypen
- **Problem:** Schlechte Sessions werden in Kategorie-Statistik mitgezählt
- **Vorschlag:** quality_filter auf acceptable+ anwenden
- **Breaking Change:** Ja (Zahlen ändern sich)
- **Use Case:** Verteilung sollte nur valide Trainings zeigen

### `{{training_minutes_week}}` ⚠️
- **Aktuelles Verhalten:** Summiert ALLE Trainingsminuten
- **Problem:** Schlechte Trainings werden voll gezählt
- **Vorschlag:**
  - Nur acceptable+ Trainings zählen
  - Oder: quality_weighted sum (excellent=1.0, good=0.95, acceptable=0.85, poor=0.5)
- **Breaking Change:** Ja
- **Use Case:** WHO-Empfehlung sollte nur valide Minuten berücksichtigen

### `{{training_frequency_7d}}` ⚠️
- **Aktuelles Verhalten:** Zählt ALLE Sessions
- **Problem:** Poor/excluded sessions werden mitgezählt
- **Vorschlag:** Nur acceptable+ Sessions zählen
- **Breaking Change:** Ja
- **Use Case:** Frequenz-Statistik sollte nur valide Trainings zählen

### `{{ability_balance_*}}` ⚠️
- **Aktuelles Verhalten:** Berechnet Balance aus ALLEN Activities
- **Problem:** Schlechte Trainings beeinflussen Ability-Balance
- **Vorschlag:** Nur acceptable+ Activities für Berechnung nutzen
- **Breaking Change:** Ja (Balance-Scores ändern sich)
- **Use Case:** Balance-Berechnung sollte nur valide Trainings nutzen

### `{{proxy_internal_load_7d}}` ℹ️ TEILWEISE KORREKT
- **Aktuelles Verhalten:** Nutzt quality_label als Gewichtungsfaktor (excellent=1.15, poor=0.75)
- **Problem:** Lädt ALLE Activities, gewichtet sie dann runter - aber poor sollte gar nicht gezählt werden
- **Vorschlag:** Filter auf acceptable+ PLUS quality-Gewichtung
- **Breaking Change:** Teilweise
- **Use Case:** Load-Monitoring sollte nur valide Trainings berücksichtigen

---

## 3. Neue Berechnungslogik / Funktionen

### Feature: Quality-Aware Activity Metrics
- **Beschreibung:** Alle activity_metrics Funktionen erhalten quality_level Parameter
- **Input:**
  - `profile_id: str`
  - `days: int`
  - `quality_level: str = 'quality'` (new parameter)
- **Output:** Wie bisher, aber gefiltert nach quality_level
- **Algorithmus:**
  ```python
  from quality_filter import get_quality_filter_sql

  def get_activity_summary_data(profile_id, days=14, quality_level='quality'):
      profile = get_profile_data(profile_id)
      profile['quality_filter_level'] = quality_level

      quality_sql = get_quality_filter_sql(profile)  # Returns "AND quality_label IN (...)"

      query = f"""
          SELECT COUNT(*) as count, ...
          FROM activity_log
          WHERE profile_id=%s AND date >= %s
          {quality_sql}
      """
  ```
- **Modul:** `backend/data_layer/activity_metrics.py` (alle Funktionen)
- **Dependencies:**
  - `quality_filter.py` (bereits vorhanden)
  - `get_profile_data()` für quality_filter_level

### Feature: Evaluation Breakdown Calculator
- **Beschreibung:** Berechnet Verteilung nach quality_label für Zeitraum
- **Input:** `profile_id: str`, `days: int = 28`
- **Output:**
  ```python
  {
      "excellent": {"count": 3, "percentage": 25, "minutes": 180},
      "good": {"count": 5, "percentage": 42, "minutes": 225},
      "acceptable": {"count": 3, "percentage": 25, "minutes": 90},
      "poor": {"count": 1, "percentage": 8, "minutes": 30},
      "excluded": {"count": 0, "percentage": 0, "minutes": 0},
      "total": 12,
      "confidence": "high"
  }
  ```
- **Algorithmus:**
  ```sql
  SELECT quality_label,
         COUNT(*) as count,
         SUM(duration_min) as minutes
  FROM activity_log
  WHERE profile_id = %s
    AND date >= CURRENT_DATE - INTERVAL '%s days'
  GROUP BY quality_label
  ```
- **Modul:** `backend/data_layer/activity_metrics.py` (neue Funktion)
- **Dependencies:** Keine

### Feature: Category-Specific Activity Metrics
- **Beschreibung:** Count/Minutes pro Trainings-Kategorie
- **Input:** `profile_id: str`, `category: str`, `days: int = 7`, `quality_level: str = 'quality'`
- **Output:**
  ```python
  {
      "category": "strength",
      "count": 3,
      "total_minutes": 135,
      "avg_minutes_per_session": 45,
      "sessions_per_week": 3.0,
      "percentage_of_total": 35.0,  # 35% aller Trainings
      "confidence": "high",
      "days_analyzed": 7
  }
  ```
- **Algorithmus:**
  ```python
  def get_category_activity_data(profile_id, category, days=7, quality_level='quality'):
      profile = get_profile_data(profile_id)
      profile['quality_filter_level'] = quality_level
      quality_sql = get_quality_filter_sql(profile)

      query = f"""
          SELECT COUNT(*) as count,
                 SUM(duration_min) as total_minutes
          FROM activity_log
          WHERE profile_id = %s
            AND training_category = %s
            AND date >= CURRENT_DATE - INTERVAL '%s days'
            {quality_sql}
      """
      # Calculate derived metrics...
  ```
- **Modul:** `backend/data_layer/activity_metrics.py` (neue Funktion)
- **Dependencies:** quality_filter.py

### Feature: Days Since Last Training (per Category)
- **Beschreibung:** Tage seit letzter Einheit einer bestimmten Kategorie
- **Input:** `profile_id: str`, `category: str`, `quality_level: str = 'quality'`
- **Output:**
  ```python
  {
      "category": "strength",
      "days_since_last": 2,
      "last_date": "2026-03-27",
      "status": "ok",  # ok / warning / critical
      "recommendation": "Nächste Einheit in 1-2 Tagen empfohlen",
      "confidence": "high"
  }
  ```
- **Algorithmus:**
  ```sql
  SELECT MAX(date) as last_date
  FROM activity_log
  WHERE profile_id = %s
    AND training_category = %s
    AND quality_label IN ('excellent', 'good', 'acceptable')
  ```
  ```python
  days_since = (datetime.now().date() - last_date).days

  # Status logic (category-specific thresholds)
  if category == 'strength':
      status = 'critical' if days_since > 7 else 'warning' if days_since > 3 else 'ok'
  elif category == 'cardio':
      status = 'critical' if days_since > 5 else 'warning' if days_since > 2 else 'ok'
  # etc.
  ```
- **Modul:** `backend/data_layer/activity_metrics.py` (neue Funktion)
- **Dependencies:** quality_filter.py

### Feature: Training Category Balance Calculator
- **Beschreibung:** Berechnet Balance-Score basierend auf Verteilung
- **Input:** `profile_id: str`, `days: int = 28`
- **Output:**
  ```python
  {
      "balance_score": 75,  # 0-100
      "cardio_pct": 45,
      "strength_pct": 35,
      "mobility_pct": 10,
      "recovery_pct": 5,
      "martial_arts_pct": 5,
      "missing_categories": ["hiit"],
      "recommendation": "Gut balanciert, aber kein HIIT in 28 Tagen",
      "cardio_to_strength_ratio": "1.3:1",
      "status": "balanced"  # balanced / cardio_heavy / strength_heavy
  }
  ```
- **Algorithmus:**
  ```python
  # Get category distribution
  categories = {'cardio': 0, 'strength': 0, 'mobility': 0, 'recovery': 0, ...}

  for category, minutes in distribution.items():
      categories[category] = (minutes / total_minutes) * 100

  # Balance score = 100 - (std_dev × 2)
  balance_score = 100 - (statistics.stdev(categories.values()) * 2)

  # Ratio calculations
  cardio_to_strength = categories['cardio'] / categories['strength']

  # Missing categories (expected but 0)
  expected = ['cardio', 'strength', 'mobility']
  missing = [c for c in expected if categories[c] == 0]
  ```
- **Modul:** `backend/data_layer/activity_metrics.py` (neue Funktion)
- **Dependencies:** statistics

### Feature: Subcategory Distribution (within Category)
- **Beschreibung:** Verteilung nach Subcategories innerhalb einer Kategorie
- **Input:** `profile_id: str`, `category: str = 'strength'`, `days: int = 28`
- **Output:**
  ```python
  {
      "category": "strength",
      "distribution": [
          {"subcategory": "hypertrophy", "count": 6, "percentage": 60},
          {"subcategory": "maxstrength", "count": 3, "percentage": 30},
          {"subcategory": "endurance", "count": 1, "percentage": 10}
      ],
      "total_sessions": 10,
      "ratio_hypertrophy_to_max": "2:1",
      "recommendation": "Gut verteilt, Periodisierung erkennbar",
      "confidence": "high"
  }
  ```
- **Algorithmus:**
  ```sql
  SELECT tt.subcategory,
         COUNT(*) as count
  FROM activity_log a
  JOIN training_types tt ON a.training_type_id = tt.id
  WHERE a.profile_id = %s
    AND a.training_category = %s
    AND a.date >= CURRENT_DATE - INTERVAL '%s days'
    AND a.quality_label IN ('excellent', 'good', 'acceptable')
  GROUP BY tt.subcategory
  ORDER BY count DESC
  ```
- **Modul:** `backend/data_layer/activity_metrics.py` (neue Funktion)
- **Dependencies:** training_types table, quality_filter.py

---

### Feature: Zwei-Stufen-Architektur für Interpretations-Platzhalter ⭐ NEU

#### Architektur-Überblick:
```
Data Layer (Python)  →  Raw Data Placeholder (JSON)  →  Basis-Prompt (KI)  →  Interpreted Placeholder
```

#### Beispiel: Goal-Weighted Priority

**Stufe 1: Data Layer**
```python
# backend/data_layer/scores.py (neu)
def get_goal_priority_raw_data(profile_id: str) -> Dict:
    """
    Aggregiert Rohdaten für Goal-Priorisierung.
    KEINE Interpretation, nur strukturierte Daten!
    """
    with get_db() as conn:
        cur = get_cursor(conn)

        # 1. Aktive Ziele mit Focus Contributions
        cur.execute("""
            SELECT g.id, g.name, g.goal_type, g.progress_percentage,
                   g.target_date, g.start_date, g.is_primary,
                   COALESCE(
                       json_agg(
                           json_build_object(
                               'focus_area', fad.name_de,
                               'category', fad.category,
                               'contribution_weight', gfc.contribution_weight
                           )
                       ) FILTER (WHERE fad.id IS NOT NULL),
                       '[]'::json
                   ) as focus_contributions
            FROM goals g
            LEFT JOIN goal_focus_contributions gfc ON g.id = gfc.goal_id
            LEFT JOIN focus_area_definitions fad ON gfc.focus_area_id = fad.id
            WHERE g.profile_id = %s AND g.status = 'active'
            GROUP BY g.id
        """, (profile_id,))
        goals = [dict(row) for row in cur.fetchall()]

        # 2. Focus Area Weights
        from data_layer.scores import get_user_focus_weights
        focus_weights = get_user_focus_weights(profile_id)

        # 3. Calculate derived metrics
        for goal in goals:
            # Total focus weight (Summe aller Contributions)
            goal['total_focus_weight'] = sum(
                fc['contribution_weight'] for fc in goal['focus_contributions']
            )

            # Behind schedule calculation
            if goal['target_date']:
                from datetime import datetime
                today = datetime.now().date()
                target = goal['target_date']
                start = goal['start_date']

                total_days = (target - start).days
                elapsed_days = (today - start).days
                expected_progress = (elapsed_days / total_days) * 100
                actual_progress = goal['progress_percentage']

                goal['behind_schedule_days'] = int(
                    ((expected_progress - actual_progress) / 100) * total_days
                )
            else:
                goal['behind_schedule_days'] = None

        # 4. Context
        context = {
            "behind_schedule_count": sum(
                1 for g in goals if g.get('behind_schedule_days', 0) > 0
            ),
            "on_track_count": sum(
                1 for g in goals if g.get('behind_schedule_days', 0) <= 0
            ),
            "primary_goal": next(
                (g['name'] for g in goals if g['is_primary']),
                None
            )
        }

        return {
            "goals": goals,
            "focus_area_weights": focus_weights,
            "context": context
        }
```

**Stufe 2: Platzhalter-Registration (Raw Data)**
```python
# backend/placeholder_resolver.py
PLACEHOLDER_MAP = {
    # ... existing placeholders ...

    # Raw Data Placeholders (Typ 2)
    '{{goal_priority_raw_data}}': lambda pid: json.dumps(
        get_goal_priority_raw_data(pid),
        indent=2
    ),
}
```

**Stufe 3: Basis-Prompt (KI Interpretation)**
```yaml
# Admin → KI-Prompts → Neuer Basis-Prompt

Name: Goal Priority Interpreter
Type: base
Output Format: json
Output Schema:
{
  "priority_ranking": [
    {
      "goal_name": "string",
      "priority_score": "number (0-100)",
      "rationale": "string",
      "conflicts": ["string"]
    }
  ],
  "recommended_focus": "string",
  "goal_conflicts": [
    {
      "goal_a": "string",
      "goal_b": "string",
      "conflict_type": "string",
      "severity": "string"
    }
  ]
}

Template:
---
Analysiere die folgenden Ziel-Rohdaten und erstelle eine priorisierte Liste.

# Rohdaten
{{goal_priority_raw_data}}

# Aufgabe
1. Sortiere Ziele nach kombinierter Priorität:
   - Focus-Weight (höheres Gewicht = höhere Priorität)
   - Behind-Schedule Status (hinter Plan = höhere Priorität)
   - Primary-Flag (Primary-Goal = Boost)

2. Für jedes Ziel:
   - Berechne Priority-Score (0-100)
   - Begründe die Priorisierung
   - Identifiziere Konflikte mit anderen Zielen

3. Identifiziere Goal-Konflikte:
   - Muskelaufbau vs. Kaloriendefizit (konfliktär)
   - Gewichtsverlust + Kraftaufbau (möglich mit Rekomposition)
   - etc.

4. Empfehle Fokus-Reihenfolge für nächste 4 Wochen

# Output
Gib das Ergebnis als JSON zurück (siehe Schema oben).
---
```

**Stufe 4: Interpreted Placeholder (von KI generiert)**
```python
# Wird automatisch durch Unified Prompt System erzeugt
# Wenn Basis-Prompt "Goal Priority Interpreter" ausgeführt wird:
'{{goal_weighted_priority}}' = <KI-generiertes JSON>

# Beispiel-Output:
{
  "priority_ranking": [
    {
      "goal_name": "Gewichtsverlust 85kg",
      "priority_score": 92,
      "rationale": "Höchstes Focus-Weight (75) + 5 Tage hinter Plan + Primary Goal",
      "conflicts": ["Kraftaufbau (moderate Konflikt bei zu großem Defizit)"]
    },
    {
      "goal_name": "Kraftaufbau",
      "priority_score": 58,
      "rationale": "Moderates Focus-Weight (20) + On Track + Secondary Goal",
      "conflicts": ["Gewichtsverlust (erfordert moderates Defizit)"]
    }
  ],
  "recommended_focus": "Primär Gewichtsverlust mit moderatem Defizit, dabei Krafttraining 2-3x/Woche für Muskelerhalt",
  "goal_conflicts": [
    {
      "goal_a": "Gewichtsverlust",
      "goal_b": "Kraftaufbau",
      "conflict_type": "energy_availability",
      "severity": "moderate"
    }
  ]
}
```

**Stufe 5: Verwendung in übergeordneten Prompts**
```yaml
# Pipeline-Prompt: "Weekly Coaching Report"

Template:
---
# Ziel-Priorisierung
{{goal_weighted_priority}}

# Basierend auf deinen Prioritäten...
[restlicher Prompt nutzt die Priorisierung]
---
```

#### Vorteile dieser Architektur:

1. **Flexibilität:** Prompt-Änderung ohne Code-Deploy
2. **Wartbarkeit:** Klare Trennung Data vs. Interpretation
3. **Erweiterbarkeit:** Gleiche Rohdaten für mehrere Prompts nutzbar
4. **Testbarkeit:** Rohdaten-Struktur separat testbar
5. **Transparenz:** Rohdaten sichtbar (Debug-Modus)
6. **Iterierbarkeit:** KI-Interpretation kann verfeinert werden

#### Implementierungs-Aufwand:

- **Data Layer Funktion:** 2h (get_goal_priority_raw_data)
- **Placeholder Registration:** 10min (einfacher Lambda)
- **Basis-Prompt:** 1h (Prompt-Engineering + Testing)
- **TOTAL:** 3h

#### Anwendbar für:

- P31: goal_weighted_priority ✅
- P32: main_constraint ✅
- P33: main_strength ✅
- P34: next_best_actions ⚠️ (braucht mehr Domänen-Wissen)

---

## 4. Datenqualität & Edge Cases

### Problem: Activities ohne quality_label (NULL values)
- **Beschreibung:** Alte Activities oder Imports haben kein quality_label → NULL
- **Betroffene Platzhalter:** ALLE activity-bezogenen Platzhalter
- **Vorschlag:** Wie sollte damit umgegangen werden?
  - [x] NULL behandeln als "uncategorized" (separate Kategorie)
  - [x] Bei quality_filter: NULL = excluded (nicht mitzählen)
  - [ ] Batch-Evaluation für alte Activities nachholen
  - [ ] Warnung in confidence_score wenn >20% NULL

### Problem: Quality-Filter zu strikt für manche Platzhalter
- **Beschreibung:** Bei "excellent" only → zu wenig Daten für Statistik
- **Betroffene Platzhalter:** `{{activity_summary_excellent}}`, etc.
- **Vorschlag:** Wie sollte damit umgegangen werden?
  - [x] Confidence-Score anpassen (insufficient wenn <3 activities)
  - [x] Fallback-Message: "Nur 2 excellent Sessions in 14 Tagen (zu wenig für Statistik)"
  - [ ] Zeitraum automatisch erweitern (14d → 28d → 90d)

### Problem: quality_label vs. user quality_filter_level
- **Beschreibung:** Es gibt zwei Quality-Konzepte, die verwechselt werden können:
  - `quality_label` (DB-Spalte): Evaluation-Ergebnis pro Activity (excellent, good, acceptable, poor, excluded)
  - `quality_filter_level` (Profile-Einstellung): User-Präferenz für globalen Filter (all, quality, very_good, excellent)
- **Betroffene Platzhalter:** Alle activity-bezogenen Platzhalter
- **Vorschlag:**
  - [x] Platzhalter verwenden IMMER default='quality' (acceptable+) → konsistent für KI-Analysen
  - [x] User quality_filter_level nur für manuelle UI-Filter (Charts, Activity Page)
  - [x] Keine Vermischung: Platzhalter = fix 'quality', UI = user preference
  - [ ] Dokumentation: Klarstellung der beiden Konzepte

---

## 5. Placeholder-Kategorisierung & Organisation

### Vorschlag für neue Kategorien:
- [ ] Kategorie-Name: ___
  - Platzhalter: `{{...}}`, `{{...}}`
  - Begründung: ___

### Umstrukturierung existierender Kategorien:
- [ ] Von Kategorie X nach Y verschieben: `{{placeholder}}`
  - Begründung: ___

---

## 6. Dokumentation & Metadaten

### Fehlende Beschreibungen:
- `{{placeholder}}` - Beschreibung fehlt oder ist unklar

### Fehlende Beispiele:
- `{{placeholder}}` - Beispiel-Output fehlt

---

## 7. Prioritäten & Abhängigkeiten

### Must-Have (kritisch für Prompt-Qualität):

#### Gap #1: Quality Label
1. **Quality-Filter in data_layer/activity_metrics.py** - ALLE Funktionen betroffen
   - Breaking Change, aber notwendig für korrekte Auswertungen
   - Dauer: 4-6h (9 Funktionen + Tests)
   - Blockiert: Alle neuen Platzhalter
2. **Neue Platzhalter für Evaluation-Breakdown**
   - `{{evaluation_breakdown}}` - Übersicht über Qualitätsverteilung
   - Dauer: 1h (Funktion + Platzhalter)
3. **Placeholder-Updates in placeholder_resolver.py**
   - Alle activity-Platzhalter auf quality='quality' umstellen
   - Dauer: 2h (Updates + Testen)

**Teilsumme Gap #1:** 7-9h

#### Gap #2: Training Categories
4. **Category-Specific Activity Metrics (data_layer)**
   - `get_category_activity_data(category)` - Count/Minutes pro Kategorie
   - Dauer: 2h (1 Funktion, alle Kategorien abdecken)
5. **Kategorie-spezifische Platzhalter (Top Priority)**
   - `{{strength_training_count_7d}}`, `{{strength_training_minutes_7d}}`
   - `{{cardio_training_count_7d}}`, `{{cardio_training_minutes_7d}}`
   - `{{strength_frequency_adequate}}`, `{{muscle_preservation_risk}}`
   - Dauer: 3h (6-8 Platzhalter, kritisch für Muskelerhalt-Coaching)
6. **Days Since Last Training (per Category)**
   - `get_days_since_last_training(category)` - Funktion
   - `{{days_since_last_strength}}`, `{{days_since_last_cardio}}`, etc.
   - Dauer: 2h (Funktion + 3-4 Platzhalter)
7. **Training Balance Calculator**
   - `get_training_balance_data()` - Balance-Score + Ratios
   - `{{cardio_to_strength_ratio}}`, `{{training_balance_score}}`, `{{missing_training_categories}}`
   - Dauer: 2-3h (Funktion + 3 Platzhalter)

**Teilsumme Gap #2:** 9-10h

**TOTAL Must-Have:** 16-19h

### Should-Have (sinnvolle Ergänzungen):

#### Gap #1: Quality Label
1. **Dedizierte Quality-Platzhalter**
   - `{{activity_summary_acceptable_plus}}`, `{{activity_summary_excellent}}`
   - Dauer: 2h (4-5 neue Platzhalter)
2. **Poor Sessions Warning Platzhalter**
   - `{{poor_sessions_count}}`, `{{poor_sessions_warning}}`
   - Dauer: 1h

#### Gap #2: Training Categories
3. **Weitere Kategorie-Platzhalter**
   - `{{martial_arts_frequency_28d}}`, `{{recovery_sessions_count_28d}}`, `{{mobility_sessions_count_28d}}`
   - Dauer: 2h (3-4 Platzhalter)
4. **Subcategory Distribution**
   - `get_subcategory_distribution(category)` - Funktion
   - `{{strength_type_distribution}}`, `{{hypertrophy_vs_maxstrength_ratio}}`, `{{technique_vs_sparring_balance}}`
   - Dauer: 3h (Funktion + 3 Platzhalter)
5. **NULL-Handling für alte Activities**
   - Batch-Evaluation Script für Activities ohne quality_label
   - Dauer: 2h

**Teilsumme Should-Have:** 10h

### Nice-to-Have (optional):
1. **Quality-Weighted Metrics**
   - `{{training_minutes_quality_weighted}}` - gewichtet nach Qualität
   - Dauer: 1h
2. **Auto-Timeframe-Expansion**
   - Bei insufficient data: automatisch von 14d → 28d → 90d erweitern
   - Dauer: 3h (Logik + alle Funktionen anpassen)
3. **Advanced Subcategory Analysen**
   - Periodisierungs-Erkennung (Maximalkraft-Phase → Hypertrophie-Phase?)
   - Dauer: 2-3h

**Teilsumme Nice-to-Have:** 6-7h

### Geschätzte Gesamt-Dauer (Original):
- **Must-Have (Gap #1 + #2):** 16-19h (beide Gaps kritisch!)
- **Should-Have:** 10h
- **Nice-to-Have:** 6-7h
- **TOTAL (ohne User Requirements):** 32-36h

### Gesamt-Dauer (mit User Requirements P1-P27):
- **Sprint 1 (User Req + Governance):** 34-41h
- **Sprint 2 (Gap #1 + #2):** 26-32h
- **Sprint 3 (Optional):** 12-16h
- **TOTAL (inkl. User Requirements):** 72-89h

**Empfehlung:** Sprint 1 + Sprint 2 parallel bearbeiten wo möglich (viele unabhängige Tasks)

### Abhängigkeiten:
1. Quality-Filter in activity_metrics.py (MUSS zuerst)
2. Dann: Neue Platzhalter können parallel implementiert werden
3. Dann: Tests für alle Änderungen
4. Letzter Schritt: Bestehende Prompts auf neue Platzhalter umstellen

---

## Notizen

### Technische Details: quality_label System

**Verfügbare Quality Labels (activity_log.quality_label):**
- `'excellent'` - ⭐ Exzellentes Training (z.B. HR in Zone, Dauer optimal, RPE passend)
- `'very_good'` - ✓✓ Sehr gutes Training
- `'good'` - ✓ Gutes Training
- `'acceptable'` - ✓ Akzeptables Training (Mindestschwelle)
- `'poor'` - ⚠ Schlechtes Training (zu kurz, HR zu niedrig, etc.)
- `'excluded'` - ❌ Auszuschließen (fehlerhafte Messung, Dummy-Eintrag)
- `NULL` - Nicht evaluiert (alte Einträge, Imports ohne Evaluation)

**Quality Filter Levels (für User-Präferenz, nicht Platzhalter!):**
- `'all'` - Alle Activities (kein Filter)
- `'quality'` - Hochwertig (acceptable+) ← **DEFAULT für Platzhalter**
- `'very_good'` - Sehr gut+ (excellent, good)
- `'excellent'` - Nur exzellent

**Bestehende Infrastruktur (quality_filter.py):**
```python
get_quality_filter_sql(profile, table_alias='')
# Returns: "AND quality_label IN ('excellent', 'good', 'acceptable')"

get_quality_filter_tuple(profile)
# Returns: ('excellent', 'good', 'acceptable')

filter_activities_by_quality(activities, profile)
# Post-query filtering
```

**Migration Path:**
1. Alle data_layer Funktionen erweitern um `quality_level='quality'` Parameter
2. Alle Platzhalter updaten: `lambda pid: get_activity_summary_data(pid, quality_level='quality')`
3. Neue Platzhalter für andere Levels: `{{activity_summary_excellent}}`
4. Tests schreiben für alle Kombinationen
5. Bestehende Prompts prüfen und ggf. anpassen

### Verfügbare Trainings-Kategorien & Subcategories:

**7 Hauptkategorien (training_category):**
1. **cardio** → Ausdauer
   - Subcategories: running, cycling, swimming, rowing, other
2. **strength** → Kraft
   - Subcategories: hypertrophy, maxstrength, endurance, functional
3. **hiit** → Schnellkraft
   - Subcategories: hiit, explosive, circuit
4. **martial_arts** → Kampfsport
   - Subcategories: technique, sparring, strength
5. **mobility** → Beweglichkeit
   - Subcategories: static, dynamic, yoga, fascia
6. **recovery** → Erholung (aktiv)
   - Subcategories: walk, swim_light, regeneration
7. **other** → Sonstiges

**Abilities-Mapping (JSONB in training_types.abilities):**
- strength, endurance, mental, coordination, mobility

**Bestehende Platzhalter (nutzen bereits Categories):**
- `{{trainingstyp_verteilung}}` - Top 3 Kategorien mit %
- `{{ability_balance_strength}}` - Ability-Score 0-100 (nutzt abilities JSONB)
- `{{ability_balance_endurance}}` - Ability-Score 0-100

**Migration Path Training Categories:**
1. Neue data_layer Funktionen: get_category_activity_data(), get_days_since_last_training(), etc.
2. Platzhalter für JEDE Kategorie (mindestens count + minutes für strength/cardio)
3. Balance-Funktionen (Ratios, fehlende Kategorien)
4. Subcategory-Analysen (innerhalb strength, martial_arts)
5. Tests für alle Kombinationen
6. Bestehende Prompts erweitern mit neuen Platzhaltern

---

### Offene Fragen:

#### Gap #1: Quality Label
1. **Breaking Change akzeptabel?** Zahlen ändern sich bei allen activity-Platzhaltern
2. **NULL-Handling:** Als 'excluded' behandeln oder separate Kategorie?
3. **Batch-Evaluation:** Alte Activities nachträglich evaluieren? (Performance-Impact?)
4. **Confidence-Anpassung:** Thresholds senken wenn quality_filter aktiv? (weniger Daten)

#### Gap #2: Training Categories
5. **Ruhepausen-Thresholds:** Welche Schwellenwerte pro Kategorie?
   - Kraft: >3d warning, >7d critical?
   - Cardio: >2d warning, >5d critical?
   - Kampfsport: >7d warning, >14d critical?
6. **Balance-Definition:** Was ist "gut balanciert"?
   - Cardio:Kraft 2:1 bis 1:1 ok?
   - Mobility mindestens 5% aller Trainings?
7. **Subcategory-Priorität:** Welche Subcategories zuerst?
   - Kraft (hypertrophy/maxstrength/endurance) → Top Priority
   - Kampfsport (technique/sparring) → Nice-to-Have?
8. **Missing Categories Logic:** Welche Kategorien sind "Pflicht"?
   - Core: cardio, strength, mobility
   - Optional: recovery, hiit, martial_arts?

### User Requirements Summary (P1-P27):

**Sprint 1 - Must-Have (10 Core Items):**
1. goal_summary_json → vollständige Zielübersicht
2. focus_area_summary_json → strukturierte Focus Areas
3. domain_availability_json → Verfügbarkeit pro Domäne
4. body_change_summary_json → Körperentwicklung strukturiert
5. activity_structure_json → Training strukturiert
6. sleep_summary_json → Schlaf strukturiert
7. recovery_summary_json → Erholung strukturiert
8. vitals_summary_json → Vitalwerte strukturiert
9. correlation_summary_json → Korrelationen strukturiert
10. plateau_status + top_drivers → Diagnose strukturiert

**Sprint 1 - Governance (4 Items):**
- Placeholder Versioning System
- "nicht verfügbar" → null Migration
- Zeitfenster-Audit & Renaming
- Availability Flags (systematic)

**Sprint 2 - Energy & Risk:**
- underfueling_risk_flag + energy_availability_summary
- training_quality_score (aggregiert)
- load_balance_class (klassifiziert)

**Sprint 3 - Zwei-Stufen-Architektur (P31-P34):**
- goal_weighted_priority (✅ möglich via 2-Stufen)
- main_constraint (✅ möglich via 2-Stufen)
- main_strength (✅ möglich via 2-Stufen)
- next_best_actions (⚠️ teilweise, braucht Domänen-Wissen)

**Sprint 3 - Optional:**
- blood_pressure_summary_json (niedrigere Priorität)

### User Input benötigt:

#### Gap #1: Quality Label
- [ ] Strategie-Entscheidung: Breaking Change (Option A) vs. Non-Breaking (Option B)?
- [ ] NULL-Handling: excluded oder uncategorized?
- [ ] Batch-Evaluation: Ja/Nein?

#### Gap #2: Training Categories
- [ ] Ruhepausen-Thresholds definieren (pro Kategorie)
- [ ] Balance-Kriterien festlegen (Ratios, Mindest-%)
- [ ] Subcategory-Priorität: Kraft zuerst, dann Kampfsport? Oder parallel?
- [ ] Muskelerhalt-Schwelle: 2x/Woche Kraft ok? Oder 3x?

#### User Requirements (P1-P27):
- [ ] Sprint-Priorisierung: Sprint 1 + Sprint 2 parallel? Oder sequentiell?
- [ ] Sprint 3: Zwei-Stufen-Platzhalter (P31-P34) gewünscht? Oder später?
- [ ] Governance: Placeholder Versioning System sofort einführen oder später?
- [ ] Breaking Changes: "nicht verfügbar" → null jetzt oder schrittweise?
- [ ] JSON-Struktur-Review: Beispiel-Strukturen (siehe P1-P27) absegnen?

#### Zwei-Stufen-Architektur (⭐ NEU):
- [ ] **Architektur-Approval:** Zwei-Stufen-Ansatz (Data + KI) für P31-P34 ok?
- [ ] **Basis-Prompts:** Wer erstellt/reviewed die Basis-Prompts? (User oder Claude?)
- [ ] **Prompt-Governance:** Wie werden Basis-Prompts versioniert/getestet?
- [ ] **Raw Data Sichtbarkeit:** Sollen Raw Data Placeholders auch in UI-Export sichtbar sein?
- [ ] **Iterative Verfeinerung:** Basis-Prompts initial "good enough" oder erst perfekt dann deployen?

---

## 📊 Finale Zusammenfassung: Impact der Fit/Gap-Analyse

### Vor der Analyse (Original):
- **Gap #1 (Quality Label):** 11-13h
- **Gap #2 (Training Categories):** 11-13h
- **TOTAL:** 22-26h
- **User Requirements:** Nicht bewertet
- **P31-P34:** Als "nicht möglich" eingestuft

### Nach der Analyse (aktualisiert):
- **Sprint 1 (User Req + Governance):** 34-41h
- **Sprint 2 (Gap #1 + #2):** 26-32h
- **Sprint 3 (Zwei-Stufen-Architektur):** 12-16h
- **TOTAL:** 72-89h
- **Alle 27 User Requirements:** ✅ Umsetzbar!
- **P31-P34:** ✅ Möglich via Zwei-Stufen-Architektur

### Wichtigste Erkenntnisse:

#### ✅ Architektur-Durchbruch:
**Zwei-Stufen-Architektur** löst das Problem komplexer Interpretations-Platzhalter:
- Data Layer stellt strukturierte Rohdaten bereit
- KI interpretiert via Basis-Prompts
- Flexibler, wartbarer, erweiterbarer als hardcodierte Logik

#### ✅ Vollständige Umsetzbarkeit:
**Alle 27 User Requirements (P1-P34) sind umsetzbar:**
- 20 Items direkt möglich (mit aktueller Datenstruktur)
- 4 Items möglich via Zwei-Stufen-Architektur
- 3 Items teilweise möglich (einfache Erweiterungen)
- Nur P6 redundant, P30 optional

#### ✅ Governance-Framework:
**8 verbindliche Governance-Regeln** für stabile Placeholder-API:
- Platzhalter = API-Verträge
- Keine stillschweigenden Änderungen
- JSON vor Freitext
- Zwei-Stufen-Architektur für Interpretationen

#### ✅ Klare Sprint-Struktur:
**3 Sprints mit klaren Zielen:**
- Sprint 1: Foundation (User Req + Governance)
- Sprint 2: Quality + Categories (kritische Gaps)
- Sprint 3: Interpretations-Platzhalter (Zwei-Stufen)

### Empfohlenes Vorgehen:

1. **User-Entscheidungen einholen** (siehe "User Input benötigt")
2. **Sprint 1 starten** (strukturierte JSONs + Governance)
3. **Sprint 2 parallel** (Quality + Categories, unabhängig von Sprint 1)
4. **Sprint 3 nach Approval** (Zwei-Stufen-Architektur)

### Geschätzter Gesamtaufwand:
- **Minimum:** 72h (optimistisch, parallele Arbeit)
- **Realistisch:** 89h (inkl. Testing, Iterationen, Reviews)
- **Mit Buffer:** 100-110h (Puffer für Unvorhergesehenes)

### ROI / Nutzen:
- ✅ **Stabile Placeholder-API** für professionelle Prompt-Bibliothek
- ✅ **Alle 27 User Requirements** erfüllt
- ✅ **Zukunftssichere Architektur** (Zwei-Stufen erweiterbar)
- ✅ **Quality + Categories Gaps** geschlossen (kritisch für KI-Coaching)
- ✅ **Governance-Framework** verhindert technische Schulden

---

**Status:** 🔴 Draft - Bereit für User Review & Entscheidungen
**Nächster Schritt:** User Input einholen → Umsetzungskonzept erstellen → Sprint 1 starten
