Fixed health mode calculation to include all 6 dimensions. Simplified CASE statements (single CASE instead of multiple additions). Before: health mode only set flexibility (15%) + health (55%) = 70% ❌ After: health mode sets all dimensions = 100% ✅ - weight_loss: 5% - muscle_gain: 0% - strength: 10% - endurance: 20% - flexibility: 15% - health: 50% Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
126 lines
4.2 KiB
SQL
126 lines
4.2 KiB
SQL
-- Migration 027: Focus Areas System (Goal System v2.0)
|
|
-- Date: 2026-03-27
|
|
-- Purpose: Replace single primary goal with weighted multi-goal system
|
|
|
|
-- ============================================================================
|
|
-- Focus Areas Table
|
|
-- ============================================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS focus_areas (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
profile_id UUID NOT NULL REFERENCES profiles(id) ON DELETE CASCADE,
|
|
|
|
-- Six focus dimensions (percentages, sum = 100)
|
|
weight_loss_pct INTEGER DEFAULT 0 CHECK (weight_loss_pct >= 0 AND weight_loss_pct <= 100),
|
|
muscle_gain_pct INTEGER DEFAULT 0 CHECK (muscle_gain_pct >= 0 AND muscle_gain_pct <= 100),
|
|
strength_pct INTEGER DEFAULT 0 CHECK (strength_pct >= 0 AND strength_pct <= 100),
|
|
endurance_pct INTEGER DEFAULT 0 CHECK (endurance_pct >= 0 AND endurance_pct <= 100),
|
|
flexibility_pct INTEGER DEFAULT 0 CHECK (flexibility_pct >= 0 AND flexibility_pct <= 100),
|
|
health_pct INTEGER DEFAULT 0 CHECK (health_pct >= 0 AND health_pct <= 100),
|
|
|
|
-- Status
|
|
active BOOLEAN DEFAULT true,
|
|
|
|
-- Audit
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW(),
|
|
|
|
-- Constraints
|
|
CONSTRAINT sum_equals_100 CHECK (
|
|
weight_loss_pct + muscle_gain_pct + strength_pct +
|
|
endurance_pct + flexibility_pct + health_pct = 100
|
|
)
|
|
);
|
|
|
|
-- Only one active focus_areas per profile
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_focus_areas_profile_active
|
|
ON focus_areas(profile_id) WHERE active = true;
|
|
|
|
COMMENT ON TABLE focus_areas IS 'User-defined focus area weights (replaces simple goal_mode). Enables multi-goal prioritization with custom percentages.';
|
|
COMMENT ON COLUMN focus_areas.weight_loss_pct IS 'Focus on fat loss (0-100%)';
|
|
COMMENT ON COLUMN focus_areas.muscle_gain_pct IS 'Focus on muscle growth (0-100%)';
|
|
COMMENT ON COLUMN focus_areas.strength_pct IS 'Focus on strength gains (0-100%)';
|
|
COMMENT ON COLUMN focus_areas.endurance_pct IS 'Focus on aerobic capacity (0-100%)';
|
|
COMMENT ON COLUMN focus_areas.flexibility_pct IS 'Focus on mobility/flexibility (0-100%)';
|
|
COMMENT ON COLUMN focus_areas.health_pct IS 'Focus on general health (0-100%)';
|
|
|
|
-- ============================================================================
|
|
-- Migrate existing goal_mode to focus_areas
|
|
-- ============================================================================
|
|
|
|
-- For each profile with a goal_mode, create initial focus_areas
|
|
INSERT INTO focus_areas (
|
|
profile_id,
|
|
weight_loss_pct, muscle_gain_pct, strength_pct,
|
|
endurance_pct, flexibility_pct, health_pct
|
|
)
|
|
SELECT
|
|
id AS profile_id,
|
|
CASE goal_mode
|
|
WHEN 'weight_loss' THEN 60
|
|
WHEN 'recomposition' THEN 30
|
|
WHEN 'health' THEN 5
|
|
ELSE 0
|
|
END AS weight_loss_pct,
|
|
|
|
CASE goal_mode
|
|
WHEN 'strength' THEN 40 ELSE 0
|
|
END +
|
|
CASE goal_mode
|
|
WHEN 'recomposition' THEN 30 ELSE 0
|
|
END AS muscle_gain_pct,
|
|
|
|
CASE goal_mode
|
|
WHEN 'strength' THEN 50
|
|
WHEN 'recomposition' THEN 25
|
|
WHEN 'weight_loss' THEN 10
|
|
WHEN 'health' THEN 10
|
|
ELSE 0
|
|
END AS strength_pct,
|
|
|
|
CASE goal_mode
|
|
WHEN 'endurance' THEN 70
|
|
WHEN 'recomposition' THEN 10
|
|
WHEN 'weight_loss' THEN 20
|
|
WHEN 'health' THEN 20
|
|
ELSE 0
|
|
END AS endurance_pct,
|
|
|
|
CASE goal_mode
|
|
WHEN 'endurance' THEN 10 ELSE 0
|
|
END +
|
|
CASE goal_mode
|
|
WHEN 'health' THEN 15 ELSE 0
|
|
END +
|
|
CASE goal_mode
|
|
WHEN 'recomposition' THEN 5 ELSE 0
|
|
END +
|
|
CASE goal_mode
|
|
WHEN 'weight_loss' THEN 5 ELSE 0
|
|
END AS flexibility_pct,
|
|
|
|
CASE goal_mode
|
|
WHEN 'health' THEN 50
|
|
WHEN 'endurance' THEN 20
|
|
WHEN 'strength' THEN 10
|
|
WHEN 'weight_loss' THEN 5
|
|
ELSE 0
|
|
END AS health_pct
|
|
FROM profiles
|
|
WHERE goal_mode IS NOT NULL
|
|
ON CONFLICT DO NOTHING;
|
|
|
|
-- For profiles without goal_mode, use balanced health focus
|
|
INSERT INTO focus_areas (
|
|
profile_id,
|
|
weight_loss_pct, muscle_gain_pct, strength_pct,
|
|
endurance_pct, flexibility_pct, health_pct
|
|
)
|
|
SELECT
|
|
id AS profile_id,
|
|
0, 0, 10, 20, 15, 55
|
|
FROM profiles
|
|
WHERE goal_mode IS NULL
|
|
AND id NOT IN (SELECT profile_id FROM focus_areas WHERE active = true)
|
|
ON CONFLICT DO NOTHING;
|