module RateLimitable extend ActiveSupport::Concern private def rate_limit_check!(key, limit:, period:) cache_key = "rate_limit:#{key}" count = Rails.cache.read(cache_key) || 0 if count >= limit render_rate_limit_exceeded(period) return false end Rails.cache.write(cache_key, count + 1, expires_in: period) true end def rate_limit_increment(key, period:) cache_key = "rate_limit:#{key}" current_count = Rails.cache.read(cache_key) || 0 Rails.cache.write(cache_key, current_count + 1, expires_in: period) end def rate_limit_reset(key) cache_key = "rate_limit:#{key}" Rails.cache.delete(cache_key) end def render_rate_limit_exceeded(retry_after) render json: { error: "Rate limit exceeded", retry_after: retry_after.to_i }, status: :too_many_requests end # Rate limit based on IP address def rate_limit_by_ip!(limit:, period:) ip_address = request.remote_ip rate_limit_check!("ip:#{ip_address}", limit: limit, period: period) end # Rate limit based on API key def rate_limit_by_api_key!(limit:, period:) return true unless @current_api_key rate_limit_check!("api_key:#{@current_api_key.id}", limit: limit, period: period) end # Rate limit based on phone number def rate_limit_by_phone!(phone_number, limit:, period:) rate_limit_check!("phone:#{phone_number}", limit: limit, period: period) end end