addSql(<<<'SQL' CREATE TABLE audit_log ( id uuid NOT NULL, entity_type VARCHAR(100) NOT NULL, entity_id VARCHAR(64) NOT NULL, action VARCHAR(10) NOT NULL, changes JSONB NOT NULL DEFAULT '{}'::jsonb, performed_by VARCHAR(100) NOT NULL, performed_at TIMESTAMP(6) WITH TIME ZONE NOT NULL, ip_address VARCHAR(45) DEFAULT NULL, request_id VARCHAR(36) DEFAULT NULL, PRIMARY KEY(id) ) SQL); $this->addSql('CREATE INDEX idx_audit_entity_time ON audit_log (entity_type, entity_id, performed_at)'); $this->addSql('CREATE INDEX idx_audit_performer ON audit_log (performed_by, performed_at)'); $this->addSql('CREATE INDEX idx_audit_time ON audit_log (performed_at)'); $this->addSql("COMMENT ON COLUMN audit_log.entity_type IS 'Audited entity type, format module.Entity (e.g. core.User)'"); $this->addSql("COMMENT ON COLUMN audit_log.entity_id IS 'Audited entity identifier (int or composite key serialized)'"); $this->addSql("COMMENT ON COLUMN audit_log.action IS 'create|update|delete'"); $this->addSql("COMMENT ON COLUMN audit_log.changes IS 'JSON diff: {field:{old,new}} for update, full snapshot for create/delete'"); $this->addSql("COMMENT ON COLUMN audit_log.performed_by IS 'User identifier or system'"); $this->addSql("COMMENT ON COLUMN audit_log.request_id IS 'UUID shared by all audit rows of a single HTTP request (null in CLI)'"); } public function down(Schema $schema): void { $this->addSql('DROP TABLE audit_log'); } }