Compare commits
No commits in common. "main" and "V0.9h" have entirely different histories.
35
CLAUDE.md
35
CLAUDE.md
|
|
@ -76,40 +76,9 @@ frontend/src/
|
||||||
└── technical/ # MEMBERSHIP_SYSTEM.md
|
└── technical/ # MEMBERSHIP_SYSTEM.md
|
||||||
```
|
```
|
||||||
|
|
||||||
## Aktuelle Version: v0.9g+ → v0.9h (Goals Complete + Dynamic Focus Areas) 🎯 27.03.2026
|
## Aktuelle Version: v9e+ (Phase 1 Goal System Fixes) 🎯 Ready for Phase 0b - 27.03.2026
|
||||||
|
|
||||||
**Status:** BEREIT FÜR RELEASE v0.9h
|
### Letzte Updates (27.03.2026 - Phase 1 Complete) 🆕
|
||||||
**Branch:** develop
|
|
||||||
**Nächster Schritt:** Testing → Prod Deploy → Code Splitting → Phase 0b (120+ Platzhalter)
|
|
||||||
|
|
||||||
### Letzte Updates (27.03.2026 - Dynamic Focus Areas v2.0 Complete) 🆕
|
|
||||||
|
|
||||||
#### Dynamic Focus Areas v2.0 System ✅
|
|
||||||
- ✅ **Migration 031-032:** Vollständiges dynamisches System
|
|
||||||
- `focus_area_definitions` - 26 Basis-Bereiche in 7 Kategorien (admin-erweiterbar)
|
|
||||||
- `goal_focus_contributions` - Many-to-Many (Goals ↔ Focus Areas) mit Gewichtung
|
|
||||||
- `user_focus_area_weights` - User-spezifische Präferenzen (dynamisch)
|
|
||||||
- ✅ **Backend:** `routers/focus_areas.py` (~350 Zeilen)
|
|
||||||
- CRUD für Focus Area Definitions (Admin only)
|
|
||||||
- User preferences mit Auto-Normalisierung zu Prozenten
|
|
||||||
- Stats endpoint (Progress per Focus Area)
|
|
||||||
- ✅ **Frontend:** Komplett überarbeitet
|
|
||||||
- GoalsPage: Dynamische Kacheln (nur Bereiche mit Gewicht > 0)
|
|
||||||
- Edit-Modus: Alle 26 Bereiche mit Schiebereglern (gruppiert nach Kategorie)
|
|
||||||
- Ziel-Formular: Nur gewichtete Focus Areas zur Auswahl (cleaner UX)
|
|
||||||
- AdminFocusAreasPage: Volle CRUD-UI für Admin
|
|
||||||
- ✅ **Architektur-Verbesserungen:**
|
|
||||||
- Kein Goal Mode mehr (ersetzt durch dynamische Focus Areas)
|
|
||||||
- M:N Relationship: Ein Ziel zahlt auf 1-n Focus Areas ein
|
|
||||||
- Contribution Weights: Prozentuale Gewichtung pro Zuordnung
|
|
||||||
- User-extensible: Admin kann beliebige neue Bereiche hinzufügen
|
|
||||||
|
|
||||||
#### Bug Fixes (alle deployed) ✅
|
|
||||||
- ✅ **Focus Contributions speichern:** `focus_contributions` fehlte in API-Payload (GoalsPage:232)
|
|
||||||
- ✅ **Focus Area Filtering:** Nur gewichtete Areas im Ziel-Formular (bessere UX)
|
|
||||||
- ✅ **Vitals Baseline Fix:** Parameter mismatch in dynamischer Query-Generierung behoben
|
|
||||||
|
|
||||||
#### Custom Goals Page (Capture/Eigene Ziele) ✅
|
|
||||||
- ✅ **Custom Goals Page (Capture/Eigene Ziele):**
|
- ✅ **Custom Goals Page (Capture/Eigene Ziele):**
|
||||||
- Neue Seite für tägliche Werterfassung individueller Ziele
|
- Neue Seite für tägliche Werterfassung individueller Ziele
|
||||||
- Dedizierte UI für custom goals (ohne automatische Datenquelle)
|
- Dedizierte UI für custom goals (ohne automatische Datenquelle)
|
||||||
|
|
|
||||||
|
|
@ -278,7 +278,7 @@ def _fetch_by_aggregation_method(
|
||||||
- max_30d: Maximum value in last 30 days
|
- max_30d: Maximum value in last 30 days
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
filter_conditions: Optional JSON filters (e.g., {"training_category": "strength"})
|
filter_conditions: Optional JSON filters (e.g., {"training_type": "strength"})
|
||||||
"""
|
"""
|
||||||
# Guard: source_table/column required for simple aggregation
|
# Guard: source_table/column required for simple aggregation
|
||||||
if not table or not column:
|
if not table or not column:
|
||||||
|
|
@ -412,21 +412,7 @@ def _fetch_by_aggregation_method(
|
||||||
return None
|
return None
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# Log detailed error for debugging
|
|
||||||
print(f"[ERROR] Failed to fetch value from {table}.{column} using {method}: {e}")
|
print(f"[ERROR] Failed to fetch value from {table}.{column} using {method}: {e}")
|
||||||
print(f"[ERROR] Filter conditions: {filter_conditions}")
|
|
||||||
print(f"[ERROR] Filter SQL: {filter_sql}")
|
|
||||||
print(f"[ERROR] Filter params: {filter_params}")
|
|
||||||
|
|
||||||
# CRITICAL: Rollback transaction to avoid InFailedSqlTransaction errors
|
|
||||||
try:
|
|
||||||
conn.rollback()
|
|
||||||
print(f"[INFO] Transaction rolled back after query error")
|
|
||||||
except Exception as rollback_err:
|
|
||||||
print(f"[WARNING] Rollback failed: {rollback_err}")
|
|
||||||
|
|
||||||
# Return None so goal creation can continue without current_value
|
|
||||||
# (current_value will be NULL in the goal record)
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1084,7 +1084,7 @@ def list_goal_type_definitions(session: dict = Depends(require_auth)):
|
||||||
cur.execute("""
|
cur.execute("""
|
||||||
SELECT id, type_key, label_de, label_en, unit, icon, category,
|
SELECT id, type_key, label_de, label_en, unit, icon, category,
|
||||||
source_table, source_column, aggregation_method,
|
source_table, source_column, aggregation_method,
|
||||||
calculation_formula, filter_conditions, description, is_system, is_active,
|
calculation_formula, description, is_system, is_active,
|
||||||
created_at, updated_at
|
created_at, updated_at
|
||||||
FROM goal_type_definitions
|
FROM goal_type_definitions
|
||||||
WHERE is_active = true
|
WHERE is_active = true
|
||||||
|
|
|
||||||
|
|
@ -99,90 +99,52 @@ def create_or_update_baseline(
|
||||||
"""Create or update baseline entry (upsert on date)."""
|
"""Create or update baseline entry (upsert on date)."""
|
||||||
pid = get_pid(x_profile_id)
|
pid = get_pid(x_profile_id)
|
||||||
|
|
||||||
# Build dynamic INSERT columns, placeholders, UPDATE fields, and values list
|
# Build dynamic update columns (only non-None fields)
|
||||||
# All arrays must stay synchronized
|
fields = []
|
||||||
insert_cols = []
|
values = [pid, entry.date]
|
||||||
insert_placeholders = []
|
|
||||||
update_fields = []
|
|
||||||
param_values = [] # Will contain ALL values including pid and date
|
|
||||||
|
|
||||||
# Always include profile_id and date
|
|
||||||
param_values.append(pid)
|
|
||||||
param_values.append(entry.date)
|
|
||||||
|
|
||||||
if entry.resting_hr is not None:
|
if entry.resting_hr is not None:
|
||||||
insert_cols.append("resting_hr")
|
fields.append("resting_hr = COALESCE(EXCLUDED.resting_hr, vitals_baseline.resting_hr)")
|
||||||
insert_placeholders.append("%s")
|
values.append(entry.resting_hr)
|
||||||
update_fields.append("resting_hr = EXCLUDED.resting_hr")
|
|
||||||
param_values.append(entry.resting_hr)
|
|
||||||
|
|
||||||
if entry.hrv is not None:
|
if entry.hrv is not None:
|
||||||
insert_cols.append("hrv")
|
fields.append("hrv = COALESCE(EXCLUDED.hrv, vitals_baseline.hrv)")
|
||||||
insert_placeholders.append("%s")
|
values.append(entry.hrv)
|
||||||
update_fields.append("hrv = EXCLUDED.hrv")
|
|
||||||
param_values.append(entry.hrv)
|
|
||||||
|
|
||||||
if entry.vo2_max is not None:
|
if entry.vo2_max is not None:
|
||||||
insert_cols.append("vo2_max")
|
fields.append("vo2_max = COALESCE(EXCLUDED.vo2_max, vitals_baseline.vo2_max)")
|
||||||
insert_placeholders.append("%s")
|
values.append(entry.vo2_max)
|
||||||
update_fields.append("vo2_max = EXCLUDED.vo2_max")
|
|
||||||
param_values.append(entry.vo2_max)
|
|
||||||
|
|
||||||
if entry.spo2 is not None:
|
if entry.spo2 is not None:
|
||||||
insert_cols.append("spo2")
|
fields.append("spo2 = COALESCE(EXCLUDED.spo2, vitals_baseline.spo2)")
|
||||||
insert_placeholders.append("%s")
|
values.append(entry.spo2)
|
||||||
update_fields.append("spo2 = EXCLUDED.spo2")
|
|
||||||
param_values.append(entry.spo2)
|
|
||||||
|
|
||||||
if entry.respiratory_rate is not None:
|
if entry.respiratory_rate is not None:
|
||||||
insert_cols.append("respiratory_rate")
|
fields.append("respiratory_rate = COALESCE(EXCLUDED.respiratory_rate, vitals_baseline.respiratory_rate)")
|
||||||
insert_placeholders.append("%s")
|
values.append(entry.respiratory_rate)
|
||||||
update_fields.append("respiratory_rate = EXCLUDED.respiratory_rate")
|
|
||||||
param_values.append(entry.respiratory_rate)
|
|
||||||
|
|
||||||
if entry.body_temperature is not None:
|
if entry.body_temperature is not None:
|
||||||
insert_cols.append("body_temperature")
|
fields.append("body_temperature = COALESCE(EXCLUDED.body_temperature, vitals_baseline.body_temperature)")
|
||||||
insert_placeholders.append("%s")
|
values.append(entry.body_temperature)
|
||||||
update_fields.append("body_temperature = EXCLUDED.body_temperature")
|
|
||||||
param_values.append(entry.body_temperature)
|
|
||||||
|
|
||||||
if entry.resting_metabolic_rate is not None:
|
if entry.resting_metabolic_rate is not None:
|
||||||
insert_cols.append("resting_metabolic_rate")
|
fields.append("resting_metabolic_rate = COALESCE(EXCLUDED.resting_metabolic_rate, vitals_baseline.resting_metabolic_rate)")
|
||||||
insert_placeholders.append("%s")
|
values.append(entry.resting_metabolic_rate)
|
||||||
update_fields.append("resting_metabolic_rate = EXCLUDED.resting_metabolic_rate")
|
|
||||||
param_values.append(entry.resting_metabolic_rate)
|
|
||||||
|
|
||||||
if entry.note:
|
if entry.note:
|
||||||
insert_cols.append("note")
|
fields.append("note = COALESCE(EXCLUDED.note, vitals_baseline.note)")
|
||||||
insert_placeholders.append("%s")
|
values.append(entry.note)
|
||||||
update_fields.append("note = EXCLUDED.note")
|
|
||||||
param_values.append(entry.note)
|
|
||||||
|
|
||||||
# At least one field must be provided
|
# At least one field must be provided
|
||||||
if not insert_cols:
|
if not fields:
|
||||||
raise HTTPException(400, "At least one baseline vital must be provided")
|
raise HTTPException(400, "At least one baseline vital must be provided")
|
||||||
|
|
||||||
|
# Build value placeholders
|
||||||
|
placeholders = ", ".join([f"${i}" for i in range(1, len(values) + 1)])
|
||||||
|
|
||||||
with get_db() as conn:
|
with get_db() as conn:
|
||||||
cur = get_cursor(conn)
|
cur = get_cursor(conn)
|
||||||
|
|
||||||
# Build complete column list and placeholder list
|
|
||||||
# IMPORTANT: psycopg2 uses %s placeholders, NOT $1/$2/$3
|
|
||||||
all_cols = f"profile_id, date, {', '.join(insert_cols)}"
|
|
||||||
all_placeholders = f"%s, %s, {', '.join(insert_placeholders)}"
|
|
||||||
|
|
||||||
query = f"""
|
query = f"""
|
||||||
INSERT INTO vitals_baseline ({all_cols})
|
INSERT INTO vitals_baseline (profile_id, date, {', '.join([f.split('=')[0].strip() for f in fields])})
|
||||||
VALUES ({all_placeholders})
|
VALUES ($1, $2, {', '.join([f'${i}' for i in range(3, len(values) + 1)])})
|
||||||
ON CONFLICT (profile_id, date)
|
ON CONFLICT (profile_id, date)
|
||||||
DO UPDATE SET {', '.join(update_fields)}, updated_at = NOW()
|
DO UPDATE SET {', '.join(fields)}, updated_at = NOW()
|
||||||
RETURNING *
|
RETURNING *
|
||||||
"""
|
"""
|
||||||
|
cur.execute(query, values)
|
||||||
# Debug logging
|
|
||||||
print(f"[DEBUG] Vitals baseline query: {query}")
|
|
||||||
print(f"[DEBUG] Param values ({len(param_values)}): {param_values}")
|
|
||||||
|
|
||||||
cur.execute(query, tuple(param_values))
|
|
||||||
return r2d(cur.fetchone())
|
return r2d(cur.fetchone())
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,196 +0,0 @@
|
||||||
# Dokumentation Abgeschlossen - 27. März 2026
|
|
||||||
|
|
||||||
## ✅ Was wurde dokumentiert?
|
|
||||||
|
|
||||||
### 1. Hauptstatus-Dokument
|
|
||||||
📄 **`docs/STATUS_2026-03-27.md`** (NEU)
|
|
||||||
- Vollständiger aktueller Zustand
|
|
||||||
- Gitea Issues Status (offen/geschlossen)
|
|
||||||
- Nächste Schritte (Testing → Release → Code Splitting → Phase 0b)
|
|
||||||
- Code-Metriken und technische Schulden
|
|
||||||
- Entscheidungspunkte und Risiken
|
|
||||||
- **Wiederanstiegspunkt für zukünftige Sessions**
|
|
||||||
|
|
||||||
### 2. Neue Issue dokumentiert
|
|
||||||
📄 **`docs/issues/issue-52-blood-pressure-dual-targets.md`** (NEU)
|
|
||||||
- Blutdruck-Ziele benötigen zwei Zielfelder (systolisch/diastolisch)
|
|
||||||
- Migration 033 geplant
|
|
||||||
- UI-Anpassungen beschrieben
|
|
||||||
- 2-3h Aufwand geschätzt
|
|
||||||
|
|
||||||
### 3. CLAUDE.md aktualisiert
|
|
||||||
📄 **`CLAUDE.md`**
|
|
||||||
- Version: v0.9g+ → v0.9h
|
|
||||||
- Dynamic Focus Areas v2.0 Sektion hinzugefügt
|
|
||||||
- Bug Fixes dokumentiert
|
|
||||||
- Status: BEREIT FÜR RELEASE v0.9h
|
|
||||||
|
|
||||||
### 4. Roadmap aktualisiert
|
|
||||||
📄 **`.claude/docs/ROADMAP.md`**
|
|
||||||
- Phase 0a: ✅ COMPLETE
|
|
||||||
- Phase 0b: 🎯 NEXT (detaillierter Plan)
|
|
||||||
- Timeline aktualisiert
|
|
||||||
- Phasen-Übersicht neu strukturiert
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📋 Gitea Issues - Aktueller Stand
|
|
||||||
|
|
||||||
### Geprüft ✅
|
|
||||||
- Alle offenen Issues durchgesehen (49, 47, 46, 45, 43, 42, 40, 39, 38, 37, 36, 35, 34, 33, 32, 30, 29, 27, 26, 25)
|
|
||||||
- Geschlossene Issues verifiziert (#50, #51, #48, #44, #28)
|
|
||||||
|
|
||||||
### Manuelle Aktionen erforderlich ⚠️
|
|
||||||
|
|
||||||
Du musst noch in Gitea (http://192.168.2.144:3000/Lars/mitai-jinkendo/issues):
|
|
||||||
|
|
||||||
1. **Issue #25 schließen:**
|
|
||||||
- Titel: "[FEAT] Ziele-System (Goals) - v9e Kernfeature"
|
|
||||||
- Status: ✅ KOMPLETT (Phase 0a + Dynamic Focus Areas v2.0)
|
|
||||||
- Aktion: Manuell auf "Closed" setzen
|
|
||||||
- Kommentar: "Completed in v0.9g-h: Phase 0a + Dynamic Focus Areas v2.0. See issue #50 and #51 for details."
|
|
||||||
|
|
||||||
2. **Issue #52 erstellen:**
|
|
||||||
- Titel: "Enhancement: Blutdruck-Ziele benötigen zwei Zielfelder (systolisch/diastolisch)"
|
|
||||||
- Labels: enhancement, goals, blood-pressure
|
|
||||||
- Priorität: Medium
|
|
||||||
- Beschreibung: Kopiere aus `docs/issues/issue-52-blood-pressure-dual-targets.md`
|
|
||||||
- Aufwand: 2-3h
|
|
||||||
- Milestone: v0.10a (nach Phase 0b)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 Nächste Schritte (wenn du weitermachst)
|
|
||||||
|
|
||||||
### Sofort (nach Deployment-Test):
|
|
||||||
1. **Teste Vitals Baseline Fix**
|
|
||||||
- Ruhepuls eintragen (sollte jetzt funktionieren)
|
|
||||||
- Andere Baseline-Werte testen
|
|
||||||
|
|
||||||
2. **Beginne Goals Testing**
|
|
||||||
- Siehe Checklist in `STATUS_2026-03-27.md`
|
|
||||||
- 2-3 Tage gründliches Testing
|
|
||||||
|
|
||||||
### Dann:
|
|
||||||
3. **Release v0.9h vorbereiten**
|
|
||||||
- Release Notes schreiben
|
|
||||||
- Merge develop → main
|
|
||||||
- Tag v0.9h
|
|
||||||
- Deploy to Production
|
|
||||||
|
|
||||||
4. **Code Splitting durchführen**
|
|
||||||
- goals.py → 5 separate Router
|
|
||||||
- Optional: insights.py prüfen
|
|
||||||
|
|
||||||
5. **Phase 0b starten**
|
|
||||||
- 120+ goal-aware Platzhalter
|
|
||||||
- Score-System
|
|
||||||
- 16-20h Aufwand
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📚 Wichtige Dokumente - Lesereihenfolge
|
|
||||||
|
|
||||||
Wenn du zu diesem Punkt zurückkehrst:
|
|
||||||
|
|
||||||
### 1. Zuerst lesen:
|
|
||||||
- **`docs/STATUS_2026-03-27.md`** ← START HIER
|
|
||||||
- **`CLAUDE.md`** (aktuelle Version)
|
|
||||||
- **`docs/NEXT_STEPS_2026-03-26.md`** (Phase 0b Details)
|
|
||||||
|
|
||||||
### 2. Bei Bedarf:
|
|
||||||
- **`.claude/docs/ROADMAP.md`** (Gesamtübersicht)
|
|
||||||
- **`docs/issues/issue-50-phase-0a-goal-system.md`** (Was wurde gebaut)
|
|
||||||
- **`docs/issues/issue-52-blood-pressure-dual-targets.md`** (Nächstes Enhancement)
|
|
||||||
|
|
||||||
### 3. Funktionale Specs:
|
|
||||||
- **`.claude/docs/functional/AI_PROMPTS.md`** (Prompt-System)
|
|
||||||
- **`.claude/docs/functional/TRAINING_TYPES.md`** (Trainingstypen + Abilities)
|
|
||||||
|
|
||||||
### 4. Technische Specs:
|
|
||||||
- **`.claude/docs/technical/MEMBERSHIP_SYSTEM.md`** (Feature-Enforcement)
|
|
||||||
- **`.claude/docs/architecture/`** (Wenn vorhanden)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔄 Wiederanstiegspunkt für Claude Code
|
|
||||||
|
|
||||||
### Context Prompt (copy-paste für neue Session):
|
|
||||||
```
|
|
||||||
Wir sind bei v0.9g/h Release-Vorbereitung.
|
|
||||||
|
|
||||||
AKTUELLER STAND:
|
|
||||||
- Phase 0a (Goals System) + Dynamic Focus Areas v2.0: ✅ KOMPLETT
|
|
||||||
- Vitals baseline fix: deployed (needs testing)
|
|
||||||
- Branch: develop (6 commits ahead of main)
|
|
||||||
- Status: BEREIT FÜR RELEASE v0.9h
|
|
||||||
|
|
||||||
NÄCHSTER SCHRITT:
|
|
||||||
- Testing (Goals + Vitals)
|
|
||||||
- Dann: Release v0.9h → Code Splitting → Phase 0b
|
|
||||||
|
|
||||||
LIES ZUERST:
|
|
||||||
- docs/STATUS_2026-03-27.md (vollständiger Zustand)
|
|
||||||
- CLAUDE.md (aktuelle Version)
|
|
||||||
|
|
||||||
FRAGE MICH:
|
|
||||||
"Was ist der aktuelle Schritt?" → Dann sage ich dir Testing/Release/Splitting/Phase 0b
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 Zusammenfassung - Was ist fertig?
|
|
||||||
|
|
||||||
### ✅ Komplett implementiert
|
|
||||||
- Goals System (Phase 0a)
|
|
||||||
- Strategic Layer (goal_mode, goals CRUD)
|
|
||||||
- Tactical Layer (CustomGoalsPage)
|
|
||||||
- Training Phases Framework (tables, backend)
|
|
||||||
- Fitness Tests Framework (tables, backend)
|
|
||||||
- Dynamic Focus Areas v2.0
|
|
||||||
- 26 Basis-Bereiche in 7 Kategorien
|
|
||||||
- User-extensible (Admin CRUD UI)
|
|
||||||
- Many-to-Many Goals ↔ Focus Areas
|
|
||||||
- User preferences mit Gewichtungen
|
|
||||||
- Bug Fixes
|
|
||||||
- Focus contributions speichern
|
|
||||||
- Filtering (nur gewichtete Areas)
|
|
||||||
- Vitals baseline endpoint
|
|
||||||
|
|
||||||
### 🔲 Noch zu tun (dokumentiert)
|
|
||||||
- Code Splitting (goals.py → 5 Router)
|
|
||||||
- Phase 0b (120+ Platzhalter, Score-System)
|
|
||||||
- Issue #52 (BP dual targets)
|
|
||||||
- Responsive UI (Issue #30)
|
|
||||||
- Weitere Features (siehe Roadmap)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎉 Dokumentations-Qualität
|
|
||||||
|
|
||||||
**Vollständigkeit:** ⭐⭐⭐⭐⭐
|
|
||||||
- Alle wichtigen Dokumente aktualisiert
|
|
||||||
- Neue Dokumente erstellt
|
|
||||||
- Gitea Issues geprüft
|
|
||||||
- Wiederanstiegspunkt klar definiert
|
|
||||||
|
|
||||||
**Nachvollziehbarkeit:** ⭐⭐⭐⭐⭐
|
|
||||||
- Status-Dokument mit allen Details
|
|
||||||
- Entscheidungen dokumentiert
|
|
||||||
- Nächste Schritte klar beschrieben
|
|
||||||
|
|
||||||
**Wartbarkeit:** ⭐⭐⭐⭐⭐
|
|
||||||
- Strukturierte Dokumentation
|
|
||||||
- Klare Verweise zwischen Dokumenten
|
|
||||||
- Lesereihenfolge definiert
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Erstellt:** 27. März 2026, 23:00 Uhr
|
|
||||||
**Von:** Claude Code (Sonnet 4.5)
|
|
||||||
**Commit:** eb5c099 (docs: comprehensive status update v0.9h pre-release)
|
|
||||||
|
|
||||||
**Du kannst jetzt:**
|
|
||||||
✅ Sicher pausieren
|
|
||||||
✅ Deployment testen
|
|
||||||
✅ Jederzeit exakt an diesem Punkt weitermachen
|
|
||||||
|
|
@ -1,272 +0,0 @@
|
||||||
# Projekt-Status: 27. März 2026
|
|
||||||
|
|
||||||
**Branch:** `develop`
|
|
||||||
**Letzte Version:** v0.9g+ (vor Release v0.9h)
|
|
||||||
**Deployment:** dev.mitai.jinkendo.de
|
|
||||||
**Nächster Meilenstein:** Release v0.9h → Code Splitting → Phase 0b
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 Aktueller Zustand: BEREIT FÜR RELEASE v0.9h
|
|
||||||
|
|
||||||
### Was ist fertig? ✅
|
|
||||||
|
|
||||||
#### Goals System (Phase 0a + Dynamic Focus Areas v2.0)
|
|
||||||
- ✅ **Migration 022:** goals, training_phases, fitness_tests tables
|
|
||||||
- ✅ **Migration 027-032:** Dynamic Focus Areas
|
|
||||||
- 26 Basis-Bereiche in 7 Kategorien (user-extensible)
|
|
||||||
- Many-to-Many: Goals ↔ Focus Areas mit contribution weights
|
|
||||||
- User preferences mit dynamischen Gewichtungen
|
|
||||||
- ✅ **Backend:**
|
|
||||||
- `routers/goals.py` - CRUD für Goals (~1200 Zeilen, **needs splitting**)
|
|
||||||
- `routers/focus_areas.py` - Dynamic system CRUD (~350 Zeilen)
|
|
||||||
- ✅ **Frontend:**
|
|
||||||
- `GoalsPage.jsx` - Strategic layer (~1180 Zeilen, **needs component extraction**)
|
|
||||||
- `CustomGoalsPage.jsx` - Tactical daily entry
|
|
||||||
- `AdminFocusAreasPage.jsx` - Admin UI für Focus Areas
|
|
||||||
- ✅ **Navigation:** Dashboard + Analysis integriert
|
|
||||||
|
|
||||||
#### Bug Fixes (alle committed, deployed pending)
|
|
||||||
- ✅ Focus area contributions speichern (fehlte in API payload)
|
|
||||||
- ✅ Filtering: Nur gewichtete Focus Areas im Ziel-Formular
|
|
||||||
- ✅ Vitals baseline endpoint (parameter mismatch behoben)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📋 Gitea Issues - Status
|
|
||||||
|
|
||||||
### Geschlossen ✅
|
|
||||||
- ✅ **#50:** Goals System v1 (Phase 0a)
|
|
||||||
- ✅ **#51:** Dynamic Focus Areas v2.0
|
|
||||||
- ✅ **#48:** Flexibles KI Prompt System
|
|
||||||
- ✅ **#44:** BUG - Analysen löschen
|
|
||||||
- ✅ **#28:** AI-Prompts Flexibilisierung
|
|
||||||
- ⏳ **#25:** Goals System (sollte geschlossen werden - ist fertig!)
|
|
||||||
|
|
||||||
### Offen - Priorisiert 🔲
|
|
||||||
- 🔲 **#52:** NEW - Blutdruck-Ziele mit dual targets (systolic/diastolic) - 2-3h
|
|
||||||
- 🔲 **#49:** Prompt-Zuordnung zu Verlaufsseiten (6-8h, Quick Win)
|
|
||||||
- 🔲 **#47:** Wertetabelle Optimierung (4-6h, nach Phase 0b)
|
|
||||||
- 🔲 **#30:** Responsive UI - Desktop Sidebar (8-10h)
|
|
||||||
- 🔲 **#29:** Abilities-Matrix UI (6-8h)
|
|
||||||
|
|
||||||
### Offen - Backlog 📦
|
|
||||||
- 📦 #46, #45: KI Prompt-Ersteller/-Optimierer (später)
|
|
||||||
- 📦 #43, #42: Enhanced Debug UI (später)
|
|
||||||
- 📦 #40: Logout-Button (kosmetisch)
|
|
||||||
- 📦 #39: Usage-Badges Dashboard (kosmetisch)
|
|
||||||
- 📦 #27: Korrelationen erweitern (Phase 2)
|
|
||||||
- 📦 #26: Charts erweitern (Phase 1)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 Nächste Schritte (User-Plan APPROVED)
|
|
||||||
|
|
||||||
### Phase 1: Testing + Release (2-3 Tage)
|
|
||||||
```
|
|
||||||
Tag 1-2: Umfassende Tests des Goals-Moduls
|
|
||||||
[ ] Goal Mode wechseln
|
|
||||||
[ ] Focus Areas gewichten (alle 26 testen)
|
|
||||||
[ ] Ziele erstellen mit focus_contributions
|
|
||||||
[ ] Ziele bearbeiten (contributions ändern)
|
|
||||||
[ ] Ist-Werte eintragen (CustomGoalsPage)
|
|
||||||
[ ] Progress Modal testen
|
|
||||||
[ ] Admin Focus Areas CRUD
|
|
||||||
[ ] Edge Cases (leere Daten, Extremwerte)
|
|
||||||
[ ] Vitals baseline entry (Ruhepuls) - nach neuem Deployment
|
|
||||||
|
|
||||||
Tag 3: Deploy + Release v0.9h
|
|
||||||
[ ] Final commit & push
|
|
||||||
[ ] Merge develop → main (PR in Gitea)
|
|
||||||
[ ] Tag v0.9h in Git
|
|
||||||
[ ] Deploy to Production
|
|
||||||
[ ] Smoke Tests
|
|
||||||
[ ] Release Notes schreiben
|
|
||||||
```
|
|
||||||
|
|
||||||
### Phase 2: Code Splitting (1-2 Tage)
|
|
||||||
```
|
|
||||||
Tag 3-4: Backend Router Split
|
|
||||||
[ ] goals.py → 5 separate Router
|
|
||||||
- goals.py (core CRUD ~300 Zeilen)
|
|
||||||
- goal_types.py (~200 Zeilen)
|
|
||||||
- goal_progress.py (~150 Zeilen)
|
|
||||||
- training_phases.py (~150 Zeilen)
|
|
||||||
- fitness_tests.py (~150 Zeilen)
|
|
||||||
[ ] Imports anpassen
|
|
||||||
[ ] main.py: 5 neue Router registrieren
|
|
||||||
[ ] Optional: insights.py prüfen (wenn >800 Zeilen)
|
|
||||||
|
|
||||||
Tag 5: Testing nach Split
|
|
||||||
[ ] API-Endpoints vollständig testen
|
|
||||||
[ ] Frontend funktioniert
|
|
||||||
[ ] Deployment auf dev
|
|
||||||
```
|
|
||||||
|
|
||||||
### Phase 3: Phase 0b - Goal-Aware Placeholders (4 Tage)
|
|
||||||
```
|
|
||||||
Aufwand: 16-20h
|
|
||||||
Neue Platzhalter: 120+ Funktionen
|
|
||||||
|
|
||||||
Tag 6: KÖRPER + ERNÄHRUNG (40 Funktionen)
|
|
||||||
- weight_7d_rolling_median, weight_28d_trend_slope
|
|
||||||
- fm_28d_delta, lbm_28d_delta, recomposition_score
|
|
||||||
- protein_g_per_kg, protein_g_per_kg_lbm
|
|
||||||
- nutrition_adherence_score, energy_availability
|
|
||||||
|
|
||||||
Tag 7: AKTIVITÄT + RECOVERY (37 Funktionen)
|
|
||||||
- activity_quality_avg_28d, activity_strain_28d
|
|
||||||
- activity_monotony_28d, ability_balance_score
|
|
||||||
- recovery_score, sleep_regularity_index, sleep_debt_hours
|
|
||||||
|
|
||||||
Tag 8: KORRELATIONEN + META + Scoring (20 Funktionen + System)
|
|
||||||
- corr_energy_weight_lag, plateau_detected
|
|
||||||
- goal_mode, data_quality_score, profile_age_years
|
|
||||||
- Score-Gewichtung pro goal_mode implementieren
|
|
||||||
|
|
||||||
Tag 9: Integration + Testing
|
|
||||||
- Prompts aktualisieren mit neuen Platzhaltern
|
|
||||||
- Testing mit verschiedenen goal_modes
|
|
||||||
- Dokumentation
|
|
||||||
|
|
||||||
Tag 10: Deploy v0.10a
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 Code-Metriken (Stand 27.03.2026)
|
|
||||||
|
|
||||||
### Große Dateien (Splitting-Kandidaten)
|
|
||||||
```
|
|
||||||
Backend:
|
|
||||||
- routers/goals.py ~1200 Zeilen ⚠️ SPLIT NEEDED
|
|
||||||
- routers/insights.py ~800 Zeilen (prüfen)
|
|
||||||
- routers/focus_areas.py ~350 Zeilen ✓ OK
|
|
||||||
|
|
||||||
Frontend:
|
|
||||||
- pages/GoalsPage.jsx ~1180 Zeilen ⚠️ Component extraction möglich
|
|
||||||
- pages/AdminPanel.jsx ~700 Zeilen ✓ OK
|
|
||||||
- pages/CustomGoalsPage.jsx ~350 Zeilen ✓ OK
|
|
||||||
```
|
|
||||||
|
|
||||||
### Migrations Status
|
|
||||||
```
|
|
||||||
Letzte Migration: 032_user_focus_area_weights.sql
|
|
||||||
Nächste: 033_dual_target_fields.sql (BP goals, Issue #52)
|
|
||||||
|
|
||||||
Alle Migrationen 001-032 erfolgreich angewandt auf dev ✅
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔧 Technische Schulden
|
|
||||||
|
|
||||||
### Hoch-Priorität
|
|
||||||
1. **Code Splitting:** goals.py zu groß für Context Window
|
|
||||||
2. **Component Extraction:** GoalsPage.jsx komponenten-basiert
|
|
||||||
3. **Testing Suite:** Automatisierte Tests fehlen komplett
|
|
||||||
|
|
||||||
### Mittel-Priorität
|
|
||||||
4. **Responsive UI:** Desktop-Sidebar fehlt (Issue #30)
|
|
||||||
5. **Error Handling:** Mehr defensive Programmierung nötig
|
|
||||||
6. **API Documentation:** Swagger/OpenAPI fehlt
|
|
||||||
|
|
||||||
### Niedrig-Priorität
|
|
||||||
7. **Type Hints:** Mehr Python Type Annotations
|
|
||||||
8. **Performance:** Einige N+1 Queries optimieren
|
|
||||||
9. **Caching:** Redis für häufige Abfragen
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📚 Dokumentation - Status
|
|
||||||
|
|
||||||
### Aktuell ✅
|
|
||||||
- ✅ `CLAUDE.md` - Hauptdokumentation
|
|
||||||
- ✅ `docs/STATUS_2026-03-27.md` - Dieser Status (NEU)
|
|
||||||
- ✅ `docs/NEXT_STEPS_2026-03-26.md` - Roadmap Phase 0b
|
|
||||||
- ✅ `docs/issues/issue-50-phase-0a-goal-system.md` - Phase 0a abgeschlossen
|
|
||||||
- ✅ `docs/issues/issue-52-blood-pressure-dual-targets.md` - Neue Issue (NEU)
|
|
||||||
- ✅ `.claude/docs/functional/AI_PROMPTS.md` - Prompt-System komplett
|
|
||||||
- ✅ `.claude/docs/technical/MEMBERSHIP_SYSTEM.md` - Feature-Enforcement
|
|
||||||
|
|
||||||
### Zu aktualisieren 📝
|
|
||||||
- 📝 `CLAUDE.md` - v0.9g/h Updates eintragen
|
|
||||||
- 📝 `.claude/docs/ROADMAP.md` - Phase 0a als ✅ markieren
|
|
||||||
- 📝 `.claude/library/` - Nach v0.9h Release aktualisieren
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 Decision Points
|
|
||||||
|
|
||||||
### Entschieden ✅
|
|
||||||
1. **User-Plan APPROVED:** Testing → Release → Split → Phase 0b
|
|
||||||
2. **Code Splitting:** Backend Router zuerst, Frontend optional
|
|
||||||
3. **Phase 0b:** Szenario 2 (Strategic Depth first) - 120+ Platzhalter
|
|
||||||
4. **Release Strategy:** v0.9h als stabiler Rollback-Punkt
|
|
||||||
|
|
||||||
### Offen 🤔
|
|
||||||
1. **Issue #52 (BP dual targets):** Vor oder nach Phase 0b? → **Empfehlung: Nach Phase 0b**
|
|
||||||
2. **Frontend Components:** Extract während oder nach Split? → **Empfehlung: Nach, wenn Zeit**
|
|
||||||
3. **Issue #49 (Prompt pages):** Vor oder nach Phase 0b? → **Empfehlung: Nach Phase 0b**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚨 Aktuelle Blocker / Risiken
|
|
||||||
|
|
||||||
### Keine kritischen Blocker ✅
|
|
||||||
|
|
||||||
**Kleine Risiken:**
|
|
||||||
1. ⚠️ **Vitals baseline fix:** Gerade deployed, needs testing
|
|
||||||
2. ⚠️ **Migration 032:** Muss auf Prod laufen (dev läuft bereits)
|
|
||||||
3. ⚠️ **Code Splitting:** Könnte Regressionen einführen → gründliches Testing
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📞 Ansprechpunkte für Wiederaufnahme
|
|
||||||
|
|
||||||
**Wenn du zu diesem Stand zurückkehrst:**
|
|
||||||
|
|
||||||
1. **Lies zuerst:**
|
|
||||||
- Dieses Dokument (STATUS_2026-03-27.md)
|
|
||||||
- CLAUDE.md (aktuelle Version)
|
|
||||||
- docs/NEXT_STEPS_2026-03-26.md (Roadmap)
|
|
||||||
|
|
||||||
2. **Prüfe:**
|
|
||||||
- Ist v0.9h deployed? `git describe --tags`
|
|
||||||
- Läuft dev/prod? `curl https://dev.mitai.jinkendo.de/api/version`
|
|
||||||
- Gitea Issues-Status aktuell?
|
|
||||||
|
|
||||||
3. **Nächster Schritt:**
|
|
||||||
- Falls v0.9h deployed: Start Code Splitting
|
|
||||||
- Falls nicht: Führe Testing-Checklist aus (siehe Phase 1 oben)
|
|
||||||
|
|
||||||
4. **Claude Code Context:**
|
|
||||||
```
|
|
||||||
"Wir sind bei v0.9h Release. Goals-System ist komplett (Phase 0a + Dynamic Focus Areas v2.0).
|
|
||||||
Nächster Schritt: [Testing/Code Splitting/Phase 0b] - siehe STATUS_2026-03-27.md"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📈 Metriken seit letztem Stand
|
|
||||||
|
|
||||||
**Commits seit v0.9g:**
|
|
||||||
- 6 Commits (Goals fixes, Focus Areas v2.0, Vitals baseline fix)
|
|
||||||
- +1200 Zeilen (neue Features)
|
|
||||||
- -400 Zeilen (Refactoring)
|
|
||||||
|
|
||||||
**Issues:**
|
|
||||||
- 3 geschlossen (#50, #51, #48)
|
|
||||||
- 1 neu (#52)
|
|
||||||
- 1 sollte geschlossen werden (#25)
|
|
||||||
|
|
||||||
**Deployment:**
|
|
||||||
- Letzte 3 Deployments erfolgreich
|
|
||||||
- Dev-Environment stabil
|
|
||||||
- Prod auf v0.9g (stabil)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Erstellt:** 27. März 2026, 22:30 Uhr
|
|
||||||
**Von:** Claude Code (Sonnet 4.5)
|
|
||||||
**Nächstes Update:** Nach v0.9h Release
|
|
||||||
|
|
@ -1,157 +0,0 @@
|
||||||
# Issue #52: Blutdruck-Ziele benötigen zwei Zielfelder
|
|
||||||
|
|
||||||
**Status:** 🔲 OFFEN
|
|
||||||
**Erstellt:** 27.03.2026
|
|
||||||
**Priorität:** Medium
|
|
||||||
**Typ:** Enhancement
|
|
||||||
**Labels:** goals, blood-pressure, enhancement
|
|
||||||
**Aufwand:** 2-3h
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Problem
|
|
||||||
|
|
||||||
**Aktuell:**
|
|
||||||
- Blutdruck-Ziele (goal_type = 'bp') haben nur EIN Zielfeld (`target_value`)
|
|
||||||
- Blutdruck besteht aber aus ZWEI Werten: Systolisch + Diastolisch
|
|
||||||
- Beispiel-Ziel: "Blutdruck senken auf 120/80 mmHg"
|
|
||||||
- Systolisch (oberer Wert): 120
|
|
||||||
- Diastolisch (unterer Wert): 80
|
|
||||||
|
|
||||||
**Konsequenz:**
|
|
||||||
- User kann nur einen Wert als Ziel eingeben
|
|
||||||
- Unvollständige Zieldefinition
|
|
||||||
- Progress-Tracking ungenau
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Lösung
|
|
||||||
|
|
||||||
### Option A: Dual Target Fields (empfohlen)
|
|
||||||
|
|
||||||
**Schema-Änderung:**
|
|
||||||
```sql
|
|
||||||
-- Migration 033
|
|
||||||
ALTER TABLE goals ADD COLUMN target_value_secondary DECIMAL(10,2);
|
|
||||||
ALTER TABLE goals ADD COLUMN current_value_secondary DECIMAL(10,2);
|
|
||||||
ALTER TABLE goals ADD COLUMN start_value_secondary DECIMAL(10,2);
|
|
||||||
|
|
||||||
COMMENT ON COLUMN goals.target_value_secondary IS 'Secondary target (e.g., diastolic BP for bp goal type)';
|
|
||||||
```
|
|
||||||
|
|
||||||
**Anwendung:**
|
|
||||||
- `bp` goal type:
|
|
||||||
- `target_value` = Systolisch (120)
|
|
||||||
- `target_value_secondary` = Diastolisch (80)
|
|
||||||
- Andere goal types: `target_value_secondary` = NULL
|
|
||||||
|
|
||||||
**UI-Anpassung:**
|
|
||||||
```jsx
|
|
||||||
// GoalForm - conditional rendering
|
|
||||||
{formData.goal_type === 'bp' && (
|
|
||||||
<div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:12}}>
|
|
||||||
<div>
|
|
||||||
<label>Systolisch (oben)</label>
|
|
||||||
<input type="number" value={formData.target_value} />
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label>Diastolisch (unten)</label>
|
|
||||||
<input type="number" value={formData.target_value_secondary} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Progress-Berechnung:**
|
|
||||||
```python
|
|
||||||
def calculate_bp_progress(goal):
|
|
||||||
"""
|
|
||||||
Berechnet Progress für Blutdruck-Ziele.
|
|
||||||
Nimmt Durchschnitt von systolischem und diastolischem Progress.
|
|
||||||
"""
|
|
||||||
systolic_progress = calculate_single_progress(
|
|
||||||
goal.current_value, goal.start_value, goal.target_value
|
|
||||||
)
|
|
||||||
diastolic_progress = calculate_single_progress(
|
|
||||||
goal.current_value_secondary,
|
|
||||||
goal.start_value_secondary,
|
|
||||||
goal.target_value_secondary
|
|
||||||
)
|
|
||||||
|
|
||||||
return (systolic_progress + diastolic_progress) / 2
|
|
||||||
```
|
|
||||||
|
|
||||||
**Display:**
|
|
||||||
```
|
|
||||||
🎯 Blutdruck
|
|
||||||
━━━━━━━━━━━━━━━━━━━━
|
|
||||||
Ziel: 120/80 mmHg
|
|
||||||
Aktuell: 135/88 mmHg
|
|
||||||
Fortschritt: 68% (sys: 60%, dia: 75%)
|
|
||||||
━━━━━━━━━━━━━━━━━━━━
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Option B: JSON Target (flexibler, komplexer)
|
|
||||||
|
|
||||||
```sql
|
|
||||||
ALTER TABLE goals ADD COLUMN target_json JSONB;
|
|
||||||
|
|
||||||
-- Beispiel:
|
|
||||||
{
|
|
||||||
"systolic": 120,
|
|
||||||
"diastolic": 80,
|
|
||||||
"unit": "mmHg"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Nachteil:** Komplexer zu abfragen, weniger SQL-freundlich.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Betroffene Dateien
|
|
||||||
|
|
||||||
**Backend:**
|
|
||||||
- `backend/migrations/033_dual_target_fields.sql` (NEU)
|
|
||||||
- `backend/routers/goals.py` - Progress-Berechnung erweitern
|
|
||||||
- `backend/routers/goal_utils.py` - `_get_current_value_for_goal_type()` für BP
|
|
||||||
|
|
||||||
**Frontend:**
|
|
||||||
- `frontend/src/pages/GoalsPage.jsx` - Form conditional rendering
|
|
||||||
- `frontend/src/pages/GoalsPage.jsx` - Display conditional rendering
|
|
||||||
- `frontend/src/pages/CustomGoalsPage.jsx` - Dual input für BP
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Acceptance Criteria
|
|
||||||
|
|
||||||
- [ ] Migration 033 erstellt und angewandt
|
|
||||||
- [ ] GoalForm zeigt zwei Felder für BP-Ziele (Systolisch/Diastolisch)
|
|
||||||
- [ ] Progress-Berechnung berücksichtigt beide Werte
|
|
||||||
- [ ] Display zeigt "120/80 mmHg" Format
|
|
||||||
- [ ] CustomGoalsPage erlaubt Eingabe beider Werte
|
|
||||||
- [ ] Backward compatible (alte BP-Ziele mit nur target_value funktionieren noch)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Verwandte Issues
|
|
||||||
|
|
||||||
- Issue #50: Goals System v1 ✅
|
|
||||||
- Issue #51: Dynamic Focus Areas v2.0 ✅
|
|
||||||
- Migration 022: goals table (Basis)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Timeline
|
|
||||||
|
|
||||||
**Geschätzt:** 2-3 Stunden
|
|
||||||
- Migration: 30 min
|
|
||||||
- Backend Logic: 1h
|
|
||||||
- Frontend UI: 1-1.5h
|
|
||||||
- Testing: 30 min
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Erstellt von:** Claude Code
|
|
||||||
**Review benötigt:** Vor Implementierung mit User abstimmen (Option A vs. B)
|
|
||||||
Loading…
Reference in New Issue
Block a user