-- AP1.4: Roadmap + RoadmapItem + Dependencies (methodenneutral) CREATE TABLE roadmaps ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE, initiative_id UUID NOT NULL REFERENCES initiatives(id) ON DELETE CASCADE, title VARCHAR(255) NOT NULL DEFAULT 'Plan', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), UNIQUE (tenant_id, initiative_id) ); CREATE INDEX idx_roadmaps_tenant_initiative ON roadmaps(tenant_id, initiative_id); CREATE TABLE roadmap_items ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE, roadmap_id UUID NOT NULL REFERENCES roadmaps(id) ON DELETE CASCADE, item_type VARCHAR(32) NOT NULL DEFAULT 'milestone' CHECK (item_type IN ('milestone', 'review_gate', 'maturity_stage')), title VARCHAR(255) NOT NULL, goal_description TEXT NOT NULL DEFAULT '', definition_of_done JSONB NOT NULL DEFAULT '[]'::jsonb, status VARCHAR(32) NOT NULL DEFAULT 'planned' CHECK (status IN ('planned', 'active', 'at_risk', 'reached', 'moved', 'discarded')), sequencing_mode VARCHAR(32) NOT NULL DEFAULT 'sequential' CHECK (sequencing_mode IN ('sequential', 'parallel', 'optional')), target_date DATE NULL, sort_order INT NOT NULL DEFAULT 0, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX idx_roadmap_items_tenant_roadmap ON roadmap_items(tenant_id, roadmap_id); CREATE INDEX idx_roadmap_items_tenant_status ON roadmap_items(tenant_id, status); CREATE INDEX idx_roadmap_items_tenant_type ON roadmap_items(tenant_id, item_type); CREATE TABLE roadmap_item_dependencies ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE, from_item_id UUID NOT NULL REFERENCES roadmap_items(id) ON DELETE CASCADE, to_item_id UUID NOT NULL REFERENCES roadmap_items(id) ON DELETE CASCADE, dependency_type VARCHAR(32) NOT NULL DEFAULT 'requires' CHECK (dependency_type IN ('requires', 'blocks', 'related')), created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), UNIQUE (tenant_id, from_item_id, to_item_id, dependency_type) ); CREATE INDEX idx_roadmap_deps_from ON roadmap_item_dependencies(tenant_id, from_item_id); CREATE INDEX idx_roadmap_deps_to ON roadmap_item_dependencies(tenant_id, to_item_id); ALTER TABLE backlog_items ADD COLUMN roadmap_item_id UUID NULL REFERENCES roadmap_items(id) ON DELETE SET NULL; ALTER TABLE actions ADD COLUMN roadmap_item_id UUID NULL REFERENCES roadmap_items(id) ON DELETE SET NULL; CREATE INDEX idx_backlog_roadmap_item ON backlog_items(tenant_id, roadmap_item_id) WHERE roadmap_item_id IS NOT NULL; CREATE INDEX idx_actions_roadmap_item ON actions(tenant_id, roadmap_item_id) WHERE roadmap_item_id IS NOT NULL; -- Ein Plan pro Initiative INSERT INTO roadmaps (tenant_id, initiative_id, title) SELECT tenant_id, id, 'Plan' FROM initiatives; -- Bestehende Meilensteine → RoadmapItems (IDs beibehalten für Evidence/Review-FKs) INSERT INTO roadmap_items ( id, tenant_id, roadmap_id, item_type, title, goal_description, status, sequencing_mode, target_date, sort_order, created_at, updated_at ) SELECT m.id, m.tenant_id, r.id, 'milestone', m.title, m.goal_description, m.status, 'sequential', m.target_date, 0, m.created_at, m.updated_at FROM milestones m JOIN roadmaps r ON r.initiative_id = m.initiative_id AND r.tenant_id = m.tenant_id;