Class: PartyResearch::Adapters::Base
- Inherits:
-
Object
- Object
- PartyResearch::Adapters::Base
- Defined in:
- app/services/party_research/adapters/base.rb
Direct Known Subclasses
Defined Under Namespace
Classes: AdapterError, ConfigurationError
Constant Summary collapse
- ALL =
Explicit registry — adding a new adapter requires registering it here.
We intentionally don't use.descendantsbecause Zeitwerk only loads
subclasses when something references them; in dev mode the list would
be empty until each adapter class is referenced elsewhere.Ordering matters: Gemini runs last and acts as the arbiter, taking
all the other adapters' raw findings as context for synthesis. %w[apollo people_data_labs google_places gemini].freeze
- PERSONAL_EMAIL_DOMAINS =
Consumer/webmail domains that don't anchor a company lookup. Shared
by adapters that derive a company domain (PDL) or judge whether an
email is a corporate anchor worth grounding on (Gemini). Subclasses
reference it unqualified via constant inheritance. %w[ gmail.com yahoo.com hotmail.com outlook.com aol.com icloud.com me.com mac.com live.com msn.com proton.me protonmail.com ymail.com rocketmail.com att.net comcast.net verizon.net sbcglobal.net cox.net charter.net bellsouth.net juno.net earthlink.net optonline.net mindspring.net netzero.net ].to_set.freeze
Instance Attribute Summary collapse
-
#party ⇒ Object
readonly
protected
Returns the value of attribute party.
-
#raw_findings ⇒ Object
readonly
protected
Returns the value of attribute raw_findings.
Class Method Summary collapse
- .adapter_name ⇒ Object
-
.arbiter? ⇒ Boolean
Whether this adapter SYNTHESIZES findings from raw inputs (Gemini) versus emitting raw API-derived findings of its own (everyone else).
-
.configured? ⇒ Boolean
Override to return false when credentials are missing.
- .lookup(name) ⇒ Object
-
.registered ⇒ Object
All registered adapter classes, in display order.
-
.relevant_for?(_party) ⇒ Boolean
Override to declare whether this adapter is likely to return useful findings for the given party.
Instance Method Summary collapse
-
#finding(category:, proposed_value:, field: nil, confidence: nil, evidence: {}) ⇒ Object
protected
Build a normalized finding hash.
-
#findings_for ⇒ Array<Hash>
Finding-attribute hashes — see #finding.
-
#initialize(party, raw_findings: []) ⇒ Base
constructor
The Gemini arbiter receives
raw_findings:— every other adapter ignores it.
Constructor Details
#initialize(party, raw_findings: []) ⇒ Base
The Gemini arbiter receives raw_findings: — every other
adapter ignores it. Defaulted to [] so existing call sites
don't need to change.
92 93 94 95 |
# File 'app/services/party_research/adapters/base.rb', line 92 def initialize(party, raw_findings: []) @party = party @raw_findings = raw_findings end |
Instance Attribute Details
#party ⇒ Object (readonly, protected)
Returns the value of attribute party.
104 105 106 |
# File 'app/services/party_research/adapters/base.rb', line 104 def party @party end |
#raw_findings ⇒ Object (readonly, protected)
Returns the value of attribute raw_findings.
104 105 106 |
# File 'app/services/party_research/adapters/base.rb', line 104 def raw_findings @raw_findings end |
Class Method Details
.adapter_name ⇒ Object
46 47 48 |
# File 'app/services/party_research/adapters/base.rb', line 46 def adapter_name name.demodulize.underscore end |
.arbiter? ⇒ Boolean
Whether this adapter SYNTHESIZES findings from raw inputs
(Gemini) versus emitting raw API-derived findings of its own
(everyone else). Used by the orchestrator to flag the resulting
party_research_findings.arbiter column.
72 73 74 |
# File 'app/services/party_research/adapters/base.rb', line 72 def arbiter? false end |
.configured? ⇒ Boolean
Override to return false when credentials are missing. The default
returns true so adapters that don't need configuration (a noop
test adapter, an LLM with a globally-set key) work without extra
boilerplate.
54 55 56 |
# File 'app/services/party_research/adapters/base.rb', line 54 def configured? true end |
.lookup(name) ⇒ Object
76 77 78 79 80 81 |
# File 'app/services/party_research/adapters/base.rb', line 76 def lookup(name) klass = "PartyResearch::Adapters::#{name.to_s.camelize}".safe_constantize return nil unless klass && klass < self klass end |
.registered ⇒ Object
All registered adapter classes, in display order.
84 85 86 |
# File 'app/services/party_research/adapters/base.rb', line 84 def registered ALL.filter_map { |name| lookup(name) } end |
.relevant_for?(_party) ⇒ Boolean
Override to declare whether this adapter is likely to return
useful findings for the given party. The picker UI uses this to
decide whether to check the box by default — irrelevant adapters
still appear (so the user can opt in) but start unchecked. The
default is "true" so adapters without an opinion (a hypothetical
universal lookup) are checked by default.
64 65 66 |
# File 'app/services/party_research/adapters/base.rb', line 64 def relevant_for?(_party) true end |
Instance Method Details
#finding(category:, proposed_value:, field: nil, confidence: nil, evidence: {}) ⇒ Object (protected)
Build a normalized finding hash. Categories outside PartyResearchFinding::CATEGORIES
are rejected at the DB layer (Postgres enum), so a typo crashes the
transaction rather than silently writing junk.
109 110 111 112 113 114 115 116 117 118 |
# File 'app/services/party_research/adapters/base.rb', line 109 def finding(category:, proposed_value:, field: nil, confidence: nil, evidence: {}) { adapter: self.class.adapter_name, category: category.to_s, field: field, proposed_value: proposed_value, confidence: confidence, evidence: evidence } end |
#findings_for ⇒ Array<Hash>
Returns finding-attribute hashes — see #finding.
98 99 100 |
# File 'app/services/party_research/adapters/base.rb', line 98 def findings_for raise NotImplementedError, "#{self.class} must implement #findings_for" end |