- 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.
62 lines
2.5 KiB
Python
62 lines
2.5 KiB
Python
"""
|
|
Kanonische Aufteilung activity_log vs. EAV für Aktivitätssessions.
|
|
|
|
Single Source für: welche Felder das CSV-/Registry-Modul „activity“ direkt in activity_log schreibt,
|
|
und welche training_parameters primär über EAV laufen (mit optionalem Lesefallback auf Legacy-Spalten).
|
|
|
|
Normative Doku: .claude/docs/technical/ACTIVITY_PRODUCTION_ARCHITECTURE_AND_PHASES.md
|
|
|
|
Phase A: Keine zweite hartcodierte Key-Liste — Registry-Felder kommen ausschließlich aus
|
|
``csv_parser.module_registry.MODULE_DEFINITIONS["activity"].fields``.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from typing import Dict, Final
|
|
|
|
from csv_parser.module_registry import get_module_definition
|
|
|
|
|
|
def get_activity_module_registry_field_keys() -> frozenset[str]:
|
|
"""Keys des Universal-CSV-Moduls ``activity`` (= Spine-Spalten-Namen in activity_log)."""
|
|
mod = get_module_definition("activity")
|
|
if not mod:
|
|
return frozenset()
|
|
return frozenset((mod.get("fields") or {}).keys())
|
|
|
|
|
|
# ── activity_log: Modul „activity“ (Universal-CSV-Kern) ───────────────────────
|
|
# Ableitung aus module_registry — bei neuen Registry-Feldern hier kein manuelles Update nötig.
|
|
ACTIVITY_MODULE_REGISTRY_FIELD_KEYS: Final[frozenset[str]] = get_activity_module_registry_field_keys()
|
|
|
|
# Teil-UPDATEs (Import): alle Registry-Kernfelder außer ``date`` (Identität/Duplikat-Key).
|
|
ACTIVITY_LOG_PATCHABLE_COLUMNS: Final[frozenset[str]] = ACTIVITY_MODULE_REGISTRY_FIELD_KEYS - {"date"}
|
|
|
|
# Parameter-Keys (training_parameters.key), die primär in EAV geführt werden; source_field nach Migration 057 NULL.
|
|
# Lesefallback: activity_log-Spalte unter ACTIVITY_LOG_LEGACY_COLUMN_FOR_EAV_PRIMARY_PARAM, falls EAV leer.
|
|
ACTIVITY_EAV_PRIMARY_PARAMETER_KEYS: Final[frozenset[str]] = frozenset(
|
|
{
|
|
"min_hr",
|
|
"pace_min_per_km",
|
|
"cadence",
|
|
"avg_power",
|
|
"elevation_gain",
|
|
"temperature_celsius",
|
|
"humidity_percent",
|
|
"avg_hr_percent",
|
|
"kcal_per_km",
|
|
}
|
|
)
|
|
|
|
# Spaltenname activity_log für Legacy-Lesefallback (Merge), wenn EAV für den Parameter fehlt.
|
|
ACTIVITY_LOG_LEGACY_COLUMN_FOR_EAV_PRIMARY_PARAM: Final[Dict[str, str]] = {
|
|
"min_hr": "hr_min",
|
|
"pace_min_per_km": "pace_min_per_km",
|
|
"cadence": "cadence",
|
|
"avg_power": "avg_power",
|
|
"elevation_gain": "elevation_gain",
|
|
"temperature_celsius": "temperature_celsius",
|
|
"humidity_percent": "humidity_percent",
|
|
"avg_hr_percent": "avg_hr_percent",
|
|
"kcal_per_km": "kcal_per_km",
|
|
}
|