Skip to content

Analytics Metrics (Staff)

Reference for the 30-day backoffice metric tiles — engagement, conversion, demo, email-only, booking rate with/without Rose — and the staff-only stats_valid_from cutoff used to rescue them when a tracking-config fix happens mid-window.

This page is for Rose staff investigating metric questions. Client-facing copy lives in the schema's ui:description (rendered inline in the backoffice form) and in the Client Documentation. For deeper backoffice-vs-PostHog discrepancy investigations, see the rose-metric-discrepancy skill in .agents/skills/.

What the tiles show

The Dashboard tiles are read from the materialized view mv_client_stats_30d. Each row is one client, computed across all of that client's domains.

Tile Numerator Denominator Source
Engagement % Unique persons who started a conversation Unique persons whose widget displayed for >10s mv_conversation_visitors / mv_widget_visitors
Conversion % Persons who booked (in-chat) OR captured email (in-chat) OR fired an external client_form_submitted / email_captured / demo_booked event tied to their chat Conversation visitors conversations + session_events
Demo % Persons with conversations.demo_booked = TRUE Conversation visitors conversations
Email-only % Persons with conversations.email_captured = TRUE AND NOT demo_booked Conversation visitors conversations
Booking rate WITH Rose Form submitters who also chatted in-window Form submitters who chatted session_eventsmv_conversation_visitors
Booking rate WITHOUT Rose Form submitters who saw the widget but never chatted Widget-displayed visitors who never chatted session_eventsmv_widget_visitors (excluding chatters)

Definitive view body: supabase/migrations/20260507190000_add_stats_valid_from_to_mv_client_stats_30d.sql. The MV refreshes nightly (and on-demand via REFRESH MATERIALIZED VIEW mv_client_stats_30d).

Window math

For each client, the start of each metric window is the GREATEST of:

  • NOW() - INTERVAL '30 days' — the rolling 30d floor
  • The client's first observed engagement / conversion / form event (so brand-new clients aren't shown as "0%" before they have data)
  • analytics.stats_valid_from — the per-domain cutoff (see below). Aggregated as MAX across a client's domains, so the most-recently-fixed domain caps the whole client.
  • For form_submission_start only: '2026-04-02T09:00:00Z' — the global floor for client_form_submitted events (events before this are not reliable).

NULL cutoffs collapse cleanly through GREATEST(), so clients without stats_valid_from set keep the full 30d behaviour.

When to use stats_valid_from

The 30d window is rolling, so any pre-fix garbage events stay in the numerators / denominators until they age out naturally. That's a problem when a tracking-config bug overcounts forms or undercounts conversions — the "real" post-fix metric is buried under up to 30 days of bad data.

Set stats_valid_from whenever you change any of these and want the dashboard to reflect the post-fix world immediately:

  • analytics.form_tracking_pages — narrowed a wildcard, added/removed a page
  • analytics.thank_you_pages — same
  • analytics.form_detection_strategies — toggled superform, hubspot, network_observer, dom_observer, post_message, cta_page_form, thankyou_page
  • analytics.conversion_filters — form_id whitelist, url_include/exclude
  • Anything that changes which events the widget fires (or which ones the MV counts as conversions)

You do not need to set it for cosmetic config changes (CTA copy, agent prompts, qualification questions) — those don't affect the events the MV reads.

How to set it

The field lives in Settings → Website Agent → Analytics → Stats Valid From (staff-only — non-staff users don't see it; gated by x-access: staff on the schema).

  1. Apply your tracking-config fix and save.
  2. Open the same Analytics page, find Stats Valid From.
  3. Click the picker and either pick a date + UTC time, or click Set to now to use the moment of the fix.
  4. Save the config. The next nightly MV refresh (or a manual REFRESH MATERIALIZED VIEW mv_client_stats_30d) will reflect it.

How to clear it

Open the picker again and click Clear. The value persists as null and the window reverts to the rolling 30d floor on the next refresh.

Don't leave a stale stats_valid_from set forever — once pre-fix events have aged past the rolling 30d floor, the cutoff is doing nothing useful and is just one more thing to remember. A reasonable rule of thumb: clear it ~30 days after you set it, unless you have a reason to keep it.

What it doesn't do

  • It does not delete events from session_events / conversations. The data is preserved; only the MV's window math ignores it.
  • It does not affect PostHog dashboards. PostHog has its own date filters. If you also need PostHog to skip the same window, set the dashboard's date filter manually.
  • It does not apply to per-conversation pages (Conversations, Visitors, Accounts) — those show raw rows, not aggregates. It only affects the 30d MV tiles.

Worked example

Augment's form_tracking_pages was changed from https://checkout.augment.org/* (wildcard, catches login forms) to a tighter pattern on 2026-04-20T07:38:52Z. Before the fix, Augment showed conversion_rate ≈ 24% (inflated by login form submits attributed as conversions). After the fix, new events are clean, but the rolling 30d window still has 30 days of pre-fix events.

Setting stats_valid_from = 2026-04-20T07:38:52Z on the analytics config for augment.org caps all four windows (engagement / conversion / form / email) at that timestamp. After the next refresh, the conversion tile drops to the post-fix value (~8%), reflecting reality. ~30 days later, the cutoff and the rolling floor coincide and you can clear it.

  • Schema: schemas/configs/website/analytics.schema.json (stats_valid_from property)
  • Migrations: supabase/migrations/20260507190000_add_stats_valid_from_to_mv_client_stats_30d.sql, 20260508124627_safe_cast_stats_valid_from_in_mv_client_stats_30d.sql
  • Skill: .agents/skills/rose-metric-discrepancy/ — backoffice-vs-PostHog discrepancy investigation playbook (Pattern 2 in references/known-patterns.md covers the broad-wildcard case)
  • Linear: IX-2913, IX-2928
  • Related pages: Data Sources, Visitor Data Flow