-- Who changed what in EnakGame, from what, to what (docs/rfc-enakgame.md §5.9, §13). -- Written in the same transaction as the change it records, so no change commits -- without its row. Append-only. CREATE TABLE audit_logs ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), organization_id UUID NOT NULL, actor_type VARCHAR(20) NOT NULL, -- The admin for USER; NULL for SYSTEM. actor_id UUID, entity_type VARCHAR(50) NOT NULL, entity_id UUID NOT NULL, action VARCHAR(50) NOT NULL, before JSONB, after JSONB, reason VARCHAR(255), -- 'admin_api', 'budget_controller', 'session_job', ... source VARCHAR(50) NOT NULL, created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), CONSTRAINT chk_audit_logs_actor_type CHECK (actor_type IN ('USER', 'SYSTEM')), CONSTRAINT chk_audit_logs_actor CHECK (actor_type = 'SYSTEM' OR actor_id IS NOT NULL) ); CREATE INDEX idx_audit_logs_entity ON audit_logs(entity_type, entity_id, created_at DESC); CREATE INDEX idx_audit_logs_organization ON audit_logs(organization_id, created_at DESC);