PhoenixKitWebAnalytics.Schemas.Event (PhoenixKitWebAnalytics v0.5.0)

Copy Markdown View Source

One analytics hit — a page view or a custom event.

Rows are append-only: there is no updated_at and nothing ever updates an event after insert. PhoenixKitWebAnalytics.Retention rolls old rows into PhoenixKitWebAnalytics.Schemas.DailyStat and deletes them.

Identity is cookieless

There is no cookie, no local storage, and no raw IP address in this table. visitor_id is a truncated SHA-256 of salt <> ip <> user_agent <> date (see PhoenixKitWebAnalytics.Visitor) — it cannot be reversed to an IP, it cannot be joined across days, and it changes when the daily salt rotates. The exception is click_id: an ad platform's own identifier, kept when a visit lands with one, which is pseudonymous and links to the platform's user (see the README's Privacy section). session_id is stitched server-side by PhoenixKitWebAnalytics.Collector: an event reuses the visitor's previous session when the previous hit is inside the session window, otherwise it starts a new one.

Event types

  • "pageview" — one HTML response served, or one LiveView navigation
  • "event" — a custom event reported through PhoenixKitWebAnalytics.track_event/2 or the beacon endpoint
  • "interaction" — something the visitor did on a page: a LiveView event (event_name is the event, e.g. "add_to_cart") or a click reported by the optional client script (event_name is "click", "outbound" or "download", target what was clicked)
  • "leave" — the visitor left a page; engaged_ms is how long it was open and scroll_depth (client script only) how far they scrolled

Tables are created by PhoenixKitWebAnalytics.Migrations, never by this schema.

Summary

Functions

Changeset for a single hit.

Valid device_type values.

Valid event_type values.

Valid referrer_medium values.

Types

t()

@type t() :: %PhoenixKitWebAnalytics.Schemas.Event{
  __meta__: term(),
  browser: term(),
  browser_version: term(),
  city: term(),
  click_id: term(),
  click_param: term(),
  country_code: term(),
  device_type: term(),
  duration_ms: term(),
  engaged_ms: term(),
  event_name: term(),
  event_type: term(),
  inserted_at: term(),
  is_bot: term(),
  language: term(),
  metadata: term(),
  os: term(),
  os_version: term(),
  page_title: term(),
  path: term(),
  referrer: term(),
  referrer_medium: term(),
  referrer_source: term(),
  region: term(),
  scroll_depth: term(),
  session_id: term(),
  session_start: term(),
  site: term(),
  status: term(),
  target: term(),
  user_uuid: term(),
  utm_campaign: term(),
  utm_content: term(),
  utm_medium: term(),
  utm_source: term(),
  utm_term: term(),
  uuid: term(),
  visitor_id: term()
}

Functions

changeset(event, attrs)

@spec changeset(t(), map()) :: Ecto.Changeset.t()

Changeset for a single hit.

Long free-text fields are truncated rather than rejected — an over-long page_title or referrer from the wild must never cost us the whole event.

device_types()

@spec device_types() :: [String.t()]

Valid device_type values.

event_types()

@spec event_types() :: [String.t()]

Valid event_type values.

referrer_mediums()

@spec referrer_mediums() :: [String.t()]

Valid referrer_medium values.