Turns an untrusted beacon payload into a hit map for
PhoenixKitWebAnalytics.Collector.
This is the trust boundary for the two public collection endpoints, kept out of the controller so it can be tested directly for exactly the things that matter: what a client can and cannot influence.
A client controls only the content of a hit — which path, which event name, which properties. It cannot influence identity or origin:
siteisconn.host, so a payload can't attribute hits to another site- only the path is read from the client's URL; scheme and host are dropped
user_uuidcomes from the session, never from the bodyvisitor_idis derived server-side downstream and isn't representable here at all
Free-form content is capped so an unbounded jsonb blob per event can't turn the analytics table into the largest one in the database: 20 properties, 200 bytes per value, 120 bytes of event name.
Summary
Functions
Whether the payload describes a custom event or a page view.
Extracts just the path from a client-sent URL.
Caps custom event properties by count, key length, and value size.
Builds the hit map for params received on conn.
Extracts campaign parameters from a client-sent URL's query string.
Functions
Whether the payload describes a custom event or a page view.
A payload with a non-empty n is an event; everything else — including an
explicit "e" => "pageview" — is a page view.
Extracts just the path from a client-sent URL.
Anything that isn't an absolute path becomes "/" — URI.parse/1 happily
reports a bare word as a relative path, and a "path" that doesn't start with
a slash would corrupt every pages report it appeared in.
iex> PhoenixKitWebAnalytics.Web.BeaconPayload.path("https://evil.example/steal?x=1")
"/steal"
iex> PhoenixKitWebAnalytics.Web.BeaconPayload.path("garbage")
"/"
Caps custom event properties by count, key length, and value size.
@spec to_hit(Plug.Conn.t(), map()) :: map()
Builds the hit map for params received on conn.
Never raises: every field degrades to nil or a default, because the caller
is a public endpoint that must answer 204 no matter what it was sent.
Extracts campaign parameters from a client-sent URL's query string.