-- audit_events — platform-level security/admin audit log, distinct from the Provisioner's -- environment_events (which is Lab-lifecycle-only). Never stores plaintext passwords, raw -- session tokens, Provisioner secrets, or raw routing tokens — see src/audit.js callers. CREATE TABLE IF NOT EXISTS audit_events ( audit_event_id BIGSERIAL PRIMARY KEY, actor_type TEXT NOT NULL, -- 'instructor' | 'student' | 'system' actor_id TEXT, -- instructor_id or student_id as text; NULL for e.g. a failed login with no matching account action TEXT NOT NULL, resource_type TEXT, resource_id TEXT, result TEXT NOT NULL, -- 'success' | 'failure' source_ip TEXT, metadata JSONB, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX IF NOT EXISTS idx_audit_created ON audit_events(created_at DESC); CREATE INDEX IF NOT EXISTS idx_audit_actor ON audit_events(actor_type, actor_id); CREATE INDEX IF NOT EXISTS idx_audit_action ON audit_events(action);