# Mitai Jinkendo – Entwickler-Kontext für Claude Code ## Projekt-Übersicht **Mitai Jinkendo** (身体 Jinkendo) – selbst-gehostete PWA für Körper-Tracking mit KI-Auswertung. Teil der **Jinkendo**-App-Familie (人拳道). Domains: jinkendo.de / .com / .life ## Tech-Stack | Komponente | Technologie | |-----------|-------------| | Frontend | React 18 + Vite + PWA (Node 20) | | Backend | FastAPI Python 3.12 | | Datenbank | PostgreSQL 16 Alpine | | Container | Docker + Docker Compose | | Auth | Token-basiert + bcrypt | | KI | OpenRouter API (claude-sonnet-4) | **Ports:** Prod 3002/8002 · Dev 3099/8099 – nie ändern! ## Verzeichnisstruktur ``` backend/ ├── main.py # App-Setup + Router-Registration (~75 Zeilen) ├── db.py # PostgreSQL Connection Pool ├── db_init.py # DB-Init + Migrations-System (automatisch beim Start) ├── auth.py # Hash, Verify, Sessions, Feature-Access-Control ├── models.py # Pydantic Models ├── feature_logger.py # Strukturiertes JSON-Logging (Phase 2) ├── migrations/ # SQL-Migrationen (XXX_*.sql Pattern) └── routers/ # 14 Router-Module auth · profiles · weight · circumference · caliper activity · nutrition · photos · insights · prompts admin · stats · exportdata · importdata frontend/src/ ├── App.jsx # Root, Auth-Gates, Navigation ├── app.css # CSS-Variablen + globale Styles ├── context/ # AuthContext · ProfileContext ├── pages/ # Alle Screens └── utils/ api.js # ALLE API-Calls – Token automatisch injiziert calc.js · interpret.js · Markdown.jsx · guideData.js .claude/ ├── settings.json ├── commands/ # /deploy /merge-to-prod /refactor /ui-responsive etc. └── docs/ ├── BACKLOG.md ├── functional/ # Fachliche Specs (TRAINING_TYPES, AI_PROMPTS, RESPONSIVE_UI) └── technical/ # MEMBERSHIP_SYSTEM.md ``` ## Aktuelle Version: v9c (komplett) 🚀 Production seit 21.03.2026 ### Implementiert ✅ - Login (E-Mail + bcrypt), Auth-Middleware alle Endpoints, Rate Limiting - Gewicht · Umfänge · Caliper · Ernährung · Aktivität + CSV-Imports - KI-Analyse: 6 Prompts + 3-stufige Pipeline - Dashboard · Verlauf · Assistent-Modus · Fotos - Admin-Panel · E-Mail (SMTP) · PWA - PostgreSQL 16 · Modulare Router-Architektur - Membership-System: Tiers · Coupons · Access-Grants · Admin-UI - Export: CSV · JSON · ZIP - **Feature-Enforcement (komplett):** Alle 11 Features mit Monitoring, UI-Badges + Blocking - **Ernährungs-Modul (erweitert):** - Manuelles Erfassungsformular mit Upsert-Logik (verhindert Duplikate) - Import-Historie (CSV-Importe gruppiert nach Datum) - Bearbeiten/Löschen von Einträgen (inline) - Datumsfilter (7/30/90/365 Tage, Alle) - Zwei-Ebenen-Layout: Eingabe (Einzelerfassung/Import) + Auswertung (Charts) ### Feature-Enforcement Status (4-Phasen-Modell) - ✅ **Phase 1:** Cleanup (Feature-Konsolidierung, Migration) - ✅ **Phase 2:** Non-blocking Monitoring (JSON-Logs, alle 11 Features) - ✅ **Phase 3:** Frontend Display (Usage-Badges, Quota-Übersicht, Hover-Tooltips) - ✅ **Phase 4:** Enforcement (HTTP 403 bei Limit-Überschreitung, alle Features) **Abgedeckte Features:** weight_entries, circumference_entries, caliper_entries, activity_entries, nutrition_entries, photos, ai_calls, ai_pipeline, data_export, data_import ### Bug-Fixes (v9c) - ✅ **BUG-001:** TypeError in `/api/nutrition/weekly` (datetime.date vs string handling) - ✅ **BUG-002:** Ernährungs-Daten Tab fehlte – importierte Einträge nicht sichtbar - ✅ **BUG-003:** Korrelations-Chart Extrapolation (gestrichelte Linien für fehlende Werte) - ✅ **BUG-004:** Import-Historie Refresh (Force remount via key prop) - ✅ **BUG-005:** Login → leere Seite (window.location.href='/' nach login) - ✅ **BUG-006:** Email-Verifizierung → leere Seite (window.location.href='/' statt navigate) - ✅ **BUG-007:** Doppelklick Verifizierungslink → generischer JSON-Fehler (Error-Parsing + bessere Backend-Meldung) - ✅ **BUG-008:** Dashboard infinite loading bei API-Fehlern (.catch() handler in load()) ### v9c Finalisierung ✅ (Deployed to Production 21.03.2026) - ✅ **Selbst-Registrierung:** POST /api/auth/register, E-Mail-Verifizierung, Auto-Login - ✅ **Trial-System UI:** Countdown-Banner im Dashboard (3 Urgency-Level) - ✅ **Migrations-System:** Automatische Schema-Migrationen beim Start (db_init.py) - ✅ **Navigation-Fixes:** Alle Login/Verify-Flows funktionieren korrekt - ✅ **Error-Handling:** JSON-Fehler sauber formatiert, Dashboard robust bei API-Fehlern ### Auf develop (bereit für Prod) 🚀 **v9d Phase 1b - Feature-komplett, ready for deployment** - ✅ **Trainingstypen-System (komplett):** - 29 Trainingstypen (7 Kategorien) - Admin-CRUD mit vollständiger UI - Automatisches Apple Health Mapping (23 Workout-Typen) - Bulk-Kategorisierung für bestehende Aktivitäten - Farbige Typ-Badges in Aktivitätsliste - TrainingTypeDistribution Chart in History-Seite - TrainingTypeSelect in ActivityPage - ✅ **Weitere Verbesserungen:** - TrialBanner mailto (Vorbereitung zentrales Abo-System) - Admin-Formular UX-Optimierung (Full-width inputs, größere Textareas) - 📚 **Dokumentation:** - `.claude/docs/technical/CENTRAL_SUBSCRIPTION_SYSTEM.md` - `.claude/docs/functional/AI_PROMPTS.md` (erweitert um Fähigkeiten-Mapping) ### v9d – Phase 1 ✅ (Deployed 21.03.2026) - ✅ **Trainingstypen Basis:** DB-Schema, 23 Typen, API-Endpoints - ✅ **Logout-Button:** Im Header neben Avatar, mit Bestätigung - ✅ **Components:** TrainingTypeSelect, TrainingTypeDistribution ### v9d – Phase 1b ✅ (Abgeschlossen, auf develop) - ✅ ActivityPage: TrainingTypeSelect eingebunden - ✅ History: TrainingTypeDistribution Chart + Typ-Badges bei Aktivitäten - ✅ Apple Health Import: Automatisches Mapping (29 Typen) - ✅ Bulk-Kategorisierung: UI + Endpoints - ✅ Admin-CRUD: Vollständige Verwaltung inkl. UX-Optimierungen ### v9d – Phase 2+ 🔲 (Später) - 🔲 Ruhetage erfassen (rest_days Tabelle) - 🔲 Ruhepuls erfassen (vitals_log Tabelle) - 🔲 HF-Zonen + Erholungsstatus - 🔲 Schlaf-Modul 📚 Details: `.claude/docs/technical/MEMBERSHIP_SYSTEM.md` · `.claude/docs/architecture/FEATURE_ENFORCEMENT.md` ## Feature-Roadmap > Vollständiges Backlog: `.claude/docs/BACKLOG.md` > Beim Implementieren: verlinkte Dok-Datei zuerst lesen! | Version | Feature | Dokumentation | |---------|---------|---------------| | v9c | Membership (aktiv) | `technical/MEMBERSHIP_SYSTEM.md` ✅ | | v9d | Schlaf-Modul | `functional/SLEEP_MODULE.md` (ausstehend) | | v9d | Trainingstypen + HF | `functional/TRAINING_TYPES.md` ✅ | | v9e | Ziele + Vitalwerte | `functional/GOALS_VITALS.md` (ausstehend) | | v9f | KI-Prompt Flexibilisierung | `functional/AI_PROMPTS.md` ✅ | | v9g | Meditation + Selbstwahrnehmung | `functional/MEDITATION.md` (ausstehend) | | v9h | Connectoren + Stripe | ausstehend | | — | Responsive UI | `functional/RESPONSIVE_UI.md` ✅ | ## Deployment ``` Internet → Fritz!Box (privat.stommer.com) → Synology NAS → Raspberry Pi 5 (192.168.2.49) Git Workflow: develop → Auto-Deploy → dev.mitai.jinkendo.de (bodytrack-dev/, Port 3099/8099) main → Auto-Deploy → mitai.jinkendo.de (bodytrack/, Port 3002/8002) Gitea: http://192.168.2.144:3000/Lars/mitai-jinkendo Runner: Raspberry Pi (/home/lars/gitea-runner/) Manuell: cd /home/lars/docker/bodytrack[-dev] docker compose -f docker-compose[.dev-env].yml build --no-cache && up -d Migrations: Werden automatisch beim Container-Start ausgeführt (db_init.py) Nur nummerierte Dateien: backend/migrations/XXX_*.sql Tracking in schema_migrations Tabelle 📚 Details: .claude/docs/technical/MIGRATIONS.md ``` ## Datenbank-Schema (PostgreSQL 16) ``` profiles – Nutzer (role, pin_hash/bcrypt, email, tier) sessions – Auth-Tokens weight_log – Gewicht (profile_id, date, weight) circumference_log – 8 Umfangspunkte caliper_log – Hautfalten, 4 Methoden nutrition_log – Kalorien + Makros activity_log – Training photos – Progress-Fotos ai_insights – KI-Auswertungen (scope = prompt-slug) ai_prompts – Konfigurierbare Prompts (11 Standard) ai_usage – KI-Calls pro Tag pro Profil v9c neu (Membership): subscriptions · coupons · coupon_redemptions · features tier_limits · user_feature_restrictions · user_feature_usage access_grants · user_activity_log Infrastruktur: schema_migrations – Tracking für automatische DB-Migrationen Feature-Logging (Phase 2): /app/logs/feature-usage.log # JSON-Format, alle Feature-Zugriffe Schema-Datei: backend/schema.sql Migrationen: backend/migrations/*.sql (automatisch beim Start) ``` ## API & Auth ``` Alle Endpoints: /api/... Auth-Header: X-Auth-Token: Fehler: {"detail": "Fehlermeldung"} Rate Limit: HTTP 429 Auth-Flow: Login → E-Mail + Passwort → Token in localStorage Token → X-Auth-Token Header → require_auth() Profile-Id → immer aus Session, nie aus Header! SHA256 → automatisch zu bcrypt migriert beim Login ``` ## Umgebungsvariablen (.env) ``` DB_HOST/PORT/NAME/USER/PASSWORD # PostgreSQL OPENROUTER_API_KEY # KI OPENROUTER_MODEL=anthropic/claude-sonnet-4 SMTP_HOST/PORT/USER/PASS/FROM # E-Mail APP_URL=https://mitai.jinkendo.de ALLOWED_ORIGINS=https://mitai.jinkendo.de PHOTOS_DIR=/app/photos ``` ## Kritische Regeln für Claude Code ### Must-Do: 1. `api.js` für ALLE API-Calls nutzen – nie direktes `fetch()` ohne Token 2. `session: dict = Depends(require_auth)` als **separater** Parameter – nie in `Header()` einbetten 3. `bcrypt` für alle Passwort-Operationen 4. Neue DB-Spalten nur via Schema-Migration, nicht direkt 5. `npm install` (nicht npm ci) – kein package-lock.json ### Bekannte Fallstricke: ```python # ❌ FALSCH – führt zu ungeschütztem Endpoint: def endpoint(x: str = Header(default=None, session=Depends(require_auth))): # ✅ RICHTIG: def endpoint(x: str = Header(default=None), session: dict = Depends(require_auth)): ``` ```javascript // ❌ FALSCH – dayjs.week() existiert nicht ohne Plugin: dayjs(date).week() // ✅ RICHTIG – native ISO-Wochenberechnung: const w = (d => Math.ceil(((new Date(d.setDate(d.getDate()+4-(d.getDay()||7)))- new Date(d.getFullYear(),0,1))/86400000+1)/7))(new Date(date)) ``` ```python # PostgreSQL Boolean (nicht SQLite 0/1): WHERE active = true # ✅ WHERE active = 1 # ❌ ``` ## Design-System (Kurzreferenz) ```css /* Farben */ --accent: #1D9E75 --accent-dark: #085041 --danger: #D85A30 --bg · --surface · --surface2 · --border · --text1 · --text2 · --text3 /* Klassen */ .card · .btn · .btn-primary · .btn-secondary · .btn-full .form-input · .form-label · .form-row · .spinner /* Abstände */ Seiten-Padding: 16px · Card-Padding: 16-20px · Border-Radius: 12px/8px Bottom-Padding Mobile: 80px (Navigation) ``` > Vollständige CSS-Variablen und Komponenten-Muster: `frontend/src/app.css` > Responsive Layout-Spec: `.claude/docs/functional/RESPONSIVE_UI.md` ## Dokumentations-Referenzen > **Für Claude Code:** Beim Arbeiten an einem Thema die entsprechende Datei lesen: | Thema | Datei | |-------|-------| | Backend-Architektur, Router, DB-Zugriff | `.claude/docs/architecture/BACKEND.md` | | Frontend-Architektur, api.js, Komponenten | `.claude/docs/architecture/FRONTEND.md` | | **Feature-Enforcement (neue Features hinzufügen)** | `.claude/docs/architecture/FEATURE_ENFORCEMENT.md` | | **Database Migrations (Schema-Änderungen)** | `.claude/docs/technical/MIGRATIONS.md` | | Coding Rules (Pflichtregeln) | `.claude/docs/rules/CODING_RULES.md` | | Lessons Learned (Fehler vermeiden) | `.claude/docs/rules/LESSONS_LEARNED.md` | | Feature Backlog (Übersicht) | `.claude/docs/BACKLOG.md` | | **Pending Features (noch nicht enforced)** | `.claude/docs/PENDING_FEATURES.md` | | **Known Issues (Bugs & Tech Debt)** | `.claude/docs/KNOWN_ISSUES.md` | | Membership-System (v9c, technisch) | `.claude/docs/technical/MEMBERSHIP_SYSTEM.md` | | Trainingstypen + HF (v9d, fachlich) | `.claude/docs/functional/TRAINING_TYPES.md` | | KI-Prompt Flexibilisierung (v9f, fachlich) | `.claude/docs/functional/AI_PROMPTS.md` | | Responsive UI (fachlich) | `.claude/docs/functional/RESPONSIVE_UI.md` | ## Jinkendo App-Familie ``` mitai.jinkendo.de → Körper-Tracker (diese App) miken.jinkendo.de → Meditation (眉間) ikigai.jinkendo.de → Lebenssinn (生き甲斐) shinkan.jinkendo.de → Kampfsport (真観) ```