mitai-jinkendo/.claude/docs/architecture/BACKEND.md
Lars 7940dc7560 docs: Struktur .claude/docs versionieren, working/, Gitea-Index, Regeln
- .gitignore: .claude/docs, rules, commands tracken; settings.local weiter ignorieren
- DOCUMENTATION.md: verbindliche Ablage functional/technical/working/issues
- .claude/README.md: Agent-Einstieg; GITEA_ISSUES_INDEX aus MCP (Stand 2026-04-08)
- Arbeitspapiere von docs/ nach .claude/docs/working/ verschoben
- docs/MEMBERSHIP_SYSTEM.md als Stub; kanonisch technical/MEMBERSHIP_SYSTEM.md
- CLAUDE.md Pflichtlektüre und Links angepasst; docs/README.md vereinfacht

Made-with: Cursor
2026-04-08 13:01:49 +02:00

3.3 KiB
Raw Permalink Blame History

Backend-Architektur

Struktur

backend/
├── main.py          # App-Setup + Router-Registration (~75 Zeilen)
├── db.py            # PostgreSQL Connection Pool + get_cursor() Helper
├── auth.py          # hash_pin · verify_pin · require_auth · require_admin
├── models.py        # Alle Pydantic Models (LoginRequest, ProfileUpdate, etc.)
├── schema.sql       # Vollständiges PostgreSQL-Schema
└── routers/
    ├── auth.py           # Login, Logout, Password Reset, PIN (7 Endpoints)
    ├── profiles.py       # Profile CRUD + Current User (7 Endpoints)
    ├── weight.py         # Weight Tracking (5 Endpoints)
    ├── circumference.py  # Body Measurements (4 Endpoints)
    ├── caliper.py        # Skinfold Tracking (4 Endpoints)
    ├── activity.py       # Workout Logging + CSV Import (6 Endpoints)
    ├── nutrition.py      # Nutrition + FDDB Import (4 Endpoints)
    ├── photos.py         # Progress Photos (3 Endpoints)
    ├── insights.py       # AI Analysis + Pipeline (8 Endpoints)
    ├── prompts.py        # AI Prompt Management (2 Endpoints)
    ├── admin.py          # User Management (7 Endpoints)
    ├── stats.py          # Dashboard Stats (1 Endpoint)
    ├── exportdata.py     # CSV/JSON/ZIP Export (3 Endpoints)
    └── importdata.py     # ZIP Import (1 Endpoint)

Router registrieren (main.py Pattern)

from routers import auth, profiles, weight
app.include_router(auth.router, prefix="/api")
app.include_router(profiles.router, prefix="/api")

Neuen Router anlegen

  1. backend/routers/mein_modul.py erstellen
  2. router = APIRouter() definieren
  3. Endpoints mit @router.get/post/put/delete definieren
  4. In main.py importieren und registrieren
  5. Schema-Änderungen in schema.sql + Migration

Datenbank-Zugriff

# ✅ Immer so:
from db import get_db, get_cursor

with get_db() as conn:
    cur = get_cursor(conn)          # RealDictCursor  gibt Dicts zurück
    cur.execute("SELECT * FROM weight_log WHERE profile_id = %s", (pid,))
    rows = cur.fetchall()           # Liste von Dicts

# ❌ Nie so (SQLite-Syntax):
conn.execute("SELECT * FROM weight_log WHERE profile_id=?", (pid,))

Auth-Pattern

# Standard-Endpoint mit Auth:
@router.get("/mein-endpoint")
def mein_endpoint(session: dict = Depends(require_auth)):
    pid = session['profile_id']
    role = session['role']

# Admin-only:
@router.get("/admin-endpoint")
def admin_endpoint(session: dict = Depends(require_admin)):
    pass

# ❌ NIEMALS so (session innerhalb Header eingebettet):
def endpoint(x: str = Header(default=None, session=Depends(require_auth))):

PostgreSQL vs. SQLite Unterschiede

# Platzhalter:
%s          # PostgreSQL ✅
?           # SQLite ❌

# Boolean:
WHERE active = true    # PostgreSQL ✅
WHERE active = 1       # SQLite ❌

# Returning:
INSERT INTO ... RETURNING id    # PostgreSQL ✅ (für neue IDs)

# JSON:
JSONB                  # PostgreSQL (für flexible Felder)

DB-Schema ändern

  1. backend/schema.sql anpassen
  2. Migration schreiben (ALTER TABLE oder neues Skript)
  3. Container neu bauen: docker compose build --no-cache backend
  4. NIEMALS Spalten direkt löschen/umbenennen ohne Datenmigration