From f91b47f0c350e86ff18232fcee4c312440ec6f21 Mon Sep 17 00:00:00 2001 From: jamey Date: Sun, 22 Feb 2026 21:13:47 +0000 Subject: [PATCH] include browser/os/screen_size in e-commerce analytics events Event call sites (product_view, add_to_cart, checkout_start, purchase) were only passing visitor_hash and pathname, leaving browser, OS, screen size and country nil. Add AnalyticsHook.attrs/1 helper to extract common analytics fields from socket assigns, and use it in all LiveView event call sites. Checkout controller reads the same fields from the session. Also fix plug analytics test to clear stale events before assertions. Co-Authored-By: Claude Opus 4.6 --- lib/berrypod_web/analytics_hook.ex | 14 +++++++++++++ .../controllers/checkout_controller.ex | 6 +++++- .../live/shop/checkout_success.ex | 10 +++++----- lib/berrypod_web/live/shop/product_show.ex | 20 +++++++++++-------- test/berrypod_web/plugs/analytics_test.exs | 1 + 5 files changed, 37 insertions(+), 14 deletions(-) diff --git a/lib/berrypod_web/analytics_hook.ex b/lib/berrypod_web/analytics_hook.ex index 9424c45..f1dc343 100644 --- a/lib/berrypod_web/analytics_hook.ex +++ b/lib/berrypod_web/analytics_hook.ex @@ -79,6 +79,20 @@ defmodule BerrypodWeb.AnalyticsHook do end end + @doc """ + Extracts common analytics attributes from socket assigns. + Call sites can merge their own fields (pathname, revenue, etc.) on top. + """ + def attrs(socket) do + %{ + visitor_hash: socket.assigns[:analytics_visitor_hash], + browser: socket.assigns[:analytics_browser], + os: socket.assigns[:analytics_os], + screen_size: socket.assigns[:analytics_screen_size], + country_code: socket.assigns[:analytics_country_code] + } + end + defp handle_analytics_event("analytics:screen", %{"width" => width}, socket) when is_integer(width) do screen_size = classify_screen(width) diff --git a/lib/berrypod_web/controllers/checkout_controller.ex b/lib/berrypod_web/controllers/checkout_controller.ex index b6de94c..12e2ada 100644 --- a/lib/berrypod_web/controllers/checkout_controller.ex +++ b/lib/berrypod_web/controllers/checkout_controller.ex @@ -134,7 +134,11 @@ defmodule BerrypodWeb.CheckoutController do if visitor_hash do Analytics.track_event("checkout_start", %{ pathname: "/checkout", - visitor_hash: visitor_hash + visitor_hash: visitor_hash, + browser: get_session(conn, "analytics_browser"), + os: get_session(conn, "analytics_os"), + screen_size: get_session(conn, "analytics_screen_size"), + country_code: get_session(conn, "country_code") }) end end diff --git a/lib/berrypod_web/live/shop/checkout_success.ex b/lib/berrypod_web/live/shop/checkout_success.ex index 3a00015..1317cb7 100644 --- a/lib/berrypod_web/live/shop/checkout_success.ex +++ b/lib/berrypod_web/live/shop/checkout_success.ex @@ -14,11 +14,11 @@ defmodule BerrypodWeb.Shop.CheckoutSuccess do # Track purchase event if order && connected?(socket) && socket.assigns[:analytics_visitor_hash] do - Analytics.track_event("purchase", %{ - pathname: "/checkout/success", - visitor_hash: socket.assigns.analytics_visitor_hash, - revenue: order.total - }) + attrs = + BerrypodWeb.AnalyticsHook.attrs(socket) + |> Map.merge(%{pathname: "/checkout/success", revenue: order.total}) + + Analytics.track_event("purchase", attrs) end # Clear the cart after successful checkout diff --git a/lib/berrypod_web/live/shop/product_show.ex b/lib/berrypod_web/live/shop/product_show.ex index fb02eb9..02e907b 100644 --- a/lib/berrypod_web/live/shop/product_show.ex +++ b/lib/berrypod_web/live/shop/product_show.ex @@ -42,10 +42,10 @@ defmodule BerrypodWeb.Shop.ProductShow do gallery_images = filter_gallery_images(all_images, selected_options["Color"]) if connected?(socket) and socket.assigns[:analytics_visitor_hash] do - Analytics.track_event("product_view", %{ - pathname: "/products/#{slug}", - visitor_hash: socket.assigns.analytics_visitor_hash - }) + Analytics.track_event( + "product_view", + Map.put(BerrypodWeb.AnalyticsHook.attrs(socket), :pathname, "/products/#{slug}") + ) end socket = @@ -185,10 +185,14 @@ defmodule BerrypodWeb.Shop.ProductShow do cart = Cart.add_item(socket.assigns.raw_cart, variant.id, socket.assigns.quantity) if socket.assigns[:analytics_visitor_hash] do - Analytics.track_event("add_to_cart", %{ - pathname: "/products/#{socket.assigns.product.slug}", - visitor_hash: socket.assigns.analytics_visitor_hash - }) + Analytics.track_event( + "add_to_cart", + Map.put( + BerrypodWeb.AnalyticsHook.attrs(socket), + :pathname, + "/products/#{socket.assigns.product.slug}" + ) + ) end socket = diff --git a/test/berrypod_web/plugs/analytics_test.exs b/test/berrypod_web/plugs/analytics_test.exs index 1cf4c9b..6c4388d 100644 --- a/test/berrypod_web/plugs/analytics_test.exs +++ b/test/berrypod_web/plugs/analytics_test.exs @@ -9,6 +9,7 @@ defmodule BerrypodWeb.Plugs.AnalyticsTest do setup do send(Buffer, :flush) :timer.sleep(50) + Repo.delete_all(Event) :ok end