docs: update CLAUDE.md for v9b release
All checks were successful
Deploy Development / deploy (push) Successful in 56s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s

Updated documentation to reflect v9b (PostgreSQL) release:

**Version Update:**
- v9a → v9b (PostgreSQL Migration complete)
- Tech Stack: SQLite → PostgreSQL 16 (Alpine)
- 60+ protected endpoints (was 44)

**New Features Documented:**
-  PostgreSQL migration (auto-migrate from SQLite)
-  Export: CSV, JSON, ZIP (with photos)
-  Admin: Edit prompts, set email/PIN
-  All API endpoints aligned (11 fixes)

**Environment Variables:**
- Added DB_* variables (PostgreSQL connection)
- Added ANTHROPIC_API_KEY (alternative to OpenRouter)

**Important Hints:**
- Updated: PostgreSQL migrations instead of SQLite safe_alters
- Added: RealDictCursor usage for dict-like row access
- Added: PostgreSQL boolean syntax (true/false not 1/0)

**New Section: v9b Migration – Lessons Learned**
- Docker build optimization (removed apt-get)
- Empty date string handling
- Boolean field conversion
- API endpoint consistency audit

**Roadmap Adjustment:**
- v9c: Tier System (was in v9b)
- v9d: OAuth2 Connectors (was in v9c)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Lars 2026-03-18 21:39:14 +01:00
parent 1db780858b
commit 8e25b54cc2

View File

