-- IHF Phase 2 Migration: Structured Feedback and Triage -- Introduces: annotation_threads, requirement_candidates, triage_states, reviewer_assignments -- Extends: annotations (severity, thread_id) -- annotation_threads must be created BEFORE altering annotations (FK reference) CREATE TABLE annotation_threads ( id UUID DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL, widget_id UUID NOT NULL REFERENCES widgets(id) ON DELETE CASCADE, title TEXT NOT NULL, description TEXT, created_by UUID REFERENCES users(id), created_at TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL ); -- Extend annotations with severity and thread grouping ALTER TABLE annotations ADD COLUMN severity TEXT NOT NULL DEFAULT 'medium'; ALTER TABLE annotations ADD COLUMN thread_id UUID REFERENCES annotation_threads(id) ON DELETE SET NULL; CREATE TABLE requirement_candidates ( id UUID DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL, title TEXT NOT NULL, description TEXT NOT NULL, source_widget_id UUID NOT NULL REFERENCES widgets(id) ON DELETE RESTRICT, source_thread_id UUID REFERENCES annotation_threads(id) ON DELETE SET NULL, source_annotation_id UUID REFERENCES annotations(id) ON DELETE SET NULL, category TEXT NOT NULL DEFAULT 'friction', status TEXT NOT NULL DEFAULT 'open', created_by UUID REFERENCES users(id), created_at TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL ); CREATE INDEX requirement_candidates_widget_id_idx ON requirement_candidates (source_widget_id); CREATE INDEX requirement_candidates_status_idx ON requirement_candidates (status); CREATE TABLE triage_states ( id UUID DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL, candidate_id UUID NOT NULL REFERENCES requirement_candidates(id) ON DELETE CASCADE, status TEXT NOT NULL, notes TEXT, changed_by UUID REFERENCES users(id), changed_at TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL ); CREATE INDEX triage_states_candidate_id_idx ON triage_states (candidate_id); CREATE TABLE reviewer_assignments ( id UUID DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL, candidate_id UUID NOT NULL REFERENCES requirement_candidates(id) ON DELETE CASCADE, user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, assigned_by UUID REFERENCES users(id), assigned_at TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL, UNIQUE (candidate_id) );