- Mark issue #53 as completed - Create issue #55: Dynamic Aggregation Methods - Update CLAUDE.md with Phase 0c achievements - Document 97 migrated functions + 20 new chart endpoints
4.4 KiB
4.4 KiB
Issue #55: Dynamic Aggregation Methods for Goal Types
Status: 📋 Planned Priorität: Low (Nice-to-Have) Aufwand: 2-3h Erstellt: 28. März 2026 Abhängigkeiten: Keine
Problem
Aktuell:
// frontend/src/pages/AdminGoalTypesPage.jsx (Lines 28-38)
const AGGREGATION_METHODS = [
{ value: 'latest', label: 'Letzter Wert' },
{ value: 'avg_7d', label: 'Durchschnitt 7 Tage' },
{ value: 'avg_30d', label: 'Durchschnitt 30 Tage' },
{ value: 'sum_30d', label: 'Summe 30 Tage' },
{ value: 'count_7d', label: 'Anzahl 7 Tage' },
{ value: 'count_30d', label: 'Anzahl 30 Tage' },
{ value: 'min_30d', label: 'Minimum 30 Tage' },
{ value: 'max_30d', label: 'Maximum 30 Tage' },
{ value: 'avg_per_week_30d', label: 'Durchschnitt pro Woche (30d)' }
]
Probleme:
- ❌ Hardcoded im Frontend
- ❌ Backend kennt diese Liste nicht → keine Validierung
- ❌ Neue Aggregationsmethoden erfordern Frontend-Änderung
- ❌ Nicht konsistent mit dynamischer Platzhalter-Liste
Lösung: Backend-definierte Aggregation Methods
Konzept
Backend definiert die verfügbaren Methoden:
# backend/routers/goal_types.py
AGGREGATION_METHODS = [
{
"value": "latest",
"label_de": "Letzter Wert",
"label_en": "Latest Value",
"description": "Neuester Messwert im Zeitfenster",
"applicable_to": ["weight", "caliper", "circumference", "vitals"],
"example": "Aktuellstes Gewicht (heute oder letzter Eintrag)"
},
{
"value": "avg_7d",
"label_de": "Durchschnitt 7 Tage",
"label_en": "7-day Average",
"description": "Mittelwert der letzten 7 Tage",
"applicable_to": ["weight", "nutrition", "vitals", "sleep"],
"example": "Durchschnittskalorien der letzten Woche"
},
# ... alle Methoden ...
]
@router.get("/goal-types/aggregation-methods")
def get_aggregation_methods(session: dict = Depends(require_auth)):
"""
Get available aggregation methods for goal types.
Returns:
List of aggregation method definitions with metadata
"""
return {
"methods": AGGREGATION_METHODS,
"default": "latest"
}
Frontend lädt die Methoden dynamisch:
// frontend/src/pages/AdminGoalTypesPage.jsx
const [aggregationMethods, setAggregationMethods] = useState([])
useEffect(() => {
loadAggregationMethods()
}, [])
const loadAggregationMethods = async () => {
const data = await api.getAggregationMethods()
setAggregationMethods(data.methods)
}
// Render:
<select value={formData.aggregation_method} onChange={...}>
{aggregationMethods.map(method => (
<option key={method.value} value={method.value}>
{method.label_de}
</option>
))}
</select>
Implementierung
Phase 1: Backend Endpoint (1h)
Datei: backend/routers/goal_types.py
- Definiere
AGGREGATION_METHODSKonstante mit Metadata - Erstelle Endpoint
GET /api/goal-types/aggregation-methods - Optional: Validierung bei Goal Type Create/Update
Phase 2: Frontend Integration (1h)
Datei: frontend/src/pages/AdminGoalTypesPage.jsx
- Remove hardcoded
AGGREGATION_METHODS - Add
loadAggregationMethods()in useEffect - Update dropdown to use loaded methods
- Add
api.getAggregationMethods()inapi.js
Phase 3: Optional Enhancements (1h)
- Tooltips mit method.description
- Filtering nach applicable_to (nur relevante Methoden für gewählte Tabelle zeigen)
- Beispiel-Text anzeigen (method.example)
Vorteile
- ✅ Single Source of Truth im Backend
- ✅ Backend kann Aggregationsmethoden validieren
- ✅ Neue Methoden ohne Frontend-Änderung hinzufügbar
- ✅ Konsistent mit PlaceholderPicker-Architektur
- ✅ Bessere UX (Tooltips, Beispiele, Filtering)
Akzeptanzkriterien
- Backend Endpoint
/api/goal-types/aggregation-methodsexistiert - Frontend lädt Methoden dynamisch beim Laden der Seite
- Dropdown zeigt alle verfügbaren Methoden
- Hardcoded Array aus Frontend entfernt
- Backend validiert aggregation_method bei Create/Update
Related Issues
- ✅ #54: Dynamic Placeholder System (UI bereits implementiert)
- ✅ #53: Phase 0c Multi-Layer Architecture (abgeschlossen)
- ✅ #50: Goals System (Basis vorhanden)
Notes
- Priorität Low, weil System funktioniert (nur nicht dynamisch)
- Nice-to-Have für Admin-UX-Verbesserung
- Kann jederzeit später implementiert werden ohne Breaking Changes