2026-04-17 12:55:12 +02:00
# 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` **.
2026-04-17 15:49:38 +02:00
| 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.
2026-04-17 12:55:12 +02:00
---
## 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