# Aktivität: Skalar-Kanon (eine Semantik → eine Quelle) **Stand:** 2026-04-16 **Normativer Code:** `backend/data_layer/activity_data_canon.py` **Kontext:** `ACTIVITY_PRODUCTION_ARCHITECTURE_AND_PHASES.md` (Phase A abgeschlossen) --- ## 1. Spine & Identität (`activity_log`, nicht EAV) Diese Felder sind **keine** `training_parameters`-Skalare. Sie gehören zur Session-Zeile. | Semantik | DB / API | Kanonische Quelle | Lesefallback | Sync Spalte↔EAV | |----------|----------|-------------------|--------------|-----------------| | Primärschlüssel | `activity_log.id` | `activity_log` | — | — | | Profil | `profile_id` | `activity_log` | — | — | | Kalendertag | `date` | `activity_log` | — | — | | Start / Ende (Zeit) | `start_time`, `end_time`, `started_at`, `ended_at` | `activity_log` | — | — | | Trainingsart (Freitext/Legacy) | `activity_type` | `activity_log` | — | — | | Referenz Trainingstyp | `training_type_id`, `training_category`, … | `activity_log` (+ `training_types`) | — | — | | Notiz | `notes` | `activity_log` | — | — | | Quelle / Import | `source`, `created`, … | `activity_log` | — | — | | Session-Auswertung | `evaluation`, `quality_label`, `overall_score`, … | `activity_log` (Blob/Ergebnis) | — | Kein EAV-Raster | --- ## 2. Kernfelder CSV-Modul `activity` (= „heiße“ Skalare) Abgeleitet aus `csv_parser.module_registry.MODULE_DEFINITIONS["activity"].fields` — maschinenlesbar über `ACTIVITY_MODULE_REGISTRY_FIELD_KEYS` in `activity_data_canon.py`. | Semantik | Key (Registry/API) | Kanonische Quelle | Lesefallback | Bemerkung | |----------|-------------------|-------------------|--------------|-----------| | Dauer | `duration_min` | **`activity_log`** | — | Aggregates, Listen | | Aktive Energie | `kcal_active` | **`activity_log`** | — | | | Ruhe-Energie | `kcal_resting` | **`activity_log`** | — | | | Distanz | `distance_km` | **`activity_log`** | — | | | Ø HF | `hr_avg` (Parameter oft `avg_hr` in EAV-Schema) | **`activity_log`** | EAV nur wenn `source_field` / Profil-Schema | `merge_column_backed_and_eav_metrics`: Spalte schlägt EAV | | Max-HF | `hr_max` | **`activity_log`** | analog | | | RPE | `rpe` | **`activity_log`** | analog | | Schreibpfad: Universal-CSV und API sollen diese Keys auf **`activity_log`** mappen, sofern nicht ausdrücklich ein EAV-primärer Parameter (§3) gewählt ist. --- ## 3. EAV-primäre Parameter (erweiterte Skalare) `ACTIVITY_EAV_PRIMARY_PARAMETER_KEYS` in `activity_data_canon.py`. **`training_parameters.source_field`** = NULL (nach Kanon / Migration 057): kanonischer Speicher ist **`activity_session_metrics`**. | Parameter-Key (`training_parameters.key`) | Legacy-Spalte `activity_log` | Schreib-Kanon (Ziel) | |-------------------------------------------|------------------------------|------------------------| | `min_hr` | `hr_min` | **EAV** | | `pace_min_per_km` | `pace_min_per_km` | **EAV** | | `cadence` | `cadence` | **EAV** | | `avg_power` | `avg_power` | **EAV** | | `elevation_gain` | `elevation_gain` | **EAV** | | `temperature_celsius` | `temperature_celsius` | **EAV** | | `humidity_percent` | `humidity_percent` | **EAV** | | `avg_hr_percent` | `avg_hr_percent` | **EAV** | | `kcal_per_km` | `kcal_per_km` | **EAV** | **Lesen:** `merge_column_backed_and_eav_metrics` — wenn Legacy-Spalte **und** EAV einen Wert haben, **gewinnt die Spalte** (kanonische `activity_log`-Sicht). EAV nur, wenn die Spalte leer/nicht koerzierbar ist. --- ## 4. Profil-/Typ-dynamische Skalare (EAV, nicht in Registry-Kernliste) | Semantik | Kanonische Quelle | Lesefallback | |----------|-------------------|--------------| | Admin-definierte Parameter (Attributprofil Kategorie/Typ) | **`activity_session_metrics`** + `training_parameters` | — | | Parameter mit `source_field` → Spalte | **`activity_log`** (Spalte) | EAV ergänzend; Leseregel: Spalte bevorzugt (kein veraltetes EAV) | --- ## 5. Composites (Zielbild, noch nicht Kanon-Zeile pro Slot) | Semantik | Kanonische Quelle (Ziel) | |----------|---------------------------| | Strukturierte Composite-Dokumente (z. B. Zonen/Bänder) | **EAV** ein Dokument pro Parameter/Session (siehe `ACTIVITY_COMPOSITE_METRICS_IMPLEMENTATION_CONCEPT.md`) | Kein dauerhaftes Spiegeln derselben Semantik in `activity_log`-Spalten. --- ## 6. Sync & Übergang - **Kein** automatischer Dauer-Sync „Spalte → EAV“ für dieselbe Semantik; Lesepfad vereinheitlicht die Sicht (`merge_column_backed_and_eav_metrics`). - Optionale **Backfill**-Migration/Skript (idempotent) nur nach fachlicher Freigabe — siehe EAV-Agent-Guide §6. --- ## 7. Referenzen - `ACTIVITY_PRODUCTION_ARCHITECTURE_AND_PHASES.md` — Phasen A–F - `ACTIVITY_SESSION_METRICS_EAV_AGENT_GUIDE.md` — APIs, Tests - `activity_data_canon.py` — `ACTIVITY_LOG_PATCHABLE_COLUMNS`, Legacy-Map