Class: Crm::OpportunityLinkPath

Inherits:
Object
  • Object
show all
Defined in:
app/services/crm/opportunity_link_path.rb

Overview

Resolves ON… tokens to canonical CRM opportunity paths: +/opportunities/:id+.

LLMs often emit +ON+ plus a number that is the row +id+ (not +reference_number+).
+reference_number+ is +ON+ + sequence and may not equal +id+.

Resolution order:

  1. +Opportunity+ with +reference_number+ matching +ON#digits+ (case-insensitive)
  2. Else +Opportunity+ with primary key +digits.to_i+ when that row exists
  3. Else fallback +/opportunities/#digits+ (may 404; avoids leaving broken +/opportunities/ON…+ paths)

Class Method Summary collapse

Class Method Details

.path_for_on_digits(digits) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'app/services/crm/opportunity_link_path.rb', line 14

def self.path_for_on_digits(digits)
  digits = digits.to_s.strip
  return '/opportunities/0' if digits.blank?

  numeric = digits.to_i
  ref = "ON#{digits}"

  opp = Opportunity.find_by(reference_number: ref)
  opp ||= Opportunity.where('reference_number ILIKE ?', ref).first
  return "/opportunities/#{opp.id}" if opp

  return "/opportunities/#{numeric}" if numeric.positive? && Opportunity.exists?(numeric)

  "/opportunities/#{numeric}"
end

.rewrite_on_segments_in_text(text) ⇒ Object

Rewrites +/opportunities/ON123+ segments anywhere in +text+ (markdown/HTML/plain URLs).
Preserves an optional URL fragment (+#quotes+, etc.) immediately after the numeric tail.



32
33
34
35
36
37
38
39
40
# File 'app/services/crm/opportunity_link_path.rb', line 32

def self.rewrite_on_segments_in_text(text)
  return text if text.blank?

  text.gsub(%r{/opportunities/ON(\d+)(#[\w.+-]*)?}i) do
    digits = ::Regexp.last_match(1)
    frag = ::Regexp.last_match(2).to_s
    "#{path_for_on_digits(digits)}#{frag}"
  end
end