-- Migration 044: CSV Parser — System-Vorlagen Schlaf (Apple) + Vitalwerte Baseline (Issue #21) -- Idempotent wie 043. INSERT INTO csv_field_mappings ( profile_id, is_system, module, mapping_name, description, column_signature, delimiter, encoding, has_header, field_mappings, type_conversions ) SELECT NULL, true, 'sleep', 'Apple Health Schlaf (Segment-Export)', 'Apple-Health-Schlaf-CSV mit Phasen-Zeilen (Start, End, Duration (hr), Value). Import läuft aggregiert pro Nacht.', ARRAY['Start', 'End', 'Duration (hr)', 'Value']::TEXT[], ',', 'utf-8', true, '{ "Start": "-", "End": "-", "Duration (hr)": "-", "Value": "-" }'::JSONB, '{}'::JSONB WHERE NOT EXISTS ( SELECT 1 FROM csv_field_mappings f WHERE f.is_system AND f.profile_id IS NULL AND f.module = 'sleep' AND f.mapping_name = 'Apple Health Schlaf (Segment-Export)' ); INSERT INTO csv_field_mappings ( profile_id, is_system, module, mapping_name, description, column_signature, delimiter, encoding, has_header, field_mappings, type_conversions ) SELECT NULL, true, 'sleep', 'Apple Health Schlaf (Schlafanalyse / Nacht)', 'Apple-Health-Schlafanalyse mit Nacht-Zusammenfassung (u. a. Total Sleep (hr), Start, End).', ARRAY['Start', 'End', 'Total Sleep (hr)']::TEXT[], ',', 'utf-8', true, '{ "Start": "-", "End": "-", "Total Sleep (hr)": "-" }'::JSONB, '{}'::JSONB WHERE NOT EXISTS ( SELECT 1 FROM csv_field_mappings f WHERE f.is_system AND f.profile_id IS NULL AND f.module = 'sleep' AND f.mapping_name = 'Apple Health Schlaf (Schlafanalyse / Nacht)' ); INSERT INTO csv_field_mappings ( profile_id, is_system, module, mapping_name, description, column_signature, delimiter, encoding, has_header, field_mappings, type_conversions ) SELECT NULL, true, 'vitals_baseline', 'Apple Health Baseline Vitals (English)', 'Tägliche Baseline-Messungen aus Apple Health (Ruhepuls, HRV, VO2, SpO2, Atemfrequenz).', ARRAY[ 'Start', 'Resting Heart Rate', 'Heart Rate Variability', 'VO2 Max', 'Oxygen Saturation', 'Respiratory Rate' ]::TEXT[], ',', 'utf-8', true, '{ "Start": "date", "Resting Heart Rate": "resting_hr", "Heart Rate Variability": "hrv", "VO2 Max": "vo2_max", "Oxygen Saturation": "spo2", "Respiratory Rate": "respiratory_rate" }'::JSONB, '{ "date": { "type": "datetime", "format": "yyyy-mm-dd HH:MM:SS", "extract": "date_only", "flexible": true }, "resting_hr": {"type": "int", "flexible": true}, "hrv": {"type": "int", "flexible": true}, "vo2_max": {"type": "float", "decimal_separator": "auto", "flexible": true}, "spo2": {"type": "int", "flexible": true}, "respiratory_rate": {"type": "float", "decimal_separator": "auto", "flexible": true} }'::JSONB WHERE NOT EXISTS ( SELECT 1 FROM csv_field_mappings f WHERE f.is_system AND f.profile_id IS NULL AND f.module = 'vitals_baseline' AND f.mapping_name = 'Apple Health Baseline Vitals (English)' ); INSERT INTO csv_field_mappings ( profile_id, is_system, module, mapping_name, description, column_signature, delimiter, encoding, has_header, field_mappings, type_conversions ) SELECT NULL, true, 'vitals_baseline', 'Apple Health Baseline Vitals (Deutsch)', 'Tägliche Baseline-Messungen aus Apple Health (deutsche Spaltenbezeichnungen).', ARRAY[ 'Datum/Uhrzeit', 'Ruhepuls (count/min)', 'Herzfrequenzvariabilität (ms)', 'VO2 max (ml/(kg·min))', 'Blutsauerstoffsättigung (%)', 'Atemfrequenz (count/min)' ]::TEXT[], ',', 'utf-8', true, '{ "Datum/Uhrzeit": "date", "Ruhepuls (count/min)": "resting_hr", "Herzfrequenzvariabilität (ms)": "hrv", "VO2 max (ml/(kg·min))": "vo2_max", "Blutsauerstoffsättigung (%)": "spo2", "Atemfrequenz (count/min)": "respiratory_rate" }'::JSONB, '{ "date": { "type": "datetime", "format": "yyyy-mm-dd HH:MM:SS", "extract": "date_only", "flexible": true }, "resting_hr": {"type": "int", "flexible": true}, "hrv": {"type": "int", "flexible": true}, "vo2_max": {"type": "float", "decimal_separator": "auto", "flexible": true}, "spo2": {"type": "int", "flexible": true}, "respiratory_rate": {"type": "float", "decimal_separator": "auto", "flexible": true} }'::JSONB WHERE NOT EXISTS ( SELECT 1 FROM csv_field_mappings f WHERE f.is_system AND f.profile_id IS NULL AND f.module = 'vitals_baseline' AND f.mapping_name = 'Apple Health Baseline Vitals (Deutsch)' );