Tools · Analytics map ← Tools menu Updated 10-09-2026

Analytics map

Source of truth: Notion · byForja — Claude Code HQ — specifics (no analytics page yet) Refreshed: —
D1 tables
—
Event types
—
Endpoints
—

D1 tables

TableRowsLast write
—

Event types (events table)

Type30dTotal
—

Endpoints + dashboards

PathReads
—

Event catalogue · accepted by /api/events on byforja.com (bf-tracking.js)

Event typeWhen it firesMeta payloadNotes
page_visit On DOMContentLoaded (none — base fields only) Auto-fired by bf-tracking.js
page_exit On pagehide / beforeunload { path, ms, max_depth, had_conversion } Single structured exit event
scroll_depth When scroll crosses 25/50/75/100% { depth } One per threshold per page load
time_on_page On pagehide / beforeunload { ms, max_depth } Visible-time only (excludes hidden tab time)
click On every click (debounced 400ms) { x, y, tag, id, track_id, text } Coordinates as % of viewport
outbound_click On click of external <a> { host, href } Captured before navigation
contact_link_clicked On click of mailto: / tel: / sms: { scheme, href } Counts as conversion-adjacent
cta_call_clicked Manual bfTrack() on "Book a call" CTA (custom) Wire on byforja.com CTAs
cta_signin_clicked Manual bfTrack() on Sign-In button (custom) Pending Sign-In UI rollout
nav_lang_switched Manual bfTrack() on FR/EN toggle { from, to } Pending wiring
newsletter_signup Manual bfTrack() on newsletter form submit (custom) Pending newsletter
web_vital Auto (LCP / FID / CLS) { name, value } Pending Web Vitals integration
js_error Auto on uncaught JS error { message, stack, source } Pending error handler
Self-exclusion: visit any byforja.com page with ?bftrack=off (localStorage flag, ?bftrack=on to re-enable); server side, EXCLUDE_IPS drops listed IPs in /api/events

Analytics process · Claude ∩ AL

Working agreement + design rules for every data point tracked and displayed on byForja.

Rule 1 · drill-down
Every displayed data point links to an existing page that drills deeply into the data, OR opens a drawer (side panel) on click showing the exact data values displayed.
Rule 2 · yellow bar
Each "existing page" lives in tools.byforja.com/, with a yellow line bar (#fbbf24) at the start of the row on the parent menu.
Rule 3 · Type A vs Type B
Type A (Core data, Clients, Clients-detail): AL curated, strict layouts. Type B (all /data pages): Claude Code visual free hand, emerald/rose/violet/sky/amber palette, 88px hero KPI, drill-down drawers, vertical scroll allowed.
Rule 4 · title coherence
Tile menu = <title> tab = page <h1>. Strict match (optional period suffix).
Rule 5 · funnel order
On every data sub-menu: order top-of-funnel → bottom (acquisition → engagement → conversion → retention). Visual scan reflex for AL.
Rule 6 · backward-compat
Any renamed URL/data keeps the old path via _redirects 301. No internal link or external bookmark breaks.
Rule 7 · RGPD consent
Tracking site public via bf-tracking.js; consent banner on byforja.com not verified on 2026-09-10. consent_level=full mint visitor_id persistent ; minimal = session-only anonyme.
Rule 8 · server-side enrichment
Every event is enriched server-side in /api/events with country/region/city, device_class, ua_browser/os, source_class, is_bot, user_email (when authenticated), before the D1 insert.
Rule 9 · error_events watchdog
Server-side 4xx/5xx errors logged into error_events. CRON7 daily 06:00 UTC checks the past 24h, Resend email if > 0. No silent bugs.
Rule 10 · extended smoke
On every deploy: npm run deploy:prod runs the mobile check then scripts/smoke-test.sh (every page and API of this intranet). Zero hidden regression.
Rule 11 · bot filter
All data aggregates filter on COALESCE(is_bot,0)=0. Bot detection via CF botManagement + UA regex fallback.
Rule 12 · self-update doc
Any new D1 table / /api/admin/* endpoint / tools dashboard = update the hard-coded list in analytics-map.js.

12 rules · last updated 2026-09-10 · this is the agreement between Claude Code and AL on how data flows + displays on byForja. Inherited from the EO agreement (rule 15 parity, 2026-09-10).