# Architektur-Regeln – Mitai Jinkendo

> **PFLICHTLEKTÜRE für Claude Code vor jeder Implementierung.**
> Diese Regeln sind verbindlich und dürfen nicht ohne explizite
> Genehmigung des Nutzers abgeändert werden.

---

## 1. Router-Architektur

### 1.1 Ein Modul = Ein Router
Jedes fachliche Modul hat genau eine Router-Datei in `backend/routers/`.

```
backend/routers/
├── auth.py           # Authentifizierung
├── profiles.py       # Nutzerprofile
├── weight.py         # Gewichts-Tracking
├── sleep.py          # Schlaf-Modul
├── training_types.py # Trainingstypen + HF
└── ...               # je neues Modul = neue Datei
```

**Regeln:**
- Kein Endpoint darf außerhalb seines thematischen Routers definiert werden
- Neue Module immer als neue Router-Datei anlegen, nie in bestehende einfügen
- Router in `main.py` registrieren: `app.include_router(modul.router, prefix="/api")`
- Router-Datei-Name = Modul-Name in `version.py` MODULE_VERSIONS

### 1.2 API-First Prinzip
Jede Funktion ist zuerst als API-Endpoint implementiert – die UI nutzt ausschließlich
diese Endpoints über `api.js`. Keine Business-Logik im Frontend.

```python
# ✅ Richtig: Logik im Backend-Endpoint
@router.get("/sleep/stats")
def get_sleep_stats(session=Depends(require_auth)):
    # Berechnung hier
    return {"avg_duration": ..., "sleep_debt": ...}

# ❌ Falsch: Berechnung im Frontend
const sleepDebt = entries.reduce((sum, e) => sum + (goal - e.duration), 0)
```

### 1.3 Einheitliche Fehlerbehandlung
```python
# ✅ Immer dieses Format:
raise HTTPException(status_code=404, detail="Eintrag nicht gefunden")
# Response: {"detail": "Eintrag nicht gefunden"}

# ❌ Nie eigene Formate:
return {"error": "not found"}
return {"message": "Fehler", "success": False}
```

---

## 2. Versionskontrollsystem

### 2.1 Versionierungsschema
**Semantic Versioning: `MAJOR.MINOR.PATCH`**

| Typ | Wann | Beispiel |
|-----|------|---------|
| MAJOR | Breaking Change, DB-Migration inkompatibel | 9.0.0 → 10.0.0 |
| MINOR | Neues Feature, neues Modul | 9.2.0 → 9.3.0 |
| PATCH | Bugfix, kleine Änderung, Refactor | 9.3.0 → 9.3.1 |

### 2.2 Versions-Dateien

**Backend: `backend/version.py`**
```python
APP_VERSION = "9.3.0"
BUILD_DATE  = "2026-03-22"

MODULE_VERSIONS = {
    "auth":           "1.2.0",
    "profiles":       "1.1.0",
    "weight":         "1.0.3",
    "circumference":  "1.0.1",
    "caliper":        "1.0.1",
    "activity":       "1.1.0",
    "nutrition":      "1.0.2",
    "photos":         "1.0.0",
    "insights":       "1.3.0",
    "prompts":        "1.1.0",
    "admin":          "1.2.0",
    "stats":          "1.0.1",
    "exportdata":     "1.1.0",
    "importdata":     "1.0.0",
    "membership":     "2.1.0",
}

CHANGELOG = [
    {
        "version": "9.3.0",
        "date": "2026-03-22",
        "changes": [
            "Feature: Sleep Module (sleep_log, JSONB-Segmente)",
            "Feature: Vitalwerte-Seite in Navigation",
            "Feature: Trainingstypen-Kategorisierung",
        ]
    },
    {
        "version": "9.2.1",
        "date": "2026-03-20",
        "changes": [
            "Fix: Feature-Enforcement Rollback",
            "Fix: Erholungsstatus-Gewichtung korrigiert",
        ]
    },
]
```

**Frontend: `frontend/src/version.js`**
```javascript
export const APP_VERSION  = "9.3.0"
export const BUILD_DATE   = "2026-03-22"

export const PAGE_VERSIONS = {
    Dashboard:        "1.3.0",
    LoginScreen:      "1.1.0",
    WeightPage:       "1.0.3",
    ActivityPage:     "1.2.0",
    NutritionPage:    "1.1.0",
    AnalysisPage:     "1.3.0",
    SettingsPage:     "1.4.0",
    AdminPanel:       "1.2.0",
    SubscriptionPage: "1.0.0",
    // Neue Seiten hier eintragen
}
```

### 2.3 Versions-Endpoint

**`GET /api/version`** – öffentlich (kein Auth erforderlich)

```json
{
  "app_version": "9.3.0",
  "build_date": "2026-03-22",
  "backend_version": "9.3.0",
  "modules": {
    "auth": "1.2.0",
    "sleep": "1.0.0"
  },
  "db_schema_version": "20260322",
  "environment": "production"
}
```

Dieser Endpoint wird in `backend/routers/version.py` implementiert und liest
direkt aus `version.py`.

### 2.4 Versions-Anzeige in der App

**Settings-Seite – Versions-Panel:**
```
System-Versionen
─────────────────────────────────────
App (gesamt)      9.3.0
Backend           9.3.0    ✓ erreichbar
Frontend          9.3.0    ✓ geladen
DB-Schema         20260322
Umgebung          production
─────────────────────────────────────
Module
auth              1.2.0
sleep             1.0.0
membership        2.1.0
[alle Module...]
─────────────────────────────────────
[Changelog]    [Cache leeren]
```

