-- Migration 119: CRA Compliance Projects -- Tracks per-product CRA conformity assessment lifecycle. -- Status state machine (validated as whitelist, no transition enforcement): -- draft -> scoped -> classified -> path_selected -> requirements_mapped -> -- evidence_pending -> gaps_open -> remediation -> ready_for_review -> -- declaration_ready -> post_market -- Tenant scoping via X-Tenant-ID header (validated UUID). CREATE TABLE IF NOT EXISTS compliance_cra_projects ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id VARCHAR(255) NOT NULL, name VARCHAR(500) NOT NULL, description TEXT DEFAULT '', gap_project_id UUID, -- Intake (Software-fokussiert, NICHT Hardware) repo_url VARCHAR(1000), primary_language VARCHAR(50), has_firmware BOOLEAN DEFAULT false, connected_to_internet BOOLEAN DEFAULT false, has_software_updates BOOLEAN DEFAULT false, processes_personal_data BOOLEAN DEFAULT false, is_critical_infra_supplier BOOLEAN DEFAULT false, intended_use TEXT DEFAULT '', -- Scope cra_classification VARCHAR(20), classification_rationale JSONB DEFAULT '[]'::jsonb, -- Path conformity_path VARCHAR(30), -- Status (whitelist) status VARCHAR(40) NOT NULL DEFAULT 'draft', -- Audit created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_cra_projects_tenant ON compliance_cra_projects(tenant_id); CREATE INDEX IF NOT EXISTS idx_cra_projects_status ON compliance_cra_projects(tenant_id, status); CREATE INDEX IF NOT EXISTS idx_cra_projects_class ON compliance_cra_projects(cra_classification); CREATE INDEX IF NOT EXISTS idx_cra_projects_gap_link ON compliance_cra_projects(gap_project_id) WHERE gap_project_id IS NOT NULL;