- 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
169 lines
4.4 KiB
Markdown
169 lines
4.4 KiB
Markdown
# 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:**
|
|
```javascript
|
|
// 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:
|
|
|
|
```python
|
|
# 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:
|
|
|
|
```javascript
|
|
// 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`
|
|
|
|
1. Definiere `AGGREGATION_METHODS` Konstante mit Metadata
|
|
2. Erstelle Endpoint `GET /api/goal-types/aggregation-methods`
|
|
3. Optional: Validierung bei Goal Type Create/Update
|
|
|
|
### Phase 2: Frontend Integration (1h)
|
|
|
|
**Datei:** `frontend/src/pages/AdminGoalTypesPage.jsx`
|
|
|
|
1. Remove hardcoded `AGGREGATION_METHODS`
|
|
2. Add `loadAggregationMethods()` in useEffect
|
|
3. Update dropdown to use loaded methods
|
|
4. Add `api.getAggregationMethods()` in `api.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-methods` existiert
|
|
- [ ] 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
|