From 8e25b54cc21d72f3bc289e4ca168becf739214ef Mon Sep 17 00:00:00 2001 From: Lars Date: Wed, 18 Mar 2026 21:39:14 +0100 Subject: [PATCH] docs: update CLAUDE.md for v9b release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- CLAUDE.md | 96 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 77 insertions(+), 19 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 887af36..56a15dd 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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), ``` -### 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