mitai-jinkendo/.claude/docs/functional/PHASE_0B_IMPROVEMENTS.md
Lars 7940dc7560 docs: Struktur .claude/docs versionieren, working/, Gitea-Index, Regeln
- .gitignore: .claude/docs, rules, commands tracken; settings.local weiter ignorieren
- DOCUMENTATION.md: verbindliche Ablage functional/technical/working/issues
- .claude/README.md: Agent-Einstieg; GITEA_ISSUES_INDEX aus MCP (Stand 2026-04-08)
- Arbeitspapiere von docs/ nach .claude/docs/working/ verschoben
- docs/MEMBERSHIP_SYSTEM.md als Stub; kanonisch technical/MEMBERSHIP_SYSTEM.md
- CLAUDE.md Pflichtlektüre und Links angepasst; docs/README.md vereinfacht

Made-with: Cursor
2026-04-08 13:01:49 +02:00

1791 lines
65 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

# 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