-- Migration 008: Vitals, Rest Days, Weekly Goals -- v9d Phase 2: Sleep & Vitals Module -- Date: 2026-03-22 -- Rest Days CREATE TABLE IF NOT EXISTS rest_days ( id SERIAL PRIMARY KEY, profile_id UUID NOT NULL REFERENCES profiles(id) ON DELETE CASCADE, date DATE NOT NULL, type VARCHAR(20) NOT NULL CHECK (type IN ('full_rest', 'active_recovery')), note TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, CONSTRAINT unique_rest_day_per_profile UNIQUE(profile_id, date) ); CREATE INDEX idx_rest_days_profile_date ON rest_days(profile_id, date DESC); -- Vitals (Resting HR + HRV) CREATE TABLE IF NOT EXISTS vitals_log ( id SERIAL PRIMARY KEY, profile_id UUID NOT NULL REFERENCES profiles(id) ON DELETE CASCADE, date DATE NOT NULL, resting_hr INTEGER CHECK (resting_hr > 0 AND resting_hr < 200), hrv INTEGER CHECK (hrv > 0), note TEXT, source VARCHAR(20) DEFAULT 'manual' CHECK (source IN ('manual', 'apple_health', 'garmin')), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, CONSTRAINT unique_vitals_per_day UNIQUE(profile_id, date) ); CREATE INDEX idx_vitals_profile_date ON vitals_log(profile_id, date DESC); -- Extend activity_log for heart rate data ALTER TABLE activity_log ADD COLUMN IF NOT EXISTS avg_hr INTEGER CHECK (avg_hr > 0 AND avg_hr < 250), ADD COLUMN IF NOT EXISTS max_hr INTEGER CHECK (max_hr > 0 AND max_hr < 250); -- Extend profiles for HF max and sleep goal ALTER TABLE profiles ADD COLUMN IF NOT EXISTS hf_max INTEGER CHECK (hf_max > 0 AND hf_max < 250), ADD COLUMN IF NOT EXISTS sleep_goal_minutes INTEGER DEFAULT 450 CHECK (sleep_goal_minutes > 0); -- Weekly Goals (Soll/Ist Wochenplanung) CREATE TABLE IF NOT EXISTS weekly_goals ( id SERIAL PRIMARY KEY, profile_id UUID NOT NULL REFERENCES profiles(id) ON DELETE CASCADE, week_start DATE NOT NULL, goals JSONB NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, CONSTRAINT unique_weekly_goal_per_profile UNIQUE(profile_id, week_start) ); CREATE INDEX idx_weekly_goals_profile_week ON weekly_goals(profile_id, week_start DESC); -- Comments for documentation COMMENT ON TABLE rest_days IS 'v9d Phase 2: Rest days tracking (full rest or active recovery)'; COMMENT ON TABLE vitals_log IS 'v9d Phase 2: Daily vitals (resting HR, HRV)'; COMMENT ON TABLE weekly_goals IS 'v9d Phase 2: Weekly training goals (Soll/Ist planning)'; COMMENT ON COLUMN profiles.hf_max IS 'Maximum heart rate for HR zone calculation'; COMMENT ON COLUMN profiles.sleep_goal_minutes IS 'Sleep goal in minutes (default: 450 = 7h 30min)';