-- Removes persisted sprint status; sprint state is derived from start/end dates. -- Safe to run multiple times. BEGIN; ALTER TABLE public.sprints DROP COLUMN IF EXISTS status; CREATE OR REPLACE FUNCTION public.complete_ended_sprints_and_rollover() RETURNS void LANGUAGE plpgsql SECURITY DEFINER SET search_path = public AS $$ DECLARE ended_sprint RECORD; next_sprint_id UUID; BEGIN FOR ended_sprint IN SELECT id FROM public.sprints WHERE end_date < CURRENT_DATE ORDER BY end_date ASC, start_date ASC LOOP SELECT s.id INTO next_sprint_id FROM public.sprints s WHERE s.end_date >= CURRENT_DATE AND s.id <> ended_sprint.id ORDER BY s.start_date ASC LIMIT 1; IF next_sprint_id IS NOT NULL THEN UPDATE public.tasks SET sprint_id = next_sprint_id WHERE sprint_id = ended_sprint.id AND status NOT IN ('done', 'canceled', 'archived'); END IF; END LOOP; END; $$; COMMIT;