-- Migration 030: Goal Progress Log -- Date: 2026-03-27 -- Purpose: Track progress history for all goals (especially custom goals without data source) -- ============================================================================ -- Goal Progress Log Table -- ============================================================================ CREATE TABLE IF NOT EXISTS goal_progress_log ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), goal_id UUID NOT NULL REFERENCES goals(id) ON DELETE CASCADE, profile_id UUID NOT NULL REFERENCES profiles(id) ON DELETE CASCADE, -- Progress data date DATE NOT NULL, value DECIMAL(10,2) NOT NULL, note TEXT, -- Metadata source VARCHAR(20) DEFAULT 'manual' CHECK (source IN ('manual', 'automatic', 'import')), created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW(), -- Constraints CONSTRAINT unique_progress_per_day UNIQUE(goal_id, date) ); CREATE INDEX idx_goal_progress_goal_date ON goal_progress_log(goal_id, date DESC); CREATE INDEX idx_goal_progress_profile ON goal_progress_log(profile_id); COMMENT ON TABLE goal_progress_log IS 'Progress history for goals - enables manual tracking for custom goals and charts'; COMMENT ON COLUMN goal_progress_log.value IS 'Progress value in goal unit (e.g., kg, cm, points)'; COMMENT ON COLUMN goal_progress_log.source IS 'manual: user entered, automatic: computed from data source, import: CSV/API'; -- ============================================================================ -- Function: Update goal current_value from latest progress -- ============================================================================ CREATE OR REPLACE FUNCTION update_goal_current_value() RETURNS TRIGGER AS $$ BEGIN -- Update current_value in goals table with latest progress entry UPDATE goals SET current_value = ( SELECT value FROM goal_progress_log WHERE goal_id = NEW.goal_id ORDER BY date DESC LIMIT 1 ), updated_at = NOW() WHERE id = NEW.goal_id; RETURN NEW; END; $$ LANGUAGE plpgsql; -- Trigger: Auto-update current_value when progress is added/updated CREATE TRIGGER trigger_update_goal_current_value AFTER INSERT OR UPDATE ON goal_progress_log FOR EACH ROW EXECUTE FUNCTION update_goal_current_value(); COMMENT ON FUNCTION update_goal_current_value IS 'Auto-update goal.current_value when new progress is logged';