60 lines
1.8 KiB
Ruby
60 lines
1.8 KiB
Ruby
# 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 |