## Implemented
### DB-Schema (Migrations)
- Migration 013: training_parameters table (16 standard parameters)
- Migration 014: training_types.profile + activity_log.evaluation columns
- Performance metric calculations (avg_hr_percent, kcal_per_km)
### Backend - Rule Engine
- RuleEvaluator: Generic rule evaluation with 9 operators
- gte, lte, gt, lt, eq, neq, between, in, not_in
- Weighted scoring system
- Pass strategies: all_must_pass, weighted_score, at_least_n
- IntensityZoneEvaluator: HR zone analysis
- TrainingEffectsEvaluator: Abilities development
### Backend - Master Evaluator
- TrainingProfileEvaluator: 7-dimensional evaluation
1. Minimum Requirements (Quality Gates)
2. Intensity Zones (HR zones)
3. Training Effects (Abilities)
4. Periodization (Frequency & Recovery)
5. Performance Indicators (KPIs)
6. Safety (Warnings)
7. AI Context (simplified for MVP)
- evaluation_helper.py: Utilities for loading + saving
- routers/evaluation.py: API endpoints
- POST /api/evaluation/activity/{id}
- POST /api/evaluation/batch
- GET /api/evaluation/parameters
### Integration
- main.py: Router registration
## TODO (Phase 1.2)
- Auto-evaluation on activity INSERT/UPDATE
- Admin-UI for profile editing
- User-UI for results display
## Testing
- ✅ Syntax checks passed
- 🔲 Runtime testing pending (after auto-evaluation)
Part of Issue #15 - Training Type Profiles System
145 lines
6.7 KiB
SQL
145 lines
6.7 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',
|
|
'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 $$;
|