- Mark v9c as deployed to production (21.03.2026) - Add BUG-005 to BUG-008 (login/verify navigation fixes) - Document TrialBanner mailto change (on develop) - Mark v9d as in progress Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
279 lines
11 KiB
Markdown
279 lines
11 KiB
Markdown
# 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 (nicht deployed) 📦
|
||
- ✅ **TrialBanner mailto:** "Abo wählen" → mailto:mitai@jinkendo.de (Vorbereitung für zentrales Abo-System)
|
||
- 📚 Dokumentation: `.claude/docs/technical/CENTRAL_SUBSCRIPTION_SYSTEM.md`
|
||
|
||
### v9d – In Arbeit 🔄
|
||
- 🔲 Schlaf-Modul (Erfassung, Import, Auswertung, Korrelationen)
|
||
- 🔲 Trainingstypen (Cardio, Kraft, HIIT, Mobility, Erholung)
|
||
- 🔲 Ruhetage erfassen
|
||
- 🔲 Ruhepuls + HF-Zonen + VO2Max-Schätzung
|
||
|
||
📚 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: <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 (真観)
|
||
```
|