@ -10,7 +10,7 @@
|-----------|-------------|---------|
| Frontend | React 18 + Vite + PWA | Node 20 |
| Backend | FastAPI (Python) | Python 3.12 |
| Datenbank | SQLite (v9a) → PostgreSQL (v9b geplant) | - |
| Datenbank | PostgreSQL 16 (Alpine) | v9b |
| Container | Docker + Docker Compose | - |
| Webserver | nginx (Reverse Proxy) | Alpine |
| Auth | Token-basiert + bcrypt | - |
@ -53,36 +53,38 @@ mitai-jinkendo/
└── CLAUDE.md # Diese Datei
```
## Aktuelle Version: v9a
## Aktuelle Version: v9b
### Was implementiert ist:
- ✅ Multi-User mit E-Mail + Passwort Login (bcrypt)
- ✅ Auth-Middleware auf ALLE Endpoints (44 Endpoints geschützt)
- ✅ Auth-Middleware auf ALLE Endpoints (60+ Endpoints geschützt)
- ✅ Rate Limiting (Login: 5/min, Reset: 3/min)
- ✅ CORS konfigurierbar via ALLOWED_ORIGINS in .env
- ✅ Admin/User Rollen, KI-Limits, Export-Berechtigungen
- ✅ Gewicht, Umfänge, Caliper (4 Formeln), Ernährung, Aktivität
- ✅ FDDB CSV-Import (Ernährung), Apple Health CSV-Import (Aktivität)
- ✅ KI-Analyse: 6 Einzel-Prompts + 3-stufige Pipeline (parallel)
- ✅ Konfigurierbare Prompts mit Template-Variablen
- ✅ Konfigurierbare Prompts mit Template-Variablen (Admin kann bearbeiten)
- ✅ Verlauf mit 5 Tabs + Zeitraumfilter + KI pro Sektion
- ✅ Dashboard mit Kennzahlen, Zielfortschritt, Combo-Chart
- ✅ Assistent-Modus (Schritt-für-Schritt Messung)
- ✅ PWA (iPhone Home Screen), Jinkendo Ensō-Logo
- ✅ E-Mail (SMTP) für Password-Recovery
- ✅ Admin-Panel: User verwalten, KI-Limits, E-Mail-Test
- ✅ Admin-Panel: User verwalten, KI-Limits, E-Mail-Test, PIN/Email setzen
- ✅ Multi-Environment: Prod (mitai.jinkendo.de) + Dev (dev.mitai.jinkendo.de)
- ✅ Gitea CI/CD mit Auto-Deploy auf Raspberry Pi 5
- ✅ PostgreSQL 16 Migration (vollständig von SQLite migriert)
- ✅ Export: CSV, JSON, ZIP (mit Fotos)
- ✅ Automatische SQLite→PostgreSQL Migration bei Container-Start
### Was in v9b kommt:
- 🔲 PostgreSQL Migration (aktuell noch SQLite)
### Was in v9c kommt:
- 🔲 Selbst-Registrierung mit E-Mail-Bestätigung
- 🔲 Freemium Tier-System (free/basic/premium/selfhosted)
- 🔲 14-Tage Trial automatisch
- 🔲 Einladungslinks für Beta-Nutzer
- 🔲 Admin kann Tiers manuell setzen
### Was in v9c kommt:
### Was in v9d kommt:
- 🔲 OAuth2-Grundgerüst für Fitness-Connectoren
- 🔲 Strava Connector
- 🔲 Withings Connector (Waage)
@ -116,20 +118,24 @@ docker compose -f docker-compose.dev-env.yml build --no-cache
docker compose -f docker-compose.dev-env.yml up -d
```
## Datenbank-Schema (SQLite, v9a)
## Datenbank-Schema (PostgreSQL 16, v9b)
### Wichtige Tabellen:
- `profiles` Nutzer (role, pin_hash/bcrypt, email, auth_type, ai_enabled)
- `profiles` Nutzer (role, pin_hash/bcrypt, email, auth_type, ai_enabled, tier)
- `sessions` Auth-Tokens mit Ablaufdatum
- `weight_log` Gewichtseinträge (profile_id, date, weight)
- `circumference_log` 8 Umfangspunkte
- `caliper_log` Hautfaltenmessung, 4 Methoden
- `nutrition_log` Kalorien + Makros (aus FDDB-CSV)
- `activity_log` Training (aus Apple Health oder manuell)
- `photos` Progress Photos
- `ai_insights` KI-Auswertungen (scope = prompt-slug)
- `ai_prompts` Konfigurierbare Prompts mit Templates (11 Prompts)
- `ai_usage` KI-Calls pro Tag pro Profil
## Auth-Flow (v9a)
**Schema-Datei:** `backend/schema.sql` (vollständiges PostgreSQL-Schema)
**Migration-Script:** `backend/migrate_to_postgres.py` (SQLite→PostgreSQL, automatisch)
## Auth-Flow (v9b)
```
Login-Screen → E-Mail + Passwort → Token im localStorage
Token → X-Auth-Token Header → Backend require_auth()
@ -146,29 +152,44 @@ SHA256 Passwörter → automatisch zu bcrypt migriert beim Login
## Umgebungsvariablen (.env)
```
OPENROUTER_API_KEY= # KI-Calls
# Database (PostgreSQL)
DB_HOST=postgres
DB_PORT=5432
DB_NAME=mitai_prod
DB_USER=mitai_prod
DB_PASSWORD= # REQUIRED
# AI
OPENROUTER_API_KEY= # KI-Calls (optional, alternativ ANTHROPIC_API_KEY)
OPENROUTER_MODEL=anthropic/claude-sonnet-4
SMTP_HOST= # E-Mail
ANTHROPIC_API_KEY= # Direkte Anthropic API (optional)
# Email
SMTP_HOST= # E-Mail (für Recovery)
SMTP_PORT=587
SMTP_USER=
SMTP_PASS=
SMTP_FROM=
# App
APP_URL=https://mitai.jinkendo.de
ALLOWED_ORIGINS=https://mitai.jinkendo.de
DATA_DIR=/app/data
PHOTOS_DIR=/app/photos
ENVIRONMENT=production
```
## Wichtige Hinweise für Claude Code
1. **Ports immer 3002/8002 (Prod) oder 3099/8099 (Dev)** nie ändern
2. **npm install** (nicht npm ci) kein package-lock.json vorhanden
3. **SQLite safe_alters** neue Spalten immer via safe_alters Liste
3. **PostgreSQL-Migrations** Schema-Änderungen in `backend/schema.sql`, dann Container neu bauen
4. **Pipeline-Prompts** haben slug-Prefix `pipeline_` nie als Einzelanalyse zeigen
5. **dayjs.week()** braucht Plugin stattdessen native JS ISO-Wochenberechnung
6. **useNavigate()** nur in React-Komponenten, nicht in Helper-Functions
7. **api.js nutzen** für alle API-Calls injiziert Token automatisch
8. **bcrypt** für alle neuen Passwort-Operationen verwenden
9. **session=Depends(require_auth)** als separater Parameter nie in Header() einbetten
10. **RealDictCursor verwenden** `get_cursor(conn)` statt `conn.cursor()` für dict-like row access
## Code-Style
- React: Functional Components, Hooks
@ -437,10 +458,47 @@ def endpoint(x_profile_id: Optional[str] = Header(default=None),
<Bar fill="#1D9E75"/>
```
### SQLite neue Spalten hinzufügen
### PostgreSQL Boolean-Syntax
```python
# In _safe_alters Liste hinzufügen (NICHT direkt ALTER TABLE):
_safe_alters = [
("profiles", "neue_spalte TEXT DEFAULT NULL"),
]
# ❌ Falsch (SQLite-Syntax):
cur.execute("SELECT * FROM ai_prompts WHERE active=1")
# ✅ Richtig (PostgreSQL):
cur.execute("SELECT * FROM ai_prompts WHERE active=true")
```
### RealDictCursor für dict-like row access
```python
# ❌ Falsch:
cur = conn.cursor()
cur.execute("SELECT COUNT(*) FROM weight_log")
count = cur.fetchone()[0] # Tuple index
# ✅ Richtig:
cur = get_cursor(conn) # Returns RealDictCursor
cur.execute("SELECT COUNT(*) as count FROM weight_log")
count = cur.fetchone()['count'] # Dict key
```
## v9b Migration Lessons Learned
### PostgreSQL Migration (SQLite → PostgreSQL)
**Problem:** Docker Build hing 30+ Minuten bei `apt-get install postgresql-client`
**Lösung:** Alle apt-get dependencies entfernt, reine Python-Lösung mit psycopg2-binary
**Problem:** Leere date-Strings (`''`) führten zu PostgreSQL-Fehlern
**Lösung:** Migration-Script konvertiert leere Strings zu NULL für DATE-Spalten
**Problem:** Boolean-Felder (SQLite INTEGER 0/1 vs PostgreSQL BOOLEAN)
**Lösung:** Migration konvertiert automatisch, Backend nutzt `active=true` statt `active=1`
### API Endpoint Consistency (März 2026)
**Problem:** 11 kritische Endpoint-Mismatches zwischen Frontend und Backend gefunden
**Gelöst:**
- AI-Endpoints konsistent: `/api/insights/run/{slug}`, `/api/insights/pipeline`
- Password-Reset: `/api/auth/forgot-password`, `/api/auth/reset-password`
- Admin-Endpoints: `/permissions`, `/email`, `/pin` Sub-Routes
- Export: JSON + ZIP Endpoints hinzugefügt
- Prompt-Bearbeitung: PUT-Endpoint für Admins
**Tool:** Vollständiger Audit via Explore-Agent empfohlen bei größeren Änderungen