Server-side sessionization context.
sessionize/3 resolves the live session for a {workspace_id, visitor_id}
with an anonymous_id fallback for freshly minted visitor ids, then applies
the 30-minute inactivity boundary plus acquisition-change splitting.
Summary
Functions
Returns the live session for a visitor within the window, or nil.
Attaches an engagement beacon to the visitor's live session.
Find-or-create the live session for key and fold the event into it.
Types
@type key() :: %{ :workspace_id => Ecto.UUID.t(), :visitor_id => Ecto.UUID.t(), optional(:anonymous_id) => String.t() | nil }
The session key carried from the recorder.
Functions
@spec find_live_session( module(), Ecto.UUID.t(), Ecto.UUID.t(), String.t() | nil, DateTime.t() ) :: GoodAnalytics.Core.Sessions.Session.t() | nil
Returns the live session for a visitor within the window, or nil.
@spec record_engagement(key(), map(), DateTime.t()) :: {:ok, GoodAnalytics.Core.Sessions.Session.t()} | :no_session
Attaches an engagement beacon to the visitor's live session.
Accumulates engaged seconds from engaged_ms, bumps last_event_at,
refreshes is_engaged, and recomputes duration using the same 30-minute
per-hop cap as normal session updates. This never creates a session and never
un-bounces one.
@spec sessionize(key(), String.t(), map()) :: {:ok, GoodAnalytics.Core.Sessions.Session.t()} | {:error, term()}
Find-or-create the live session for key and fold the event into it.
The event timestamp is read from attrs[:__ts__] or attrs["__ts__"];
when absent, the current UTC time is used.