-- Workstream I: VS-04 Audit Trail (Immutable events + GDPR compliance)
-- Creates compliance audit trail for model operations, regulatory reporting, and GDPR redaction

CREATE SCHEMA IF NOT EXISTS compliance;

-- Audit events (immutable, INSERT-only)
CREATE TABLE IF NOT EXISTS compliance.audit_events (
    id UUID PRIMARY KEY,
    event_type VARCHAR(100) NOT NULL,  -- MODEL_CREATED, APPROVAL_PROPOSED, APPROVAL_APPROVED, MODEL_ACTIVATED, SELL_DECISION_MADE, SELL_EXECUTED, BACKTEST_COMPLETED, DATA_CORRECTION, etc.
    entity_type VARCHAR(50) NOT NULL,  -- MODEL, APPROVAL, SELL_DECISION, TRADE_EXECUTION
    entity_id UUID NOT NULL,
    actor_email VARCHAR(255) NOT NULL,
    actor_role VARCHAR(50),  -- MAKER, CHECKER, SRE, SYSTEM
    event_at TIMESTAMPTZ NOT NULL,
    result VARCHAR(50) NOT NULL,  -- SUCCESS, FAILURE, PARTIAL
    error_message TEXT,
    details JSONB,  -- Event-specific metadata
    evidence_links TEXT[],  -- S3 artifact URLs (PBO scores, OOS returns, backtest reports)
    ip_address INET,  -- Source IP for forensics
    user_agent TEXT,  -- Client identifier
    published_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    correlation_id UUID NOT NULL,  -- Links related events
    revision INT NOT NULL DEFAULT 1
);

-- Indexes for compliance querying
CREATE INDEX IF NOT EXISTS idx_audit_events_entity_id ON compliance.audit_events(entity_id);
CREATE INDEX IF NOT EXISTS idx_audit_events_event_type ON compliance.audit_events(event_type);
CREATE INDEX IF NOT EXISTS idx_audit_events_actor_email ON compliance.audit_events(actor_email);
CREATE INDEX IF NOT EXISTS idx_audit_events_event_at ON compliance.audit_events(event_at);
CREATE INDEX IF NOT EXISTS idx_audit_events_correlation_id ON compliance.audit_events(correlation_id);

-- GDPR retention tracking (personal data retention policy)
CREATE TABLE IF NOT EXISTS compliance.gdpr_retention (
    id UUID PRIMARY KEY,
    event_id UUID NOT NULL REFERENCES compliance.audit_events(id),
    customer_id UUID,  -- Links to personal data
    data_categories VARCHAR(50)[],  -- PII, EMAIL, TRADING_HISTORY, PORTFOLIO_DATA, etc.
    retention_ends_at DATE,  -- When to purge
    purge_status VARCHAR(50) NOT NULL DEFAULT 'PENDING',  -- PENDING, PURGED, EXCEPTION
    purged_at TIMESTAMPTZ,
    exception_reason TEXT,
    published_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    revision INT NOT NULL DEFAULT 1
);

-- Indexes for GDPR processing
CREATE INDEX IF NOT EXISTS idx_gdpr_retention_customer_id ON compliance.gdpr_retention(customer_id);
CREATE INDEX IF NOT EXISTS idx_gdpr_retention_purge_status ON compliance.gdpr_retention(purge_status);

-- Event types enumeration (reference, not enforced at DB level)
CREATE TABLE IF NOT EXISTS compliance.audit_event_types (
    event_type VARCHAR(100) PRIMARY KEY,
    description TEXT,
    entity_type VARCHAR(50),  -- MODEL, APPROVAL, SELL_DECISION, TRADE_EXECUTION
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Seed event types
INSERT INTO compliance.audit_event_types (event_type, description, entity_type) VALUES
    ('MODEL_CREATED', 'New model version created', 'MODEL'),
    ('MODEL_ARCHIVED', 'Model retired from use', 'MODEL'),
    ('APPROVAL_PROPOSED', 'Maker submitted activation proposal', 'APPROVAL'),
    ('APPROVAL_APPROVED', 'Checker approved proposal', 'APPROVAL'),
    ('APPROVAL_REJECTED', 'Checker rejected proposal', 'APPROVAL'),
    ('MODEL_ACTIVATED', 'SRE activated model in production', 'MODEL'),
    ('MODEL_DEACTIVATED', 'SRE deactivated model', 'MODEL'),
    ('SELL_DECISION_MADE', 'Signal engine generated sell signal', 'SELL_DECISION'),
    ('SELL_EXECUTED', 'Trade executed based on signal', 'TRADE_EXECUTION'),
    ('BACKTEST_COMPLETED', 'Shadow run/backtest finished', 'MODEL'),
    ('DATA_CORRECTION', 'Source data corrected retroactively', 'MODEL'),
    ('COMPLIANCE_AUDIT', 'Auditor reviewed trail', 'MODEL')
ON CONFLICT (event_type) DO NOTHING;

-- Schema ownership
ALTER TABLE compliance.audit_events OWNER TO kartsell;
ALTER TABLE compliance.gdpr_retention OWNER TO kartsell;
ALTER TABLE compliance.audit_event_types OWNER TO kartsell;

-- Immutability constraints (enforced via code, not DB triggers)
-- INSERT-only: no UPDATE, no DELETE permitted on audit_events
-- Timestamps: immutable after insertion (enforced in application layer)
-- Correlation_id: immutable for traceability

-- 7-year retention policy (FSS requirement)
-- retention_ends_at defaults to now() + 7 years (enforced in application)
