Some checks failed
Deploy Development / deploy (push) Failing after 4s
Docker & Deployment: - docker-compose.yml (Prod: Port 3003/8003) - docker-compose.dev-env.yml (Dev: Port 3098/8098) - Backend Dockerfile (Python 3.12-slim) - Frontend Dockerfile (Node 20 + Nginx) - Gitea Actions (deploy-dev.yml, deploy-prod.yml) Frontend: - React 18 + Vite setup - package.json, vite.config.js, index.html - App.jsx (minimal with version display) - api.js (complete API client) - app.css + AuthContext from Mitai - main.jsx entry point Backend Migrations: - 001_auth_membership.sql (Auth + Features + Tier Limits) - 002_organization.sql (Clubs, Divisions, Training Groups) - 003_catalogs.sql (Skills + Methods with sample data) Documentation: - .claude/rules/ (ARCHITECTURE, CODING_RULES, etc.) - SHINKAN_PROJECT_SETUP.md (technical setup guide) Server: - Directories created on Pi: /home/lars/docker/shinkan[-dev] - Gitea Runner configured and running Ready for first deployment to dev.shinkan.jinkendo.de version: 0.1.0 date: 2026-04-21
187 lines
5.7 KiB
Markdown
187 lines
5.7 KiB
Markdown
# Lessons Learned
|
||
|
||
Fehler die gemacht wurden – damit sie nicht wiederholt werden.
|
||
|
||
## 1. Feature-Enforcement Rollback (20.03.2026)
|
||
|
||
**Was:** Membership-System Feature-Enforcement implementiert
|
||
**Problem:** Brach Analyse-Verlauf, Export-Sichtbarkeit und Zähler
|
||
**Rollback:** Commit 4fcde4a
|
||
**Lösung:** Einfaches ai_enabled + ai_limit_day System aktiv
|
||
|
||
**Regel:** Feature-Enforcement nie ohne vollständige Test-Suite aktivieren.
|
||
Zuerst Shadow-Mode (loggen aber nicht blockieren), dann schrittweise aktivieren.
|
||
|
||
## 2. session=Depends(require_auth) innerhalb Header()
|
||
|
||
**Was:** Automatisches Einfügen von Auth in bestehende Endpoints
|
||
**Problem:** `session` wurde innerhalb `Header(default=None, session=...)` eingebettet
|
||
**Folge:** FastAPI ignorierte Auth stillschweigend – Endpoint ungeschützt
|
||
**Lösung:** session immer als separater Parameter
|
||
|
||
```python
|
||
# ❌ Was passiert ist:
|
||
def endpoint(x: str = Header(default=None, session=Depends(require_auth))):
|
||
|
||
# ✅ Korrekt:
|
||
def endpoint(x: str = Header(default=None), session: dict = Depends(require_auth)):
|
||
```
|
||
|
||
## 3. PostgreSQL Migration – apt-get Probleme
|
||
|
||
**Was:** Docker Build mit apt-get postgresql-client
|
||
**Problem:** Build hing 30+ Minuten
|
||
**Lösung:** Reine Python-Lösung mit psycopg2-binary, kein apt-get
|
||
|
||
## 4. SQLite → PostgreSQL Datenmigration
|
||
|
||
**Probleme:**
|
||
- Leere date-Strings (`''`) → PostgreSQL wirft Fehler → zu NULL konvertieren
|
||
- Boolean: SQLite `0/1` → PostgreSQL `true/false`
|
||
- `?` Platzhalter → `%s`
|
||
|
||
## 5. dayjs.week() Plugin fehlt
|
||
|
||
**Was:** dayjs().week() ohne isoWeek-Plugin aufgerufen
|
||
**Problem:** Weißer Screen auf Verlauf/Ernährung
|
||
**Lösung:** Native ISO-Wochenberechnung (siehe FRONTEND.md)
|
||
|
||
## 6. Bun Crash bei langen Claude Code Sessions
|
||
|
||
**Was:** Claude Code CLI lief >30 Minuten
|
||
**Problem:** Bun (JS Runtime) crashed mit "Illegal instruction"
|
||
**Lösung:** Bei komplexen Tasks früher committen und neue Session starten
|
||
|
||
## 7. Docker Cache nach Dateiänderung
|
||
|
||
**Was:** main.py auf Pi kopiert, Container neu gestartet
|
||
**Problem:** Docker nutzte gecachten Layer – alte Datei im Container
|
||
**Lösung:** Immer `--no-cache` bei Änderungen am Code:
|
||
```bash
|
||
docker compose build --no-cache backend
|
||
```
|
||
|
||
## 8. Placeholder Registry Framework – Kritische Learnings (02.04.2026)
|
||
|
||
**Was:** Implementation von 14 Nutrition Placeholders mit neuem Registry Framework
|
||
|
||
### 8.1 OutputType.TEXT existiert nicht
|
||
**Problem:** `OutputType.TEXT` verursachte AttributeError
|
||
**Richtig:** `OutputType.STRING` für Text-Outputs
|
||
**Verfügbar:** NUMERIC, STRING, BOOLEAN, JSON, LIST, TEXT_SUMMARY
|
||
|
||
```python
|
||
# ❌ Falsch:
|
||
output_type=OutputType.TEXT
|
||
|
||
# ✅ Richtig:
|
||
output_type=OutputType.STRING
|
||
```
|
||
|
||
### 8.2 Time Window "mixed" ist problematisch
|
||
**Problem:** `time_window="mixed"` unklar für Export und Consumers
|
||
**Lösung:** Dominante Zeitkomponente wählen, Rest als Kommentar
|
||
```python
|
||
# ❌ Unklar:
|
||
time_window="mixed"
|
||
|
||
# ✅ Klar:
|
||
time_window="7d" # protein 7d avg; weight ist snapshot (secondary)
|
||
```
|
||
|
||
### 8.3 Units müssen präzise sein
|
||
**Problem:** Unpräzise Units führen zu Interpretationsproblemen
|
||
```python
|
||
# ❌ Unpräzise:
|
||
unit="score"
|
||
unit="kcal"
|
||
|
||
# ✅ Präzise:
|
||
unit="score (0-100)"
|
||
unit="kcal/day"
|
||
```
|
||
|
||
### 8.4 Date Aggregation bei CSV-Imports
|
||
**Problem:** Mehrere Einträge pro Tag → falsche "Tage"-Zählung
|
||
**Lösung:** Immer `GROUP BY date, SUM()` für Tages-Aggregation
|
||
|
||
```python
|
||
# ❌ Falsch (zählt Einträge):
|
||
SELECT protein_g FROM nutrition_log WHERE date >= ...
|
||
|
||
# ✅ Richtig (zählt Tage):
|
||
SELECT date, SUM(protein_g) as daily_protein
|
||
FROM nutrition_log
|
||
WHERE date >= ...
|
||
GROUP BY date
|
||
```
|
||
|
||
**Betroffen:** Alle Funktionen die "Tage" zählen oder daily averages berechnen
|
||
|
||
### 8.5 Evidence-Based = Nie Raten
|
||
**Problem:** CODE_DERIVED falsch gesetzt ohne Code-Inspektion
|
||
**Lösung:** Bei Unsicherheit UNRESOLVED oder TO_VERIFY nutzen
|
||
|
||
```python
|
||
# Wenn unklar:
|
||
metadata.set_evidence("field", EvidenceType.UNRESOLVED) # ehrlich
|
||
# Nicht:
|
||
metadata.set_evidence("field", EvidenceType.CODE_DERIVED) # halluziniert
|
||
```
|
||
|
||
### 8.6 Known Limitations = Dokumentations-Gold
|
||
**Problem:** Inkonsistenzen/Bugs verschwiegen
|
||
**Erfolg:** Transparent dokumentiert in `known_limitations`
|
||
|
||
**Beispiel:**
|
||
```python
|
||
known_limitations=(
|
||
"KRITISCHE INKONSISTENZ: Protein ist geglättet (7d average), "
|
||
"Gewicht ist single-point (latest). Anfällig für Gewichts-Outlier."
|
||
)
|
||
```
|
||
|
||
**Regel:** Probleme dokumentieren statt verstecken. User entscheidet über Fixes.
|
||
|
||
### 8.7 Formeln explizit dokumentieren
|
||
**Problem:** "Berechnet Score" zu vage, nicht reproduzierbar
|
||
**Erfolg:** Alle Formeln, Thresholds, TDEE-Modelle explizit dokumentiert
|
||
|
||
**Beispiel:**
|
||
```python
|
||
known_limitations=(
|
||
"TDEE-MODELL: weight_kg × 32.5 (vereinfacht). "
|
||
"NICHT berücksichtigt: Aktivitätslevel, Alter, Geschlecht."
|
||
)
|
||
```
|
||
|
||
### 8.8 No-Change Requirement ist absolut
|
||
**Problem:** Versuchung, offensichtliche Bugs zu fixen
|
||
**Regel:** NUR dokumentieren, User entscheidet
|
||
|
||
**Beispiel:** `protein_g_per_kg` hat Zeitfenster-Inkonsistenz (7d protein / latest weight)
|
||
→ Dokumentiert in known_limitations, NICHT gefixed
|
||
|
||
### 8.9 Testing nach jedem Deploy
|
||
**Problem:** Fehler erst nach komplettem Cluster entdeckt
|
||
**Erfolg:** Testing nach jedem Part (A, B, C) → frühe Fehlerkennung
|
||
|
||
**Workflow:**
|
||
1. Deploy Part A
|
||
2. Test Export
|
||
3. Werte verifizieren
|
||
4. Erst dann Part B
|
||
|
||
### 8.10 .claude in .gitignore
|
||
**Problem:** Versuch, `.claude/task/` Files zu committen
|
||
**Lösung:** Nur `backend/` Code committen, `.claude/` ist local docs
|
||
|
||
---
|
||
|
||
**Zusammenfassung Nutrition Cluster:**
|
||
- 14 Placeholders erfolgreich implementiert
|
||
- 2 Bugs gefunden und behoben (OutputType, Date Aggregation)
|
||
- 2 Metadaten-Inkonsistenzen korrigiert (time_window, unit)
|
||
- Alle kritischen Formeln dokumentiert
|
||
- Framework bewährt und skalierbar
|