mitai-jinkendo/backend/migrations/013_training_parameters.sql
Lars ca7d9b2e3f
All checks were successful
Deploy Development / deploy (push) Successful in 43s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
fix: add missing validation_rules in migration 013 (#15)
SQL Error: VALUES lists must all be the same length (line 130)
Cause: kcal_per_km row was missing validation_rules JSONB value

Fixed: Added validation_rules '{"min": 0, "max": 1000}'::jsonb

All 16 parameter rows now have correct 10 columns:
key, name_de, name_en, category, data_type, unit, source_field,
validation_rules, description_de, description_en

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 11:01:53 +01:00

146 lines
6.8 KiB
SQL

-- Migration 013: Training Parameters Registry
-- Training Type Profiles System - Foundation
-- Date: 2026-03-23
-- Issue: #15
-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-- TRAINING PARAMETERS REGISTRY
-- Zentrale Definition aller messbaren Parameter für Aktivitäten
-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
CREATE TABLE IF NOT EXISTS training_parameters (
id SERIAL PRIMARY KEY,
key VARCHAR(50) UNIQUE NOT NULL,
name_de VARCHAR(100) NOT NULL,
name_en VARCHAR(100) NOT NULL,
category VARCHAR(50) NOT NULL,
data_type VARCHAR(20) NOT NULL,
unit VARCHAR(20),
description_de TEXT,
description_en TEXT,
source_field VARCHAR(100),
validation_rules JSONB DEFAULT '{}'::jsonb,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT NOW(),
CONSTRAINT chk_category CHECK (category IN (
'physical', 'physiological', 'subjective', 'environmental', 'performance'
)),
CONSTRAINT chk_data_type CHECK (data_type IN (
'integer', 'float', 'string', 'boolean'
))
);
CREATE INDEX idx_training_parameters_category ON training_parameters(category) WHERE is_active = true;
CREATE INDEX idx_training_parameters_key ON training_parameters(key) WHERE is_active = true;
COMMENT ON TABLE training_parameters IS 'Registry of all measurable activity parameters (Training Type Profiles System)';
COMMENT ON COLUMN training_parameters.key IS 'Unique identifier (e.g. "avg_hr", "duration_min")';
COMMENT ON COLUMN training_parameters.category IS 'Parameter category: physical, physiological, subjective, environmental, performance';
COMMENT ON COLUMN training_parameters.data_type IS 'Data type: integer, float, string, boolean';
COMMENT ON COLUMN training_parameters.source_field IS 'Mapping to activity_log column name';
COMMENT ON COLUMN training_parameters.validation_rules IS 'Min/Max/Enum for validation (JSONB)';
-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-- STANDARD PARAMETERS
-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
INSERT INTO training_parameters (key, name_de, name_en, category, data_type, unit, source_field, validation_rules, description_de, description_en) VALUES
-- Physical Parameters
('duration_min', 'Dauer', 'Duration', 'physical', 'integer', 'min', 'duration_min',
'{"min": 0, "max": 600}'::jsonb,
'Trainingsdauer in Minuten',
'Training duration in minutes'),
('distance_km', 'Distanz', 'Distance', 'physical', 'float', 'km', 'distance_km',
'{"min": 0, "max": 200}'::jsonb,
'Zurückgelegte Distanz in Kilometern',
'Distance covered in kilometers'),
('kcal_active', 'Aktive Kalorien', 'Active Calories', 'physical', 'integer', 'kcal', 'kcal_active',
'{"min": 0, "max": 5000}'::jsonb,
'Aktiver Kalorienverbrauch',
'Active calorie burn'),
('kcal_resting', 'Ruhekalorien', 'Resting Calories', 'physical', 'integer', 'kcal', 'kcal_resting',
'{"min": 0, "max": 2000}'::jsonb,
'Ruheumsatz während Training',
'Resting calorie burn during training'),
('elevation_gain', 'Höhenmeter', 'Elevation Gain', 'physical', 'integer', 'm', 'elevation_gain',
'{"min": 0, "max": 5000}'::jsonb,
'Überwundene Höhenmeter',
'Elevation gain in meters'),
('pace_min_per_km', 'Pace', 'Pace', 'physical', 'float', 'min/km', 'pace_min_per_km',
'{"min": 2, "max": 20}'::jsonb,
'Durchschnittstempo in Minuten pro Kilometer',
'Average pace in minutes per kilometer'),
('cadence', 'Trittfrequenz', 'Cadence', 'physical', 'integer', 'spm', 'cadence',
'{"min": 0, "max": 220}'::jsonb,
'Schrittfrequenz (Schritte pro Minute)',
'Step frequency (steps per minute)'),
-- Physiological Parameters
('avg_hr', 'Durchschnittspuls', 'Average Heart Rate', 'physiological', 'integer', 'bpm', 'hr_avg',
'{"min": 30, "max": 220}'::jsonb,
'Durchschnittliche Herzfrequenz',
'Average heart rate'),
('max_hr', 'Maximalpuls', 'Max Heart Rate', 'physiological', 'integer', 'bpm', 'hr_max',
'{"min": 40, "max": 220}'::jsonb,
'Maximale Herzfrequenz',
'Maximum heart rate'),
('min_hr', 'Minimalpuls', 'Min Heart Rate', 'physiological', 'integer', 'bpm', 'hr_min',
'{"min": 30, "max": 200}'::jsonb,
'Minimale Herzfrequenz',
'Minimum heart rate'),
('avg_power', 'Durchschnittsleistung', 'Average Power', 'physiological', 'integer', 'W', 'avg_power',
'{"min": 0, "max": 1000}'::jsonb,
'Durchschnittliche Leistung in Watt',
'Average power output in watts'),
-- Subjective Parameters
('rpe', 'RPE (Anstrengung)', 'RPE (Perceived Exertion)', 'subjective', 'integer', 'scale', 'rpe',
'{"min": 1, "max": 10}'::jsonb,
'Subjektive Anstrengung (Rate of Perceived Exertion)',
'Rate of Perceived Exertion'),
-- Environmental Parameters
('temperature_celsius', 'Temperatur', 'Temperature', 'environmental', 'float', '°C', 'temperature_celsius',
'{"min": -30, "max": 50}'::jsonb,
'Umgebungstemperatur in Celsius',
'Ambient temperature in Celsius'),
('humidity_percent', 'Luftfeuchtigkeit', 'Humidity', 'environmental', 'integer', '%', 'humidity_percent',
'{"min": 0, "max": 100}'::jsonb,
'Relative Luftfeuchtigkeit in Prozent',
'Relative humidity in percent'),
-- Performance Parameters (calculated)
('avg_hr_percent', '% Max-HF', '% Max HR', 'performance', 'float', '%', 'avg_hr_percent',
'{"min": 0, "max": 100}'::jsonb,
'Durchschnittspuls als Prozent der maximalen Herzfrequenz',
'Average heart rate as percentage of max heart rate'),
('kcal_per_km', 'Kalorien pro km', 'Calories per km', 'performance', 'float', 'kcal/km', 'kcal_per_km',
'{"min": 0, "max": 1000}'::jsonb,
'Kalorienverbrauch pro Kilometer',
'Calorie burn per kilometer');
-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-- SUMMARY
-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-- Display inserted parameters
DO $$
BEGIN
RAISE NOTICE '✓ Migration 013 completed';
RAISE NOTICE ' - Created training_parameters table';
RAISE NOTICE ' - Inserted % standard parameters', (SELECT COUNT(*) FROM training_parameters);
END $$;