Module: Sentiero::Analytics::EntryAttribution
- Included in:
- Analyzer
- Defined in:
- lib/sentiero/analytics/entry_attribution.rb
Overview
Shared "earliest entry page" attribution, mixed into Analyzer so every analyzer gets it (StatsAggregator/ConversionAnalyzer use it directly; EngagementAnalyzer reuses only #earlier?, see its own track_entry_url — it scans every Meta in a window for the globally-earliest one instead of deferring to the window's first Meta, so it isn't update_entry_candidate).
entry_url precedence: an explicit entry_url from session metadata is authoritative (callers anchor it at -Infinity so no Meta can displace it); otherwise the first Meta href of the earliest-starting window wins.
Instance Method Summary collapse
-
#earlier?(a, b, nil_anchor_is_earlier: false) ⇒ Boolean
a "earlier than" b.
- #first_meta_href(events) ⇒ Object
-
#same_origin?(referrer, entry_url) ⇒ Boolean
Self-referral: same scheme://host:port.
-
#update_entry_candidate(state, events) ⇒ Object
Deferred candidate for one session, updated once per window: the window's first Meta href, anchored by the WINDOW's first event timestamp (not the Meta's own timestamp) so windows compare by when they started, not by their first navigation's exact instant.
Instance Method Details
#earlier?(a, b, nil_anchor_is_earlier: false) ⇒ Boolean
a "earlier than" b. nil_anchor_is_earlier: true lets a later,
well-timed candidate displace one whose anchor came back nil (an
accepted Meta whose own event lacked a numeric timestamp) —
EngagementAnalyzer's track_entry_url needs this because it can accept
a nil-anchor candidate on the first match it sees. StatsAggregator and
ConversionAnalyzer never reach that state: their nil-anchor candidate
is only ever the FIRST one (accepted unconditionally via the
entry_url.nil? guard before earlier? is consulted), so the default
(false) is the correct, stricter behavior for them.
26 27 28 29 30 31 |
# File 'lib/sentiero/analytics/entry_attribution.rb', line 26 def earlier?(a, b, nil_anchor_is_earlier: false) return false unless a.is_a?(Numeric) return true if b.nil? && nil_anchor_is_earlier b.is_a?(Numeric) && a < b end |
#first_meta_href(events) ⇒ Object
33 34 35 36 37 38 39 |
# File 'lib/sentiero/analytics/entry_attribution.rb', line 33 def (events) events.each do |event| href = (event) return href if href end nil end |
#same_origin?(referrer, entry_url) ⇒ Boolean
Self-referral: same scheme://host:port. Unparseable or host-less values return false (kept — not provably internal).
58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/sentiero/analytics/entry_attribution.rb', line 58 def same_origin?(referrer, entry_url) return false unless referrer.is_a?(String) && entry_url.is_a?(String) ref = URI.parse(referrer) entry = URI.parse(entry_url) return false unless ref.host && entry.host ref.scheme == entry.scheme && ref.host == entry.host && ref.port == entry.port rescue URI::InvalidURIError false end |
#update_entry_candidate(state, events) ⇒ Object
Deferred candidate for one session, updated once per window: the window's first Meta href, anchored by the WINDOW's first event timestamp (not the Meta's own timestamp) so windows compare by when they started, not by their first navigation's exact instant.
45 46 47 48 49 50 51 52 53 54 |
# File 'lib/sentiero/analytics/entry_attribution.rb', line 45 def update_entry_candidate(state, events) href = (events) return unless href anchor = events.first&.fetch("timestamp", nil) return unless state[:entry_url].nil? || earlier?(anchor, state[:entry_anchor]) state[:entry_url] = href state[:entry_anchor] = anchor end |