-- ============================================================================
-- Migration 010: Incident/Breach Management Schema
-- DSGVO Art. 33 (Authority Notification) & Art. 34 (Data Subject Notification)
--
-- Art. 33 requires notification of the supervisory authority within 72 hours
-- of becoming aware of a personal data breach, unless the breach is unlikely
-- to result in a risk to the rights and freedoms of natural persons.
--
-- Art. 34 requires notification of affected data subjects without undue delay
-- when the breach is likely to result in a high risk to their rights and freedoms.
-- ============================================================================

-- Incident incidents table
CREATE TABLE IF NOT EXISTS incident_incidents (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES compliance_tenants(id) ON DELETE CASCADE,

    -- Incident info
    title VARCHAR(255) NOT NULL,
    description TEXT,
    category VARCHAR(50) NOT NULL, -- data_breach, unauthorized_access, data_loss, system_compromise, phishing, ransomware, insider_threat, physical_breach, other
    status VARCHAR(50) DEFAULT 'detected', -- detected, assessment, containment, notification_required, notification_sent, remediation, closed
    severity VARCHAR(50) NOT NULL, -- critical, high, medium, low

    -- Detection & reporting
    detected_at TIMESTAMPTZ NOT NULL,
    reported_by UUID NOT NULL,

    -- Affected scope
    affected_data_categories JSONB DEFAULT '[]', -- e.g. ["personal_data", "health_data", "financial_data"]
    affected_data_subject_count INT DEFAULT 0,
    affected_systems JSONB DEFAULT '[]', -- e.g. ["crm", "email_server", "database"]

    -- Assessments & notifications (JSONB embedded objects)
    risk_assessment JSONB, -- {likelihood, impact, risk_level, assessed_at, assessed_by, notes}
    authority_notification JSONB, -- {status, deadline, submitted_at, authority_name, reference_number, contact_person, notes}
    data_subject_notification JSONB, -- {required, status, sent_at, affected_count, notification_text, channel}

    -- Resolution
    root_cause TEXT,
    lessons_learned TEXT,

    -- Timeline (JSONB array of events)
    timeline JSONB DEFAULT '[]', -- [{timestamp, action, user_id, details}, ...]

    -- Audit
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    closed_at TIMESTAMPTZ
);

-- Incident measures table (corrective and preventive measures)
CREATE TABLE IF NOT EXISTS incident_measures (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    incident_id UUID NOT NULL REFERENCES incident_incidents(id) ON DELETE CASCADE,

    -- Measure info
    title VARCHAR(255) NOT NULL,
    description TEXT,
    measure_type VARCHAR(50) NOT NULL, -- immediate, long_term
    status VARCHAR(50) DEFAULT 'planned', -- planned, in_progress, completed
    responsible VARCHAR(255),
    due_date TIMESTAMPTZ,
    completed_at TIMESTAMPTZ,

    -- Audit
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- ============================================================================
-- Indexes
-- ============================================================================

-- Incident indexes
CREATE INDEX IF NOT EXISTS idx_incident_incidents_tenant ON incident_incidents(tenant_id);
CREATE INDEX IF NOT EXISTS idx_incident_incidents_status ON incident_incidents(tenant_id, status);
CREATE INDEX IF NOT EXISTS idx_incident_incidents_severity ON incident_incidents(tenant_id, severity);
CREATE INDEX IF NOT EXISTS idx_incident_incidents_detected_at ON incident_incidents(detected_at DESC);
CREATE INDEX IF NOT EXISTS idx_incident_incidents_category ON incident_incidents(tenant_id, category);

-- Measure indexes
CREATE INDEX IF NOT EXISTS idx_incident_measures_incident ON incident_measures(incident_id);
CREATE INDEX IF NOT EXISTS idx_incident_measures_status ON incident_measures(incident_id, status);

-- ============================================================================
-- Triggers
-- ============================================================================

-- Reuse existing update_updated_at_column function

-- Incidents trigger
DROP TRIGGER IF EXISTS update_incident_incidents_updated_at ON incident_incidents;
CREATE TRIGGER update_incident_incidents_updated_at
    BEFORE UPDATE ON incident_incidents
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

-- ============================================================================
-- Comments
-- ============================================================================

COMMENT ON TABLE incident_incidents IS 'Security and data breach incidents per DSGVO Art. 33/34';
COMMENT ON TABLE incident_measures IS 'Corrective and preventive measures for incidents';

COMMENT ON COLUMN incident_incidents.detected_at IS 'When the incident was first detected - starts the 72h Art. 33 notification clock';
COMMENT ON COLUMN incident_incidents.authority_notification IS 'JSONB: Supervisory authority notification tracking per DSGVO Art. 33 (72h deadline)';
COMMENT ON COLUMN incident_incidents.data_subject_notification IS 'JSONB: Data subject notification tracking per DSGVO Art. 34';
COMMENT ON COLUMN incident_incidents.risk_assessment IS 'JSONB: Risk assessment with likelihood, impact, and auto-calculated risk level';
COMMENT ON COLUMN incident_incidents.timeline IS 'JSONB array: Chronological record of all actions taken during incident response';
COMMENT ON COLUMN incident_incidents.affected_data_categories IS 'JSONB array: Categories of personal data affected (e.g. health, financial)';
COMMENT ON COLUMN incident_incidents.affected_systems IS 'JSONB array: Systems affected by the incident';
COMMENT ON COLUMN incident_measures.measure_type IS 'immediate = short-term containment, long_term = preventive/structural fix';
