- Updated the README to include new activity production architecture and phases, improving clarity on the development roadmap. - Enhanced the `ACTIVITY_SESSION_METRICS_EAV_AGENT_GUIDE` with details on the target architecture and phase plan for production readiness. - Introduced a new function `merge_column_backed_and_eav_metrics` to streamline the merging of metrics from column-backed and EAV sources, ensuring data integrity and reducing duplication. - Refactored session metrics handling to eliminate deprecated synchronization methods, improving the overall efficiency of data processing. - Added unit tests for the new merging logic, ensuring robust validation of metrics handling.
116 lines
4.4 KiB
SQL
116 lines
4.4 KiB
SQL
-- Migration 057: Kanon EAV-primär für erweiterte Trainingsmetriken
|
|
-- Date: 2026-04-15
|
|
-- activity_log-Spalten bleiben erhalten (Lesefallback / API); training_parameters.source_field
|
|
-- wird für diese Keys entfernt. Idempotenter EAV-Backfill aus Spalten (wie 055), dann source_field NULL.
|
|
-- Siehe: backend/data_layer/activity_data_canon.py
|
|
|
|
-- min_hr (Spalte hr_min)
|
|
INSERT INTO activity_session_metrics (
|
|
activity_log_id, training_parameter_id,
|
|
value_num, value_int, value_text, value_bool, updated_at
|
|
)
|
|
SELECT a.id, tp.id, NULL, a.hr_min, NULL, NULL, NOW()
|
|
FROM activity_log a
|
|
JOIN training_parameters tp ON tp.key = 'min_hr' AND tp.is_active = true
|
|
WHERE a.hr_min IS NOT NULL
|
|
ON CONFLICT (activity_log_id, training_parameter_id) DO NOTHING;
|
|
|
|
INSERT INTO activity_session_metrics (
|
|
activity_log_id, training_parameter_id,
|
|
value_num, value_int, value_text, value_bool, updated_at
|
|
)
|
|
SELECT a.id, tp.id, a.pace_min_per_km::double precision, NULL, NULL, NULL, NOW()
|
|
FROM activity_log a
|
|
JOIN training_parameters tp ON tp.key = 'pace_min_per_km' AND tp.is_active = true
|
|
WHERE a.pace_min_per_km IS NOT NULL
|
|
ON CONFLICT (activity_log_id, training_parameter_id) DO NOTHING;
|
|
|
|
INSERT INTO activity_session_metrics (
|
|
activity_log_id, training_parameter_id,
|
|
value_num, value_int, value_text, value_bool, updated_at
|
|
)
|
|
SELECT a.id, tp.id, NULL, a.cadence, NULL, NULL, NOW()
|
|
FROM activity_log a
|
|
JOIN training_parameters tp ON tp.key = 'cadence' AND tp.is_active = true
|
|
WHERE a.cadence IS NOT NULL
|
|
ON CONFLICT (activity_log_id, training_parameter_id) DO NOTHING;
|
|
|
|
INSERT INTO activity_session_metrics (
|
|
activity_log_id, training_parameter_id,
|
|
value_num, value_int, value_text, value_bool, updated_at
|
|
)
|
|
SELECT a.id, tp.id, NULL, a.avg_power, NULL, NULL, NOW()
|
|
FROM activity_log a
|
|
JOIN training_parameters tp ON tp.key = 'avg_power' AND tp.is_active = true
|
|
WHERE a.avg_power IS NOT NULL
|
|
ON CONFLICT (activity_log_id, training_parameter_id) DO NOTHING;
|
|
|
|
INSERT INTO activity_session_metrics (
|
|
activity_log_id, training_parameter_id,
|
|
value_num, value_int, value_text, value_bool, updated_at
|
|
)
|
|
SELECT a.id, tp.id, NULL, a.elevation_gain, NULL, NULL, NOW()
|
|
FROM activity_log a
|
|
JOIN training_parameters tp ON tp.key = 'elevation_gain' AND tp.is_active = true
|
|
WHERE a.elevation_gain IS NOT NULL
|
|
ON CONFLICT (activity_log_id, training_parameter_id) DO NOTHING;
|
|
|
|
INSERT INTO activity_session_metrics (
|
|
activity_log_id, training_parameter_id,
|
|
value_num, value_int, value_text, value_bool, updated_at
|
|
)
|
|
SELECT a.id, tp.id, a.temperature_celsius::double precision, NULL, NULL, NULL, NOW()
|
|
FROM activity_log a
|
|
JOIN training_parameters tp ON tp.key = 'temperature_celsius' AND tp.is_active = true
|
|
WHERE a.temperature_celsius IS NOT NULL
|
|
ON CONFLICT (activity_log_id, training_parameter_id) DO NOTHING;
|
|
|
|
INSERT INTO activity_session_metrics (
|
|
activity_log_id, training_parameter_id,
|
|
value_num, value_int, value_text, value_bool, updated_at
|
|
)
|
|
SELECT a.id, tp.id, NULL, a.humidity_percent, NULL, NULL, NOW()
|
|
FROM activity_log a
|
|
JOIN training_parameters tp ON tp.key = 'humidity_percent' AND tp.is_active = true
|
|
WHERE a.humidity_percent IS NOT NULL
|
|
ON CONFLICT (activity_log_id, training_parameter_id) DO NOTHING;
|
|
|
|
INSERT INTO activity_session_metrics (
|
|
activity_log_id, training_parameter_id,
|
|
value_num, value_int, value_text, value_bool, updated_at
|
|
)
|
|
SELECT a.id, tp.id, a.avg_hr_percent::double precision, NULL, NULL, NULL, NOW()
|
|
FROM activity_log a
|
|
JOIN training_parameters tp ON tp.key = 'avg_hr_percent' AND tp.is_active = true
|
|
WHERE a.avg_hr_percent IS NOT NULL
|
|
ON CONFLICT (activity_log_id, training_parameter_id) DO NOTHING;
|
|
|
|
INSERT INTO activity_session_metrics (
|
|
activity_log_id, training_parameter_id,
|
|
value_num, value_int, value_text, value_bool, updated_at
|
|
)
|
|
SELECT a.id, tp.id, a.kcal_per_km::double precision, NULL, NULL, NULL, NOW()
|
|
FROM activity_log a
|
|
JOIN training_parameters tp ON tp.key = 'kcal_per_km' AND tp.is_active = true
|
|
WHERE a.kcal_per_km IS NOT NULL
|
|
ON CONFLICT (activity_log_id, training_parameter_id) DO NOTHING;
|
|
|
|
UPDATE training_parameters
|
|
SET source_field = NULL
|
|
WHERE key IN (
|
|
'min_hr',
|
|
'pace_min_per_km',
|
|
'cadence',
|
|
'avg_power',
|
|
'elevation_gain',
|
|
'temperature_celsius',
|
|
'humidity_percent',
|
|
'avg_hr_percent',
|
|
'kcal_per_km'
|
|
);
|
|
|
|
DO $$
|
|
BEGIN
|
|
RAISE NOTICE 'Migration 057: EAV-primary canon — backfill + source_field cleared for extended metrics';
|
|
END $$;
|