mitai-jinkendo/.claude/docs/working/PHASE_0C_TASKS.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

277 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

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 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
<PlaceholderSelector
onSelect={(placeholder) => 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