mitai-jinkendo/.claude/docs/technical/ACTIVITY_SESSION_METRICS_EAV_AGENT_GUIDE.md
Lars 5cda485458
All checks were successful
Deploy Development / deploy (push) Successful in 53s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 16s
feat: Refactor activity data handling and improve CSV import logic
- Updated `ACTIVITY_PRODUCTION_ARCHITECTURE_AND_PHASES.md` to clarify the derivation of `ACTIVITY_MODULE_REGISTRY_FIELD_KEYS` from `csv_parser.module_registry`.
- Enhanced `activity_data_canon.py` to eliminate hardcoded key lists, ensuring all registry fields are derived dynamically.
- Refactored the `_import_activity` function to remove redundant parameters and streamline the import process.
- Improved the `insert_activity_csv_minimal` function to handle metrics exclusively through `update_activity_columns`, preventing hardcoded values.
- Updated frontend components to manage editable activity log fields more effectively, ensuring proper handling of metrics during CSV imports.
- Added unit tests to validate the new logic and ensure consistency in activity session metrics handling.
2026-04-16 10:35:08 +02:00

8.9 KiB
Raw Blame History

Activity Session Metrics (EAV) Umsetzungs- & Agent-Guide

Stand: 2026-04-14
Status: Kern-Backend (Migration 054, Layer 1, Admin- & Nutzer-API) umgesetzt; Admin-UI & CSV-Mapping folgen.
Ziel: Sportspezifische Attributprofile (Kategorie + optional Trainingstyp-Override) administrierbar; Messwerte pro Session in EAV; alle Auswertungen sollen künftig über Layer 1 (data_layer) laufen.

Zielarchitektur, Phasenplan (Produktionsreife): ACTIVITY_PRODUCTION_ARCHITECTURE_AND_PHASES.md Kanon activity_log/EAV, Composites, Import, Layer 1/2, Reihenfolge AF.

Kanon (Code): backend/data_layer/activity_data_canon.py — Spine-Keys nur aus csv_parser.module_registry (get_activity_module_registry_field_keys()ACTIVITY_MODULE_REGISTRY_FIELD_KEYS); kein paralleles Hardcoding. EAV-primär + Migration 057 unverändert.


0. CSV-Import & Doppel-EAV (Kanon)

  • Vor Schreibzugriff: apply_activity_mapped_column_aliases kopiert Werte von training_parameters.key auf source_field-Spalte, wenn die Spalte leer ist (z.B. avg_hrhr_avg).
  • activity_csv_registry_updates_from_mapped ist die einzige Quelle für activity_log-Kernspalten aus dem Mapping (Keys = module_registry.activity.fields); der Executor liest keine parallelen mapped.get("hr_avg")-Pfade mehr.
  • Plausible Zahlen: min/max in den Feld-Specs der Registry (keine HF-speziellen Key-Listen im Executor).
  • upsert_session_metrics_from_csv_mapped schreibt keine EAV-Zeilen für Parameter mit gesetztem source_field (kanonisch activity_log).
  • Migration 058: Entfernt bestehende redundante EAV-Zeilen für alle Parameter mit source_field.

1. Produktions-Migrationen (Pflicht)

  • Nur additive Änderungen bis zur Stabilisierung: neue Tabellen/Spalten nullable, kein DROP COLUMN / DELETE von Altbestand in derselben Story.
  • Neue Migrationen: backend/migrations/054_*.sql (nächste freie Nummer nach 053 einhalten).
  • Prod-Checkliste vor Deploy:
    1. Backup / Snapshot der DB.
    2. Migration auf Kopie der Prod-DB laufen lassen; Container-Start (db_init) verifizieren.
    3. Stichprobe: activity_log-Zeilen unverändert; neue Tabellen leer oder nur Seed.
  • Datenhaltung: Bestehende Spalten in activity_log bleiben Quelle für Alt-Daten; EAV (activity_session_metrics) ist der kanonische Ort für konfigurierte Session-Metriken, sobald geschrieben. Backfill Altspalten → EAV ist separater Schritt (siehe §6).

2. Datenmodell (Ist nach Migration 054)

Tabelle Zweck
training_parameters Katalog messbarer Größen (key, data_type, unit, validation_rules, …) bereits Migration 013; Admin-API ergänzt.
training_category_parameter Welche Parameter für welche training_types.category (z. B. cardio) gelten: sort_order, required, ui_group.
training_type_parameter Zusatzparameter oder Overrides pro training_types.id: sort_order, required, ui_group (NULL = von Kategorie erben).
activity_session_metrics EAV: (activity_log_id, training_parameter_id) eindeutig; genau eine Wertspalte value_num / value_int / value_text / value_bool.
activity_log Neu: started_at, ended_at (TIMESTAMPTZ, nullable) für spätere Dedupe/Intervalle; kein Pflichtfeld in v1.

Merge-Logik effektives Schema (Layer 1, eine Funktion):

  1. Kategorie ermitteln: aus Zeile training_category oder aus training_types.category via training_type_id.
  2. Basis = alle Zeilen training_category_parameter für diese Kategorie, Join auf training_parameters (aktiv).
  3. Für jeden Eintrag in training_type_parameter zum gewählten Typ: gleiche training_parameter_id → Overrides anwenden; nur im Typ vorhanden → anhängen.
  4. Sortierung: sort_order aufsteigend, dann key.

