Part of epic #8286 (Phase 2 — Analytics).
Current state
UI pageview analytics run on self-hosted Umami through a deliberately-hardened first-party path: apps/loopover-ui/src/lib/analytics-proxy.ts forwards POST /stats/api/send to the Umami instance under a strict route/method allowlist (its header documents why: never proxy mutable third-party JS as same-origin code; never become an open proxy onto the analytics host's admin API), and the UI sends a tiny local beacon rather than loading the remote tracker script.
Deliverables
Boundaries
- No replay here (own sub-issue). No Umami removal here (gated sub-issue).
Resources
Part of epic #8286 (Phase 2 — Analytics).
Current state
UI pageview analytics run on self-hosted Umami through a deliberately-hardened first-party path:
apps/loopover-ui/src/lib/analytics-proxy.tsforwardsPOST /stats/api/sendto the Umami instance under a strict route/method allowlist (its header documents why: never proxy mutable third-party JS as same-origin code; never become an open proxy onto the analytics host's admin API), and the UI sends a tiny local beacon rather than loading the remote tracker script.Deliverables
posthog-jsinit pointed at our own origin (/stats-prefixed capture path),analytics-proxy.tsrepointed/extended to forward the PostHog capture + static-asset routes it actually needs — allowlist stays load-bearing, nothing else forwarded. Mirror feat(ui): add PostHog web analytics, first-party proxied, alongside Umami metagraphed#7781 and fold in the fix(ui): harden the analytics proxy defensively; enable pageleave + native web vitals metagraphed#7804 hardening lessons up front (defensive proxy behavior,$pageleaveenabled, native web-vitals capture) and the fix(ui): stop a background cache.put() rejection from 500ing the response metagraphed#7794 fix (a backgroundcache.put()rejection must not 500 the response).Boundaries
Resources