# Phase 0c – Architecture Cleanup & Refactoring **Datum:** 2026-03-28 **Voraussetzung:** Phase 0b abgeschlossen **Geschätzter Aufwand:** 12-16 Stunden --- ## Ziele Phase 0c fokussiert auf **Architektur-Verbesserungen** und **Structured Data**, ohne neue Features hinzuzufügen. **Kernprinzip:** Von Formatted Strings zu Structured Data → Basis für Phase 0c Refactoring (Charts/Diagramme). --- ## Task 1: Dynamic Aggregation Methods (3-4h) **Problem:** Aggregationsmethoden sind im Frontend hardcoded. **Lösung:** ### Backend ```python # backend/routers/goal_types.py @router.get("/aggregation-methods") def get_aggregation_methods(): """Return all available aggregation methods with metadata""" return [ { "value": "latest", "label_de": "Letzter Wert", "label_en": "Latest", "description": "Aktuellster Wert aus Tabelle", "compatible_types": ["DECIMAL", "INTEGER", "FLOAT"], "requires_numeric": False }, { "value": "avg_7d", "label_de": "Durchschnitt 7 Tage", "label_en": "7-day average", "description": "Mittelwert über 7 Tage", "compatible_types": ["DECIMAL", "INTEGER", "FLOAT"], "requires_numeric": True }, # ... alle Methoden aus goal_utils.py ] ``` **Implementierung:** 1. Endpoint erstellen (goal_types.py) 2. Auto-Discovery aus goal_utils.py Docstrings oder Introspection 3. Frontend anpassen (AdminGoalTypesPage.jsx) 4. Migration für Backfill (falls nötig) **Dokumentation:** `.claude/docs/technical/AGGREGATION_METHODS.md` (exists) --- ## Task 2: Dynamic Placeholder Catalog (4-5h) **Problem:** Platzhalter sind im Frontend nicht sichtbar/suchbar. **Lösung:** ### Backend ```python # backend/routers/prompts.py @router.get("/placeholders/catalog") def get_placeholder_catalog(session: dict = Depends(require_auth)): """ Return all registered placeholders with metadata. Enables auto-complete and placeholder selector in frontend. """ return { "categories": [ { "name": "Profil", "placeholders": [ { "key": "name", "placeholder": "{{name}}", "description": "Name des Nutzers", "example": "Lars", "data_type": "string" }, # ... ] }, # ... weitere Kategorien ], "total_count": 111 } ``` ### Frontend ```javascript // PlaceholderSelector Component insertAtCursor(placeholder)} categories={fetchedCatalog.categories} searchable={true} showExamples={true} /> ``` **Implementierung:** 1. Endpoint erstellen (nutzt PLACEHOLDER_CATALOG aus placeholder_resolver.py) 2. React Component: PlaceholderSelector 3. Integration in UnifiedPromptModal (Prompt-Editor) 4. Keyboard-Shortcuts (Strg+Space für Auto-Complete) **Dokumentation:** `.claude/docs/technical/PLACEHOLDER_SYSTEM.md` (neu erstellen) --- ## Task 3: Calculation Functions → Structured Return (5-7h) **Problem:** Calculation Functions returnen formatted strings statt strukturierte Daten. **Lösung:** Refactoring aller Calculation Functions zu structured return. ### Beispiel-Refactoring **Vorher (Phase 0b):** ```python def calculate_weight_trend(profile_id: str) -> str: # ... calculation ... return f"sinkend (-0.9 kg in 28 Tagen)" ``` **Nachher (Phase 0c):** ```python def calculate_weight_trend(profile_id: str) -> Dict: # ... calculation ... return { "raw_value": -0.9, "unit": "kg", "period_days": 28, "direction": "decreasing", # "increasing", "stable" "confidence": "high", # "high", "medium", "low" "data_points": 15, "slope_per_day": -0.032 } ``` ### Formatting Layer ```python # placeholder_resolver.py def format_weight_trend(data: Dict) -> str: """Format structured weight trend for AI prompts""" direction_de = {"decreasing": "sinkend", "increasing": "steigend", "stable": "stabil"} return f"{direction_de[data['direction']]} ({data['raw_value']} {data['unit']} in {data['period_days']} Tagen)" ``` ### Betroffene Module - `calculations/body_metrics.py` (~15 Funktionen) - `calculations/nutrition_metrics.py` (~12 Funktionen) - `calculations/activity_metrics.py` (~18 Funktionen) - `calculations/recovery_metrics.py` (~10 Funktionen) - `calculations/scores.py` (~8 Funktionen) **Gesamt:** ~63 Funktionen zu refactoren ### Strategie 1. **Phase 0c/1:** Body Metrics (Proof of Concept) 2. **Phase 0c/2:** Nutrition + Activity 3. **Phase 0c/3:** Recovery + Scores 4. **Phase 0c/4:** Placeholder Resolver anpassen (Formatter) **Dokumentation:** - `.claude/docs/technical/CALCULATION_FUNCTIONS.md` (neu) - `.claude/docs/functional/mitai_jinkendo_konzept_diagramme_auswertungen_v2.md` (exists, Kontext für Chart-System) --- ## Task 4: Stats/Chart Endpoints (Optional, 3-4h) **Voraussetzung:** Task 3 abgeschlossen **Lösung:** Separate Endpoints für Chart-Daten (nutzen structured calculation returns) ```python # backend/routers/stats.py (new) @router.get("/stats/body/weight-trend") def get_weight_trend_stats( days: int = 30, session: dict = Depends(require_auth) ): """Return structured weight trend data for charts""" trend_data = calculate_weight_trend(session['profile_id']) return { "trend": trend_data, "timeseries": [...], # Daily data points "projections": {...} # Linear projection } ``` **Implementierung:** 1. Neuer Router: `stats.py` 2. Endpoints für alle Chart-relevanten Metriken 3. OpenAPI Schema (für Frontend Type-Generation) --- ## Abhängigkeiten ``` Task 1 (Aggregation Methods) ─┐ ├─> Unabhängig, parallel möglich Task 2 (Placeholder Catalog) ─┘ Task 3 (Structured Returns) ──> Voraussetzung für Task 4 Task 4 (Stats Endpoints) ──> Optional, nutzt Task 3 Results ``` --- ## Akzeptanzkriterien Phase 0c **Muss (Must-Have):** - ✅ Aggregation Methods API-gesteuert - ✅ Placeholder Catalog API verfügbar - ✅ Mindestens 1 Modul (Body Metrics) zu structured return refactored - ✅ Dokumentation für alle 3 Tasks **Sollte (Should-Have):** - ✅ Alle Calculation Functions refactored - ✅ Frontend Placeholder Selector implementiert - ✅ Stats Endpoints für Body + Nutrition **Kann (Nice-to-Have):** - ⚪ Stats Endpoints für alle Module - ⚪ Chart-Preview in Admin-Panel - ⚪ TypeScript Type-Generation aus OpenAPI --- ## Rollback-Plan Falls Task 3 (Structured Returns) Probleme verursacht: 1. Calculation Functions returnen **beide** Formate: ```python return { "formatted": "sinkend (-0.9 kg)", # Backward-compat "structured": {...} # New format } ``` 2. Placeholder Resolver nutzt `formatted` weiterhin 3. Stats Endpoints nutzen `structured` 4. Schrittweise Migration ohne Breaking Changes --- ## Timeline (geschätzt) **Option A (Serial):** 12-16 Stunden über 2-3 Tage **Option B (Parallel):** 8-10 Stunden mit 2 Personen **Empfehlung:** Option A, da Tasks eng verzahnt sind. --- ## Nach Phase 0c **Enabler für:** - ✅ Chart/Diagram System (Phase 1) - ✅ Goal Progress Visualizations - ✅ Custom Dashboards - ✅ PDF/Excel Export mit strukturierten Daten - ✅ API für externe Tools (z.B. Home Assistant) **Nächste Phase (Phase 1):** - Chart Library Integration (Recharts/Victory) - Interactive Dashboards - Goal Progress Tracking UI