# frozen_string_literal: true class ProcessWafEventJob < ApplicationJob queue_as :waf_events def perform(event_data:, headers:) # Handle both single event and events array events_to_process = [] if event_data.key?('events') && event_data['events'].is_a?(Array) # Multiple events in an array events_to_process = event_data['events'] elsif event_data.key?('event_id') # Single event events_to_process = [event_data] else Rails.logger.warn "Invalid event data format: missing event_id or events array" return end events_to_process.each do |single_event_data| begin # Generate unique event ID if not provided event_id = single_event_data['event_id'] || SecureRandom.uuid # Create the WAF event record event = Event.create_from_waf_payload!(event_id, single_event_data) # Enrich with geo-location data if missing if event.ip_address.present? && event.country_code.blank? begin event.enrich_geo_location! rescue => e Rails.logger.warn "Failed to enrich geo location for event #{event.id}: #{e.message}" end end # Trigger analytics processing ProcessWafAnalyticsJob.perform_later(event_id: event.id) # Check for automatic rule generation opportunities GenerateWafRulesJob.perform_later(event_id: event.id) Rails.logger.info "Processed WAF event #{event_id}" rescue ActiveRecord::RecordInvalid => e Rails.logger.error "Failed to create WAF event: #{e.message}" Rails.logger.error e.record.errors.full_messages.join(", ") rescue => e Rails.logger.error "Error processing WAF event: #{e.message}" Rails.logger.error e.backtrace.join("\n") end end # Broadcast real-time updates once per batch ActionCable.server.broadcast("events", { type: "refresh" }) Rails.logger.info "Processed #{events_to_process.count} WAF events" end end