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

65 KiB
Raw Permalink Blame History

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:
    {
      "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:
    {
      "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:
    {
      "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:
    {
      "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:
    {
      "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:
    {
      "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:
    # 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:
    {
      "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:
    # 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:
    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
      {
        "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
      {
        "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
      {
        "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
      {
        "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:
    {
      "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

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

'{{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

# ❌ 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:

# 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:
    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:
    {
        "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:
    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:
    {
        "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:
    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:
    {
        "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:
    SELECT MAX(date) as last_date
    FROM activity_log
    WHERE profile_id = %s
      AND training_category = %s
      AND quality_label IN ('excellent', 'good', 'acceptable')
    
    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:
    {
        "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:
    # 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:
    {
        "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:
    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

# 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)

# 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)

# 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)

# 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

# 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?
    • NULL behandeln als "uncategorized" (separate Kategorie)
    • 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?
    • Confidence-Score anpassen (insufficient wenn <3 activities)
    • 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:
    • Platzhalter verwenden IMMER default='quality' (acceptable+) → konsistent für KI-Analysen
    • User quality_filter_level nur für manuelle UI-Filter (Charts, Activity Page)
    • 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

  1. Category-Specific Activity Metrics (data_layer)
    • get_category_activity_data(category) - Count/Minutes pro Kategorie
    • Dauer: 2h (1 Funktion, alle Kategorien abdecken)
  2. 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)
  3. 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)
  4. 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

  1. Weitere Kategorie-Platzhalter
    • {{martial_arts_frequency_28d}}, {{recovery_sessions_count_28d}}, {{mobility_sessions_count_28d}}
    • Dauer: 2h (3-4 Platzhalter)
  2. Subcategory Distribution
    • get_subcategory_distribution(category) - Funktion
    • {{strength_type_distribution}}, {{hypertrophy_vs_maxstrength_ratio}}, {{technique_vs_sparring_balance}}
    • Dauer: 3h (Funktion + 3 Platzhalter)
  3. 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):

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

  1. Ruhepausen-Thresholds: Welche Schwellenwerte pro Kategorie?
    • Kraft: >3d warning, >7d critical?
    • Cardio: >2d warning, >5d critical?
    • Kampfsport: >7d warning, >14d critical?
  2. Balance-Definition: Was ist "gut balanciert"?
    • Cardio:Kraft 2:1 bis 1:1 ok?
    • Mobility mindestens 5% aller Trainings?
  3. Subcategory-Priorität: Welche Subcategories zuerst?
    • Kraft (hypertrophy/maxstrength/endurance) → Top Priority
    • Kampfsport (technique/sparring) → Nice-to-Have?
  4. 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