Stack Specification
Section 13

Observability & analytics

A small, deliberate set of events is more valuable than blanket tracking. Children’s mode disables all behavioural analytics.

13.1 — Tooling

ConcernChoice
Product analyticsPostHog (self‑hostable, EU region) — see Section 20
Crash reportingSentry
Performance tracesSentry performance + custom canvas timers
Backend logsInsForge function logs + Sentry server SDK

13.2 — Event taxonomy (initial)

app_opened
library_viewed              { section: featured | new | category | downloaded }
artwork_viewed              { artwork_id, source }
artwork_download_started    { artwork_id, premium }
artwork_download_completed  { artwork_id, bytes, duration_ms }
artwork_opened              { artwork_id, open_duration_ms }
region_filled               { artwork_id, colour_id, correct }
artwork_completed           { artwork_id, total_duration_min }
paywall_viewed              { trigger }
purchase_started            { product_id }
purchase_succeeded          { product_id }
purchase_failed             { product_id, reason }
sync_failed                 { reason }

13.3 — Children’s‑mode policy

When profiles.child_mode = true, the analytics SDK is initialised in opt‑out mode: only app_opened and crash signals are sent, all user_id fields are stripped, and ad SDKs are not loaded.