add privacy-first analytics with progressive event collection
All checks were successful
deploy / deploy (push) Successful in 3m20s
All checks were successful
deploy / deploy (push) Successful in 3m20s
Three-layer pipeline: Plug for all HTTP requests (no JS needed), LiveView hook for SPA navigations, JS hook for screen width. ETS-backed buffer batches writes to SQLite every 10s. Daily-rotating salt for visitor hashing. Includes admin dashboard with date ranges, visitor trends, top pages, sources, devices, and e-commerce conversion funnel. Oban cron for 12-month data retention. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
defmodule BerrypodWeb.Shop.CheckoutSuccess do
|
||||
use BerrypodWeb, :live_view
|
||||
|
||||
alias Berrypod.Orders
|
||||
alias Berrypod.{Analytics, Orders}
|
||||
|
||||
@impl true
|
||||
def mount(%{"session_id" => session_id}, _session, socket) do
|
||||
@@ -12,6 +12,15 @@ defmodule BerrypodWeb.Shop.CheckoutSuccess do
|
||||
Phoenix.PubSub.subscribe(Berrypod.PubSub, "order:#{order.id}:status")
|
||||
end
|
||||
|
||||
# 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
|
||||
})
|
||||
end
|
||||
|
||||
# Clear the cart after successful checkout
|
||||
socket =
|
||||
if order && connected?(socket) do
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
defmodule BerrypodWeb.Shop.ProductShow do
|
||||
use BerrypodWeb, :live_view
|
||||
|
||||
alias Berrypod.Cart
|
||||
alias Berrypod.{Analytics, Cart}
|
||||
alias Berrypod.Images.Optimizer
|
||||
alias Berrypod.Products
|
||||
alias Berrypod.Products.{Product, ProductImage}
|
||||
@@ -41,6 +41,13 @@ defmodule BerrypodWeb.Shop.ProductShow do
|
||||
display_price = variant_price(selected_variant, product)
|
||||
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
|
||||
})
|
||||
end
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> assign(:page_title, product.title)
|
||||
@@ -177,6 +184,13 @@ defmodule BerrypodWeb.Shop.ProductShow do
|
||||
if variant 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
|
||||
})
|
||||
end
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> BerrypodWeb.CartHook.broadcast_and_update(cart)
|
||||
|
||||
Reference in New Issue
Block a user