# frozen_string_literal: true class CreateEvents < ActiveRecord::Migration[8.1] def change create_table :events, force: :cascade do |t| # Core event identification t.string :event_id, null: false, index: { unique: true } t.references :project, null: false, foreign_key: true, index: true # Timing t.datetime :timestamp, null: false, index: true # WAF evaluation t.integer :waf_action, default: 0, null: false, index: true t.string :rule_matched t.text :blocked_reason # Request metadata t.inet :ip_address, index: true t.string :user_agent t.string :request_url t.string :request_path t.string :request_protocol t.integer :request_method, default: 0 # Response metadata t.integer :response_status t.integer :response_time_ms # Geographic data t.string :country_code t.string :city # Server/Environment info t.string :server_name t.string :environment # WAF agent info t.string :agent_name t.string :agent_version # Normalized relationships for analytics t.references :request_host, foreign_key: true, index: true t.string :request_segment_ids # JSON array of path segment IDs # Full event payload t.json :payload t.timestamps # Composite indexes for analytics queries t.index [:project_id, :timestamp], name: 'idx_events_project_time' t.index [:project_id, :waf_action], name: 'idx_events_project_action' t.index [:project_id, :ip_address], name: 'idx_events_project_ip' t.index [:request_host_id, :request_method, :request_segment_ids], name: 'idx_events_host_method_path' t.index :request_segment_ids end end end