Frontend ruft beim Laden der Settings-Seite `/api/version` ab und vergleicht
mit der eigenen `APP_VERSION` aus `version.js`. Bei Abweichung: Warnung anzeigen.

### 2.5 Pflicht-Regel: Versions-Bump bei jedem Commit

**Jede Code-Änderung erfordert:**
1. Versions-Bump in `backend/version.py` (APP_VERSION + betroffenes MODULE_VERSION)
2. Versions-Bump in `frontend/src/version.js` (APP_VERSION + betroffene PAGE_VERSION)
3. Changelog-Eintrag in `backend/version.py` CHANGELOG

**Claude Code prüft das im `/deploy` Command automatisch.**

Kein Commit ohne Versions-Bump – keine Ausnahme.

### 2.6 DB-Schema-Version

Format: `YYYYMMDD` (Datum der letzten Migration)

Gespeichert in `backend/version.py`:
```python
DB_SCHEMA_VERSION = "20260322"
```

Bei jeder Schema-Änderung (ALTER TABLE, neue Tabelle) → DB_SCHEMA_VERSION aktualisieren.

---

## 3. Datenbankregeln

### 3.1 Pflichtfelder für neue Tabellen
```sql
-- Jede neue Tabelle braucht:
id          SERIAL PRIMARY KEY,
created_at  TIMESTAMP DEFAULT NOW(),
updated_at  TIMESTAMP DEFAULT NOW()
```

### 3.2 Source-Tracking bei Import-Daten
Tabellen die Daten aus externen Quellen empfangen brauchen:
```sql
source  VARCHAR(50) DEFAULT 'manual'
-- Werte: 'manual' | 'apple_health' | 'garmin' | 'withings'
```

Manuelle Einträge (`source = 'manual'`) haben IMMER Vorrang bei Reimport:
```sql
-- Reimport überschreibt nur nicht-manuelle Einträge:
INSERT INTO sleep_log (...) ON CONFLICT (profile_id, date)
DO UPDATE SET ... WHERE sleep_log.source != 'manual'
```

### 3.3 Profile-ID Isolation
Jede Tabelle mit Nutzerdaten hat `profile_id` als Foreign Key.
Kein Endpoint gibt Daten eines anderen Profils zurück.
Profile-ID kommt IMMER aus der Session, nie aus Request-Parametern.

### 3.4 Boolean-Werte
```sql
-- PostgreSQL Boolean (nicht SQLite 0/1):
WHERE active = true    ✓
WHERE active = 1       ✗
```

---

## 4. Frontend-Regeln

### 4.1 Alle API-Calls über api.js
```javascript
// ✅ Richtig:
import { api } from '../utils/api'
const data = await api.listSleep()

// ❌ Falsch:
const r = await fetch('/api/sleep')
```

### 4.2 Neue Seite = Eintrag in PAGE_VERSIONS
Jede neue Seite in `frontend/src/version.js` registrieren.

### 4.3 CSS-Variablen statt Hardcoded-Farben
```javascript
// ✅ Richtig:
style={{color: 'var(--accent)'}}

// ❌ Falsch:
style={{color: '#1D9E75'}}
```

### 4.4 Fehlerbehandlung in allen async Funktionen
```javascript
try {
    const data = await api.meinEndpoint()
    setData(data)
} catch(e) {
    setError(e.message)
} finally {
    setLoading(false)
}
```

---

## 5. Git & Deployment-Regeln

### 5.1 Nie direkt auf main pushen
Immer über Pull Request in Gitea: develop → main.
develop Branch niemals löschen.

### 5.2 Commit-Message Format
```
feat:     neues Feature oder Modul
fix:      Bugfix
refactor: Umbau ohne Funktionsänderung
docs:     Dokumentation
version:  Versions-Bump
ci:       CI/CD Änderungen
chore:    Maintenance
```

### 5.3 Versions-Bump im Commit
```
feat: Sleep Module v1.0.0

- sleep_log Tabelle mit JSONB-Segmenten
- Import aus Apple Health CSV
- Korrelationen Schlaf <-> Ruhepuls

version: 9.3.0 (backend + frontend)
module:  sleep 1.0.0
```

---

## 6. Dokumentations-Regeln

### 6.1 Neue Module dokumentieren
Bei jedem neuen Modul:
1. Fachliche Spec: `.claude/docs/functional/MODUL_NAME.md`
2. Technische Spec: `.claude/docs/technical/MODUL_NAME.md`
3. Nach Fertigstellung: `.claude/library/` aktualisieren

### 6.2 CLAUDE.md aktuell halten
Nach größeren Änderungen CLAUDE.md Versions-Tabelle aktualisieren.

### 6.3 Lessons Learned dokumentieren
Jeder Rollback oder schwerer Bug → Eintrag in `.claude/rules/LESSONS_LEARNED.md`

---

## Zusammenfassung: Checkliste vor jedem Commit

```
[ ] Versions-Bump in backend/version.py (APP_VERSION + MODULE)
[ ] Versions-Bump in frontend/src/version.js (APP_VERSION + PAGE)
[ ] Changelog-Eintrag in backend/version.py
[ ] DB_SCHEMA_VERSION aktualisiert (wenn Schema geändert)
[ ] Neues Modul in PAGE_VERSIONS / MODULE_VERSIONS eingetragen
[ ] Auth auf alle neuen Endpoints (require_auth)
[ ] Fehlerformat einheitlich (HTTPException mit detail)
[ ] Neue Tabellen haben created_at + updated_at
[ ] Import-Tabellen haben source-Feld
[ ] api.js für alle Frontend API-Calls
```
