# API-Referenz ## Basis-URLs | Umgebung | URL | |----------|-----| | **Production** | `https://mitai.jinkendo.de/api` | | **Development** | `https://dev.mitai.jinkendo.de/api` | | **Local** | `http://localhost:8000/api` (Backend direkt) | --- ## Authentifizierung **Alle geschützten Endpoints** benötigen einen Auth-Token im Header: ```http GET /api/weight X-Auth-Token: jT9z3xK...pQ2vL ``` **Token-Beschaffung:** `POST /api/auth/login` → `{"token": "..."}` **Storage:** `localStorage.bodytrack_token` (Frontend) --- ## Fehler-Codes | Status | Bedeutung | Beispiel | |--------|-----------|----------| | **200** | Erfolg | `{"data": [...]}` | | **201** | Erstellt | `{"id": "uuid", ...}` | | **400** | Bad Request | `{"detail": "Ungültige Eingabe"}` | | **401** | Unauthorized | `{"detail": "Nicht eingeloggt"}` | | **403** | Forbidden | `{"detail": "Nur für Admins"}` oder `{"detail": "Feature-Limit erreicht"}` | | **404** | Not Found | `{"detail": "Eintrag nicht gefunden"}` | | **429** | Too Many Requests | `{"detail": "Rate limit exceeded: 5 per 1 minute"}` | | **500** | Server Error | `{"detail": "Interner Fehler"}` | **Standard-Fehler-Format:** ```json { "detail": "Fehlermeldung" } ``` --- ## Rate Limits | Endpoint | Limit | Grund | |----------|-------|-------| | `POST /api/auth/login` | 5/minute | Brute-Force-Schutz | | `POST /api/auth/register` | 3/hour | Spam-Prevention | | `POST /api/auth/forgot-password` | 3/minute | E-Mail-Flooding-Schutz | | `POST /api/auth/resend-verification` | 3/hour | E-Mail-Flooding-Schutz | **Andere Endpoints:** Keine Rate-Limits (Feature-Limits via Membership-System) --- ## Endpoints nach Modul ### 1. Auth (`/api/auth/*`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `POST` | `/auth/login` | ❌ | `{email, password}` | `{token, profile_id, name, role, expires_at}` | Login mit E-Mail + Passwort | | `POST` | `/auth/logout` | ✅ | – | `{ok: true}` | Logout (löscht Session) | | `GET` | `/auth/me` | ✅ | – | `{id, name, email, role, tier, ...}` | Aktuelles Profil abrufen | | `GET` | `/auth/status` | ❌ | – | `{status: "ok", version: "v9b"}` | Health Check | | `PUT` | `/auth/pin` | ✅ | `{pin}` | `{ok: true}` | PIN/Passwort ändern | | `POST` | `/auth/forgot-password` | ❌ | `{email}` | `{ok: true, message}` | Passwort-Reset anfordern | | `POST` | `/auth/reset-password` | ❌ | `{token, new_password}` | `{ok: true, message}` | Passwort-Reset bestätigen | | `POST` | `/auth/register` | ❌ | `{name, email, password}` | `{ok: true, message}` | Selbst-Registrierung | | `GET` | `/auth/verify/{token}` | ❌ | – | `{ok: true, token, profile}` | E-Mail-Verifizierung | | `POST` | `/auth/resend-verification` | ❌ | `{email}` | `{ok: true, message}` | Verifizierungs-E-Mail erneut senden | **Rate Limits:** Siehe Tabelle oben --- ### 2. Profiles (`/api/profiles/*`, `/api/profile`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `GET` | `/profile` | ✅ | – | `{id, name, email, role, tier, ...}` | Aktives Profil | | `PUT` | `/profile` | ✅ | `{name?, sex?, dob?, height?, goal_weight?, goal_bf_pct?, avatar_color?}` | `{ok: true}` | Profil aktualisieren | | `GET` | `/profiles` | ✅ | – | `[{id, name, ...}, ...]` | Alle Profile (Multi-User, derzeit nicht genutzt) | | `POST` | `/profiles` | ✅ | `{name, ...}` | `{id, ...}` | Profil erstellen (Multi-User) | | `PUT` | `/profiles/{id}` | ✅ | `{name?, ...}` | `{ok: true}` | Profil bearbeiten | | `DELETE` | `/profiles/{id}` | ✅ | – | `{ok: true}` | Profil löschen | --- ### 3. Weight (`/api/weight/*`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `GET` | `/weight` | ✅ | `?limit=365` | `[{id, date, weight, note, source, created}, ...]` | Gewichtseinträge abrufen | | `POST` | `/weight` | ✅ | `{date, weight, note?}` | `{id, date, weight, ...}` | Gewicht eintragen (Upsert) | | `PUT` | `/weight/{id}` | ✅ | `{date, weight, note?}` | `{ok: true}` | Eintrag bearbeiten | | `DELETE` | `/weight/{id}` | ✅ | – | `{ok: true}` | Eintrag löschen | | `GET` | `/weight/stats` | ✅ | – | `{latest, avg_7d, avg_30d, delta_7d, delta_30d, trend}` | Gewichts-Statistiken | **Feature-Limits:** `weight_entries` (v9c Phase 4: Enforcement aktiv) --- ### 4. Circumferences (`/api/circumferences/*`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `GET` | `/circumferences` | ✅ | `?limit=100` | `[{id, date, c_neck, c_chest, c_waist, c_belly, c_hip, c_thigh, c_calf, c_arm, notes, photo_id}, ...]` | Umfangsmessungen | | `POST` | `/circumferences` | ✅ | `{date, c_neck?, c_chest?, ...}` | `{id, ...}` | Messung eintragen (Upsert) | | `PUT` | `/circumferences/{id}` | ✅ | `{date, ...}` | `{ok: true}` | Bearbeiten | | `DELETE` | `/circumferences/{id}` | ✅ | – | `{ok: true}` | Löschen | **Feature-Limits:** `circumference_entries` --- ### 5. Caliper (`/api/caliper/*`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `GET` | `/caliper` | ✅ | `?limit=100` | `[{id, date, sf_method, sf_chest, sf_abdomen, ..., body_fat_pct, lean_mass, fat_mass, notes}, ...]` | Hautfaltenmessungen | | `POST` | `/caliper` | ✅ | `{date, sf_method, sf_chest?, ...}` | `{id, body_fat_pct, ...}` | Messung eintragen (berechnet KF% automatisch) | | `PUT` | `/caliper/{id}` | ✅ | `{date, ...}` | `{ok: true}` | Bearbeiten | | `DELETE` | `/caliper/{id}` | ✅ | – | `{ok: true}` | Löschen | **Methoden:** `jackson3`, `jackson7`, `durnin`, `parrillo` **Feature-Limits:** `caliper_entries` --- ### 6. Activity (`/api/activity/*`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `GET` | `/activity` | ✅ | `?limit=200` | `[{id, date, start_time, end_time, activity_type, duration_min, kcal_active, hr_avg, hr_max, distance_km, rpe, source, notes}, ...]` | Aktivitäten | | `POST` | `/activity` | ✅ | `{date, activity_type, duration_min, ...}` | `{id, ...}` | Aktivität erstellen | | `PUT` | `/activity/{id}` | ✅ | `{date, ...}` | `{ok: true}` | Bearbeiten | | `DELETE` | `/activity/{id}` | ✅ | – | `{ok: true}` | Löschen | | `GET` | `/activity/stats` | ✅ | – | `{total_activities, total_kcal, avg_duration, ...}` | Statistiken | | `GET` | `/activity/uncategorized` | ✅ | – | `[{activity_type, count}, ...]` | Unkategorisierte Aktivitäten | | `POST` | `/activity/bulk-categorize` | ✅ | `[{activity_type, training_type_id}, ...]` | `{ok: true, updated_count}` | Bulk-Kategorisierung (lernendes System) | | `POST` | `/activity/import-csv` | ✅ | `FormData(file)` | `{imported, skipped, failed, errors}` | Apple Health CSV-Import | **Feature-Limits:** `activity_entries` --- ### 7. Nutrition (`/api/nutrition/*`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `GET` | `/nutrition` | ✅ | `?limit=365` | `[{id, date, kcal, protein_g, fat_g, carbs_g, source}, ...]` | Ernährungsdaten | | `GET` | `/nutrition/by-date/{date}` | ✅ | – | `{id, date, kcal, ...}` oder `null` | Eintrag für bestimmtes Datum | | `POST` | `/nutrition` | ✅ | `?date=YYYY-MM-DD&kcal=2000&protein_g=150&fat_g=70&carbs_g=200` | `{id, ...}` | Eintrag erstellen (Upsert) | | `PUT` | `/nutrition/{id}` | ✅ | `?kcal=2000&...` | `{ok: true}` | Bearbeiten | | `DELETE` | `/nutrition/{id}` | ✅ | – | `{ok: true}` | Löschen | | `GET` | `/nutrition/correlations` | ✅ | – | `{weight_vs_kcal: [...], bf_vs_protein: [...]}` | Korrelationen | | `GET` | `/nutrition/weekly` | ✅ | `?weeks=16` | `[{week, year, avg_kcal, avg_protein, ...}, ...]` | Wochendaten | | `GET` | `/nutrition/import-history` | ✅ | – | `[{date, count}, ...]` | Import-Historie | | `POST` | `/nutrition/import-csv` | ✅ | `FormData(file)` | `{imported, skipped, failed, errors}` | CSV-Import (FDDB, MyFitnessPal) | **Feature-Limits:** `nutrition_entries`, `data_import` --- ### 8. Photos (`/api/photos/*`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `GET` | `/photos` | ✅ | – | `[{id, date, path, created}, ...]` | Alle Fotos | | `GET` | `/photos/{id}` | ✅ | `?token=...` (optional) | Binary (JPEG) | Foto abrufen (Token für tag) | | `POST` | `/photos` | ✅ | `FormData(file, date?)` | `{id, path, date}` | Foto hochladen | | `DELETE` | `/photos/{id}` | ✅ | – | `{ok: true}` | Foto löschen | **Feature-Limits:** `photos` **Hinweis:** Token-Parameter für `GET /photos/{id}` erlaubt Zugriff via `` tag (ohne Header-Support) --- ### 9. AI Insights (`/api/insights/*`, `/api/ai/*`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `GET` | `/insights` | ✅ | – | `[{id, scope, content, created}, ...]` | Alle Insights | | `GET` | `/insights/latest` | ✅ | – | `{slug: content, ...}` | Neueste Insights pro Scope | | `POST` | `/insights/trend` | ✅ | – | `{content, usage}` | Trend-Analyse (Gewicht) | | `POST` | `/insights/run/{slug}` | ✅ | – | `{content, usage}` | Einzelnen Prompt ausführen | | `POST` | `/insights/pipeline` | ✅ | – | `{content, usage}` | 3-stufige Pipeline | **Feature-Limits:** `ai_calls` (pro Aufruf), `ai_pipeline` (für Pipeline) **Prompts:** Konfigurierbar via `/api/prompts` --- ### 10. AI Prompts (`/api/prompts/*`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `GET` | `/prompts` | ✅ | – | `[{id, slug, name, description, template, active, sort_order}, ...]` | Alle Prompts | | `PUT` | `/prompts/{id}` | 🔒 Admin | `{name?, description?, template?, active?, sort_order?}` | `{ok: true}` | Prompt bearbeiten | **Standard-Prompts:** - `weight-trend` – Gewichts-Trend-Analyse - `nutrition-analysis` – Ernährungs-Auswertung - `training-plan` – Trainings-Empfehlungen - `body-composition` – Körperzusammensetzung - `progress-summary` – Fortschritts-Zusammenfassung - `pipeline` – Master-Schalter für Pipeline --- ### 11. Admin (`/api/admin/*`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `GET` | `/admin/profiles` | 🔒 Admin | – | `[{id, name, email, role, tier, ...}, ...]` | Alle Profile | | `POST` | `/admin/profiles` | 🔒 Admin | `{name, email, password, role?}` | `{id, ...}` | Profil erstellen | | `DELETE` | `/admin/profiles/{id}` | 🔒 Admin | – | `{ok: true}` | Profil löschen | | `PUT` | `/admin/profiles/{id}/permissions` | 🔒 Admin | `{ai_enabled?, ai_limit_day?, export_enabled?}` | `{ok: true}` | Permissions setzen | --- ### 12. Stats (`/api/stats`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `GET` | `/stats` | ✅ | – | `{weight: {...}, nutrition: {...}, activity: {...}, body_comp: {...}}` | Dashboard-Stats | **Response-Struktur:** ```json { "weight": { "latest": 75.5, "avg_7d": 75.8, "avg_30d": 76.2, "delta_7d": -0.3, "delta_30d": -0.7 }, "nutrition": { "avg_kcal_7d": 2100, "avg_protein_7d": 150, "days_logged_7d": 6 }, "activity": { "total_activities_7d": 5, "total_kcal_7d": 2500, "avg_duration_7d": 45 }, "body_comp": { "latest_bf_pct": 12.5, "latest_lean_mass": 65.8 } } ``` --- ### 13. Export (`/api/export/*`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `GET` | `/export/csv` | ✅ | – | Binary (CSV) | Alle Daten als CSV | | `GET` | `/export/json` | ✅ | – | Binary (JSON) | Alle Daten als JSON | | `GET` | `/export/zip` | ✅ | – | Binary (ZIP) | Alle Daten + Fotos als ZIP | **Feature-Limits:** `data_export` **Dateiname:** `mitai-export-YYYY-MM-DD.[csv|json|zip]` **ZIP-Struktur:** ``` mitai-export-2026-03-23.zip ├── data.json ├── photos/ │ ├── photo_uuid1.jpg │ └── photo_uuid2.jpg └── README.txt ``` --- ### 14. Import (`/api/import/*`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `POST` | `/import/backup` | ✅ | `FormData(file)` | `{imported: {...}, skipped: {...}, failed: {...}}` | JSON-Backup importieren | **Feature-Limits:** `data_import` **Format:** JSON-Export von `/export/json` **Hinweis:** Überschreibt keine existierenden Einträge (Upsert-Logik) --- ## Subscription System (v9c) ### 15. Subscription (`/api/subscription/*`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `GET` | `/subscription/me` | ✅ | – | `{tier, tier_expires_at, trial_ends_at, invited_by, ...}` | Abo-Status | | `GET` | `/subscription/usage` | ✅ | – | `{feature_id: {used, limit, remaining, allowed}, ...}` | Feature-Usage | | `GET` | `/subscription/limits` | ✅ | – | `{feature_id: limit, ...}` | Feature-Limits für aktuelles Tier | --- ### 16. Coupons (`/api/coupons/*`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `POST` | `/coupons/redeem` | ✅ | `{code}` | `{ok: true, tier_id, valid_days, message}` | Coupon einlösen | | `GET` | `/coupons` | 🔒 Admin | – | `[{id, code, tier_id, valid_days, max_uses, ...}, ...]` | Alle Coupons | | `POST` | `/coupons` | 🔒 Admin | `{code, tier_id, valid_days, max_uses?}` | `{id, ...}` | Coupon erstellen | | `PUT` | `/coupons/{id}` | 🔒 Admin | `{...}` | `{ok: true}` | Bearbeiten | | `DELETE` | `/coupons/{id}` | 🔒 Admin | – | `{ok: true}` | Löschen | | `GET` | `/coupons/{id}/redemptions` | 🔒 Admin | – | `[{profile_id, redeemed_at}, ...]` | Einlösungen | --- ### 17. Features (`/api/features/*`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `GET` | `/features` | ✅ | – | `[{id, name, description, limit_type, reset_period, default_limit, active}, ...]` | Alle Features | | `GET` | `/features/usage` | ✅ | – | `[{feature_id, feature_name, limit, used, remaining, allowed, reason}, ...]` | Feature-Usage für aktuellen User | | `POST` | `/features` | 🔒 Admin | `{id, name, description, limit_type, reset_period, default_limit}` | `{id, ...}` | Feature erstellen | | `PUT` | `/features/{id}` | 🔒 Admin | `{...}` | `{ok: true}` | Bearbeiten | | `DELETE` | `/features/{id}` | 🔒 Admin | – | `{ok: true}` | Löschen | **Limit-Types:** `count` (zählbar), `boolean` (on/off) **Reset-Periods:** `never`, `daily`, `monthly` --- ### 18. Tiers (`/api/tiers/*`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `GET` | `/tiers` | 🔒 Admin | – | `[{id, name, description, price_monthly, active}, ...]` | Alle Tiers | | `POST` | `/tiers` | 🔒 Admin | `{id, name, description, price_monthly}` | `{id, ...}` | Tier erstellen | | `PUT` | `/tiers/{id}` | 🔒 Admin | `{...}` | `{ok: true}` | Bearbeiten | | `DELETE` | `/tiers/{id}` | 🔒 Admin | – | `{ok: true}` | Löschen | **Standard-Tiers:** `free`, `basic`, `premium`, `selfhosted` --- ### 19. Tier Limits (`/api/tier-limits/*`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `GET` | `/tier-limits` | 🔒 Admin | – | `{tiers: [...], features: [...], matrix: {...}}` | Tier-Limits-Matrix | | `PUT` | `/tier-limits` | 🔒 Admin | `{tier_id, feature_id, limit_value}` | `{ok: true}` | Limit setzen | | `PUT` | `/tier-limits/batch` | 🔒 Admin | `{updates: [{tier_id, feature_id, limit_value}, ...]}` | `{ok: true}` | Batch-Update | **Matrix-Format:** ```json { "tiers": ["free", "basic", "premium", "selfhosted"], "features": [ {"id": "weight_entries", "name": "Gewichtseinträge", ...}, ... ], "matrix": { "weight_entries": { "free": 100, "basic": 1000, "premium": null, "selfhosted": null }, ... } } ``` --- ### 20. User Restrictions (`/api/user-restrictions/*`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `GET` | `/user-restrictions` | 🔒 Admin | `?profile_id=...` | `[{id, profile_id, feature_id, limit_value}, ...]` | User-spezifische Limits | | `POST` | `/user-restrictions` | 🔒 Admin | `{profile_id, feature_id, limit_value}` | `{id, ...}` | Limit setzen | | `PUT` | `/user-restrictions/{id}` | 🔒 Admin | `{limit_value}` | `{ok: true}` | Bearbeiten | | `DELETE` | `/user-restrictions/{id}` | 🔒 Admin | – | `{ok: true}` | Löschen | **Verwendung:** Individuelle Limits überschreiben Tier-Limits --- ### 21. Access Grants (`/api/access-grants/*`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `GET` | `/access-grants` | 🔒 Admin | `?profile_id=...&active_only=true` | `[{id, profile_id, tier_id, valid_from, valid_until, source, is_active}, ...]` | Zeitlich begrenzte Tier-Zugriffe | | `POST` | `/access-grants` | 🔒 Admin | `{profile_id, tier_id, valid_from, valid_until, source?}` | `{id, ...}` | Grant erstellen | | `PUT` | `/access-grants/{id}` | 🔒 Admin | `{...}` | `{ok: true}` | Bearbeiten | | `DELETE` | `/access-grants/{id}` | 🔒 Admin | – | `{ok: true}` | Revoke | **Quellen:** `coupon`, `trial`, `manual`, `gift` --- ## Training Types (v9d) ### 22. Training Types (`/api/training-types/*`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `GET` | `/training-types` | ✅ | – | `{category: [{id, name, category, color, icon}, ...], ...}` | Gruppiert nach Kategorie | | `GET` | `/training-types/flat` | ✅ | – | `[{id, name, category, ...}, ...]` | Flache Liste | | `GET` | `/training-types/categories` | ✅ | – | `[{id, name, icon, color}, ...]` | Kategorien-Metadaten | **Kategorien:** Kraft, Cardio, Flexibilität, Spiel & Sport, Alltag & Bewegung, Outdoor & Natur, Geist & Meditation --- ### 23. Admin Training Types (`/api/admin/training-types/*`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `GET` | `/admin/training-types` | 🔒 Admin | – | `[{id, name, category, color, icon, abilities}, ...]` | Alle Typen (inkl. abilities JSONB) | | `GET` | `/admin/training-types/{id}` | 🔒 Admin | – | `{id, name, ...}` | Einzelner Typ | | `POST` | `/admin/training-types` | 🔒 Admin | `{name, category, color?, icon?}` | `{id, ...}` | Typ erstellen | | `PUT` | `/admin/training-types/{id}` | 🔒 Admin | `{name?, category?, color?, icon?, abilities?}` | `{ok: true}` | Bearbeiten | | `DELETE` | `/admin/training-types/{id}` | 🔒 Admin | – | `{ok: true}` | Löschen | | `GET` | `/admin/training-types/taxonomy/abilities` | 🔒 Admin | – | `{categories: [...], abilities: [...]}` | Abilities-Taxonomie (v9f) | --- ### 24. Activity Mappings (`/api/admin/activity-mappings/*`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `GET` | `/admin/activity-mappings` | 🔒 Admin | `?profile_id=...&global_only=true` | `[{id, activity_type, training_type_id, profile_id, is_global}, ...]` | Lernendes Mapping-System | | `GET` | `/admin/activity-mappings/{id}` | 🔒 Admin | – | `{id, ...}` | Einzelnes Mapping | | `POST` | `/admin/activity-mappings` | 🔒 Admin | `{activity_type, training_type_id, profile_id?, is_global?}` | `{id, ...}` | Mapping erstellen | | `PUT` | `/admin/activity-mappings/{id}` | 🔒 Admin | `{training_type_id?, is_global?}` | `{ok: true}` | Bearbeiten | | `DELETE` | `/admin/activity-mappings/{id}` | 🔒 Admin | – | `{ok: true}` | Löschen | | `GET` | `/admin/activity-mappings/stats/coverage` | 🔒 Admin | – | `{total_activities, mapped, unmapped, coverage_pct}` | Mapping-Coverage | **Auto-Learning:** Bulk-Kategorisierung in ActivityPage speichert neue Mappings automatisch --- ### 25. Training Profiles (`/api/evaluation/*`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `GET` | `/evaluation/parameters` | 🔒 Admin | – | `{categories: [...], abilities: [...]}` | Training-Parameter-Taxonomie | | `POST` | `/evaluation/batch` | 🔒 Admin | – | `{evaluated, failed, errors}` | Batch-Evaluierung aller Aktivitäten (v9d #15) | --- ## Sleep & Vitals (v9d Phase 2) ### 26. Sleep (`/api/sleep/*`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `GET` | `/sleep` | ✅ | `?limit=90` | `[{id, date, bedtime, wakeup, duration_min, quality, sleep_segments, notes, source}, ...]` | Schlaf-Einträge | | `GET` | `/sleep/by-date/{date}` | ✅ | – | `{id, date, ...}` oder `null` | Eintrag für Datum | | `POST` | `/sleep` | ✅ | `{date, bedtime, wakeup, duration_min, quality?, sleep_segments?, notes?}` | `{id, ...}` | Eintrag erstellen (Upsert) | | `PUT` | `/sleep/{id}` | ✅ | `{...}` | `{ok: true}` | Bearbeiten | | `DELETE` | `/sleep/{id}` | ✅ | – | `{ok: true}` | Löschen | | `GET` | `/sleep/stats` | ✅ | `?days=7` | `{avg_duration, avg_quality, total_deep, total_rem, ...}` | Stats | | `GET` | `/sleep/debt` | ✅ | `?days=14` | `{sleep_debt_min, avg_duration, target_duration}` | Schlafschuld | | `GET` | `/sleep/trend` | ✅ | `?days=30` | `[{date, duration_min, quality}, ...]` | Trend | | `GET` | `/sleep/phases` | ✅ | `?days=30` | `[{date, deep_min, rem_min, light_min, awake_min}, ...]` | Schlafphasen | | `POST` | `/sleep/import/apple-health` | ✅ | `FormData(file)` | `{imported, skipped, failed, errors}` | Apple Health CSV-Import | **sleep_segments Format (JSONB):** ```json [ {"phase": "deep", "start": "23:30", "end": "01:15"}, {"phase": "rem", "start": "01:15", "end": "02:45"}, {"phase": "light", "start": "02:45", "end": "06:00"}, {"phase": "awake", "start": "06:00", "end": "06:15"} ] ``` --- ### 27. Rest Days (`/api/rest-days/*`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `GET` | `/rest-days` | ✅ | `?limit=90` | `[{id, date, rest_type, reason, notes}, ...]` | Ruhetage | | `GET` | `/rest-days/{id}` | ✅ | – | `{id, ...}` | Einzelner Eintrag | | `POST` | `/rest-days` | ✅ | `{date, rest_type, reason?, notes?}` | `{id, ...}` | Ruhetag eintragen | | `PUT` | `/rest-days/{id}` | ✅ | `{...}` | `{ok: true}` | Bearbeiten | | `DELETE` | `/rest-days/{id}` | ✅ | – | `{ok: true}` | Löschen | | `GET` | `/rest-days/stats` | ✅ | `?weeks=4` | `{total_rest_days, kraft_days, cardio_days, entspannung_days}` | Stats | | `POST` | `/rest-days/validate-activity` | ✅ | `{date, activity_type}` | `{conflicts: [{rest_type, reason}, ...]}` | Validierung gegen Ruhetage | **rest_type:** `kraft`, `cardio`, `entspannung` (Multi-Dimensional Rest) --- ### 28. Vitals Baseline (`/api/vitals/baseline/*`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `GET` | `/vitals/baseline` | ✅ | `?limit=90` | `[{id, date, resting_hr, hrv, vo2_max, spo2, respiratory_rate, notes}, ...]` | Morgenmessungen | | `GET` | `/vitals/baseline/by-date/{date}` | ✅ | – | `{id, ...}` oder `null` | Eintrag für Datum | | `POST` | `/vitals/baseline` | ✅ | `{date, resting_hr?, hrv?, vo2_max?, spo2?, respiratory_rate?, notes?}` | `{id, ...}` | Eintrag erstellen (Upsert) | | `PUT` | `/vitals/baseline/{id}` | ✅ | `{...}` | `{ok: true}` | Bearbeiten | | `DELETE` | `/vitals/baseline/{id}` | ✅ | – | `{ok: true}` | Löschen | | `GET` | `/vitals/baseline/stats` | ✅ | `?days=30` | `{avg_resting_hr, avg_hrv, trend_resting_hr, trend_hrv}` | Stats | | `POST` | `/vitals/baseline/import/apple-health` | ✅ | `FormData(file)` | `{imported, skipped, failed, errors}` | Apple Health CSV-Import | **Messung:** 1x täglich, morgens nüchtern --- ### 29. Blood Pressure (`/api/blood-pressure/*`) | Methode | Pfad | Auth | Parameter | Response | Beschreibung | |---------|------|------|-----------|----------|--------------| | `GET` | `/blood-pressure` | ✅ | `?limit=90` | `[{id, date, time, systolic, diastolic, pulse, context, irregular_heartbeat, afib_warning, notes}, ...]` | Blutdruck-Messungen | | `GET` | `/blood-pressure/by-date/{date}` | ✅ | – | `[{id, time, ...}, ...]` | Alle Messungen für Datum | | `POST` | `/blood-pressure` | ✅ | `{date, time, systolic, diastolic, pulse?, context?, irregular_heartbeat?, afib_warning?, notes?}` | `{id, ...}` | Messung eintragen | | `PUT` | `/blood-pressure/{id}` | ✅ | `{...}` | `{ok: true}` | Bearbeiten | | `DELETE` | `/blood-pressure/{id}` | ✅ | – | `{ok: true}` | Löschen | | `GET` | `/blood-pressure/stats` | ✅ | `?days=30` | `{avg_systolic, avg_diastolic, avg_pulse, classification, trend}` | Stats | | `POST` | `/blood-pressure/import/omron` | ✅ | `FormData(file)` | `{imported, skipped, failed, errors}` | Omron CSV-Import (Deutsch) | **Contexts:** `fasting`, `after_meal`, `exercise`, `stress`, `rest`, `before_sleep`, `after_sleep`, `medication` **WHO/ISH-Klassifizierung:** - Optimal: <120/<80 - Normal: 120-129/80-84 - Hoch-Normal: 130-139/85-89 - Hypertonie Grad 1: 140-159/90-99 - Hypertonie Grad 2: 160-179/100-109 - Hypertonie Grad 3: ≥180/≥110 --- ## Zusammenfassung **Gesamt:** 29 Router-Module, ~200 Endpoints **Authentifizierung:** Token-basiert (X-Auth-Token Header) **Fehlerformat:** `{"detail": "Fehlermeldung"}` **Rate Limits:** Nur Auth-Endpoints (5/min Login, 3/hour Register) **Feature-Limits:** Membership-basiert (v9c), enforcement via HTTP 403 **Import-Formate:** CSV (Apple Health, Omron, FDDB), JSON (Backup) **Export-Formate:** CSV, JSON, ZIP (mit Fotos) **Besonderheiten:** - Upsert-Logik für viele Endpoints (Date-basiert) - Inline-Editing-Support (GET by date, PUT by id) - CSV-Import mit Duplikat-Erkennung - Lernendes Mapping-System (Activity Types) - JSONB für flexible Datenstrukturen (sleep_segments, abilities) - Auto-Migration SHA256 → bcrypt - E-Mail-Verifizierung + Passwort-Reset