3. Layer 1 Kanonische Module

Modul Pfad Aufgabe
Session-Metriken & Schema backend/data_layer/activity_session_metrics.py resolve_activity_attribute_schema, fetch_activity_session_metrics, replace_activity_session_metrics, get_activity_session_logical_unit, enrich_sessions_with_metrics, merge_column_backed_and_eav_metrics.

Spalten vs. EAV (Lesepfad): merge_column_backed_and_eav_metrics / get_activity_session_logical_unit / enrich_sessions_with_metrics werten Parameter mit source_field primär aus activity_log aus; EAV ist Fallback (z.B. Legacy) oder für Parameter ohne Spalte. Kein automatischer Spalte→EAV-Schreib-Sync mehr in run_activity_post_write_hooks / Import-Hooks (vermeidet Doppelhaltung).

Regeln für Agenten:

  • Keine zweite Implementierung derselben Merge- oder Validierungslogik in Routern.
  • Platzhalter / Charts, die Session-Details brauchen: nur diese Layer-1-Helfer erweitern oder aufrufen (z. B. activity_metrics.get_training_sessions_recent_weeks_data nutzt enrich_sessions_with_metrics).
  • Router: get_db, get_cursor, Auth; Business-Validierung delegieren an activity_session_metrics.

4. API (Ist / geplant)

Admin (require_admin)

Methode Pfad Beschreibung
GET/POST /api/admin/training-parameters Katalog lesen / Parameter anlegen
PUT/DELETE /api/admin/training-parameters/{id} Aktualisieren / Soft-deaktivieren (is_active)
GET /api/admin/training-category-parameters?category= Zuordnungen Kategorie
POST /api/admin/training-category-parameters Zuordnung anlegen
DELETE /api/admin/training-category-parameters/{id} Zuordnung entfernen
GET /api/admin/training-type-parameters?training_type_id= Zuordnungen Typ
POST /api/admin/training-type-parameters Zuordnung anlegen
DELETE /api/admin/training-type-parameters/{id} Zuordnung entfernen

Router: backend/routers/admin_training_parameters.py, backend/routers/admin_activity_attribute_profiles.py.

Nutzer (require_auth)

Methode Pfad Beschreibung
GET /api/activity/{eid} Session-Kopf + schema + metrics (Layer 1)
PUT /api/activity/{eid}/metrics Voller Ersatz der EAV-Metriken für diese Session (Liste {parameter_key, value})

ActivityEntry unverändert für bestehende Create/Update-Routen; optionale Erweiterung um started_at/ended_at in späterem Schritt.


5. Agent-Checkliste (nächste Iterationen)

Siehe Phasen AF in ACTIVITY_PRODUCTION_ARCHITECTURE_AND_PHASES.md. Kurz:

  • Phase A (Code-Kanon): Spine-Felder = Registry activity.fields; insert_activity_csv_minimal nur Kopf, Metriken via update_activity_columns / activity_csv_registry_updates_from_mapped; Import-Eval liest Session aus DB. (Spreadsheet „eine Semantik pro Zeile“ weiterhin fachlich empfohlen.)
  • Phase B: Lesepfad Layer 1 härten (Consumer-Audit).
  • Phase C: Schreibpfad: Doppelhaltung / Sync stufenweise abschalten.
  • Phase D: Composite-MVP (ein Archetyp E2E).
  • Phase E: Archetypen ausbauen + CSV-Typkonvertierung vollständig + Mapping-UX.
  • Phase F: Härtung Prod (Indizes, Observability, Doku).

Legacy-Punkte:

  • Admin-UI: frontend/src/pages/AdminActivityAttributeProfilesPage.jsx, Route /admin/activity-attribute-profiles, Admin-Nav-Gruppe „Trainingstypen“.
  • /activity Frontend: Bearbeiten lädt GET /api/activity/{id}, dynamische Felder + PUT /api/activity/{id}/metrics.
  • Universal CSV: Mapping inkl. EAV/Composite-Ziele + Executor (fortlaufend).
  • Optional: Backfill / Abschluss source_field-Pfad nach Kanon (Phase A/C).
  • Dedupe Polar/Apple: nach stabilen started_at/ended_at + Policy (eigenes Issue).

6. Backfill (nicht in Migration 054)

Separates Skript oder Migration 055+, wenn fachlich freigegeben:

  • Pro aktivem training_parameter mit gesetztem source_field: Wert aus activity_log lesen, in EAV schreiben, wenn noch keine Zeile existiert.
  • Idempotent (ON CONFLICT DO NOTHING oder Upsert-Regel dokumentieren).

7. Automatische Tests (pytest, ohne DB)

Aus backend/:

python -m pytest tests/test_activity_session_metrics.py -v

Abdeckung: reine Merge-Logik (merge_parameter_schema_rows), Validierung (_validate_single_value), resolve_activity_attribute_schema mit Mock-Cursor, enrich_sessions_with_metrics mit Mock-Cursor.


8. Referenzen

  • Migration 013: training_parameters
  • Migration 004/014: training_types, activity_log-Erweiterungen
  • Pattern Admin-Katalog: routers/admin_reference_value_types.py
  • Platzhalter Session-JSON: data_layer/activity_metrics.pyget_training_sessions_recent_weeks_data

Version: 1.1 · Bei Schema- oder API-Änderungen dieses Dokument und ggf. CLAUDE.md Kurzverweis aktualisieren.