shinkan-jinkendo/.claude/rules/LESSONS_LEARNED.md
Lars b2bc8590c4
Some checks failed
Deploy Development / deploy (push) Failing after 4s
feat: Complete MVP setup - Docker, Frontend, Migrations, CI/CD
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
2026-04-21 14:36:52 +02:00

5.7 KiB
Raw Permalink Blame History

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

# ❌ 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:

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

# ❌ 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

# ❌ 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

# ❌ 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

# ❌ 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

# 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:

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:

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