Class: NeuronAiChatbot::ApiIntentValidator
- Inherits:
-
Object
- Object
- NeuronAiChatbot::ApiIntentValidator
- Defined in:
- app/services/neuron_ai_chatbot/api_intent_validator.rb
Class Method Summary collapse
- .find_catalog_row(catalog, request_path, method) ⇒ Object
- .merge_path_params(template_path, request_path, params) ⇒ Object
- .normalize_endpoint(ep) ⇒ Object
- .path_matches_template?(request_path, template_path) ⇒ Boolean
- .present_param?(params, key) ⇒ Boolean
- .validate(ai_output, catalog = nil) ⇒ Object
Class Method Details
.find_catalog_row(catalog, request_path, method) ⇒ Object
35 36 37 38 39 |
# File 'app/services/neuron_ai_chatbot/api_intent_validator.rb', line 35 def self.find_catalog_row(catalog, request_path, method) catalog.find do |row| row[:method].to_s.upcase == method && path_matches_template?(request_path, row[:endpoint].to_s) end end |
.merge_path_params(template_path, request_path, params) ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'app/services/neuron_ai_chatbot/api_intent_validator.rb', line 55 def self.merge_path_params(template_path, request_path, params) return params unless template_path.include?("{id}") out = params.dup return out if present_param?(out, "id") req_segments = request_path.split("/") tpl_segments = template_path.split("/") tpl_segments.each_with_index do |seg, i| if seg == "{id}" && req_segments[i].to_s.match?(/\A\d+\z/) out["id"] = req_segments[i] break end end out end |
.normalize_endpoint(ep) ⇒ Object
72 73 74 |
# File 'app/services/neuron_ai_chatbot/api_intent_validator.rb', line 72 def self.normalize_endpoint(ep) ep.to_s.sub(/\A(GET|POST|PUT|PATCH|DELETE)\s+/i, "").strip end |
.path_matches_template?(request_path, template_path) ⇒ Boolean
41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'app/services/neuron_ai_chatbot/api_intent_validator.rb', line 41 def self.path_matches_template?(request_path, template_path) return true if request_path == template_path return false unless template_path.include?("{id}") req_segments = request_path.split("/") tpl_segments = template_path.split("/") return false unless req_segments.length == tpl_segments.length req_segments.zip(tpl_segments).all? do |req_seg, tpl_seg| tpl_seg == "{id}" ? req_seg.match?(/\A\d+\z/) : req_seg == tpl_seg end end |
.present_param?(params, key) ⇒ Boolean
76 77 78 79 80 81 82 |
# File 'app/services/neuron_ai_chatbot/api_intent_validator.rb', line 76 def self.present_param?(params, key) val = params[key] return false if val.nil? return false if val.is_a?(String) && val.strip.blank? true end |
.validate(ai_output, catalog = nil) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'app/services/neuron_ai_chatbot/api_intent_validator.rb', line 5 def self.validate(ai_output, catalog = nil) catalog ||= NeuronAiChatbot.api_knowledge_array return nil if catalog.blank? return nil if ai_output.is_a?(Hash) && ai_output["error"].present? endpoint = normalize_endpoint(ai_output["endpoint"]) method = ai_output["method"].to_s.upcase params = (ai_output["params"] || {}).stringify_keys.dup match = find_catalog_row(catalog, endpoint, method) return nil if match.nil? template_path = match[:endpoint].to_s effective_params = merge_path_params(template_path, endpoint, params) required = Array(match[:required]).map(&:to_s) missing = required.reject { |k| present_param?(effective_params, k) } return nil if missing.empty? { status: 400, body: { "error" => "Missing required parameters for #{method} #{endpoint}.", "missing_required" => missing, "required_fields" => required } } end |