Repository navigation
metrics: shared v_* views + north_star.sql (one definition of sessions, actives, shares) - #393
Merged
Merged
Conversation
One definition of feed session (30-min gap on feed sends; broadcast% is push), actives, non-self shares, new-user funnel and per-assignment outcomes, as plain views. analytics_excluded_user holds automated accounts (filled by an operator from excluded-users-detector.sql). north_star.sql is the canonical readout.
… guard reached_5 for young users; super_user segment
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Today there are ~4 session definitions in
docs/analyst/(reaction gaps vs send gaps, with or without push rows, >= 2 memes or not), and readouts silently disagree. This adds ONE metrics layer that agents and experiment readouts share.What
One Alembic migration (
a7c3e9f1b5d2, on top ofe5a7c9b1d3f4): plain views + one table.SET lock_timeout = '5s',CREATE OR REPLACE VIEW/CREATE TABLE IF NOT EXISTS, so it is safe to re-run.analytics_excluded_user(user_id, reason, created_at): automated accounts, stored as data so user IDs never enter the repo. The migration leaves it empty.v_metric_user: segment (excluded/moderator/admin/user), signup, acquisition channel (the first/startdeep link within a day of signup: organic / share / channel / vcru / ...;unknownbefore the log existed), languages.v_feed_session: feed sends only (recommended_by NOT LIKE 'broadcast%'); a new session starts after a 30-min gap. Columns: memes_sent, reactions, likes, started_by_push.v_user_day: memes_sent / reactions / likes (feed + push), feed sessions, and shares (distinct non-self clicks on the user'sm_/s_links).v_new_user: got_first_meme, first_tap, first_like (all on the first meme), reached_5_reactions (within 7d), d1/d7 return (NULL until observable), blocked_within_24h.v_experiment_user: one row perexperiment_assignment, with outcomes since assignment (reactions/likes per week, memes per session) for user-level-mean readouts.docs/analyst/north_star.sql: 4 queries over the last 28 days in 7-day buckets. All of them dropsegment='excluded'. Q2 and Q3 also drop moderators and admins, because their low_sent_pool review work inflates reactions and session length.docs/analyst/excluded-users-detector.sql: finds users with >= 50 push reactions where >= 50% of them fall in one 10-second bin of (reacted_at - sent_at).v_experiment_usercross-check.Performance (prod, read-only, views inlined as NOT MATERIALIZED CTEs, 28-day window)
Filter on the views' date columns with plain bounds (
CURRENT_DATE - 28). WithDATE_TRUNC(now())bounds the filter is evaluated per row, and Q2/Q4 took about 25 s. Session-start detection usesLATERAL ... LIMIT 1so the planner keeps per-row index probes; withNOT EXISTSit hashed the whole table and took more than 150 s.Tests
tests/test_metrics_views.pybuilds a tiny fixture (3 users, feed + push sends, share deep links, one excluded user, one assignment) and checks every view. Upgrade, re-run after stamp and downgrade were checked manually against a local DB (not in the test).Deploy
docs/analyst/excluded-users-detector.sql, reviews it (today it returns 1 candidate), and inserts the rows:INSERT INTO analytics_excluded_user (user_id, reason) <query> ON CONFLICT (user_id) DO NOTHING;Review fixes
started_by_pushnow requires the push to have been opened within 15 min of delivery. Before, idle users always had a push as the last chat message, so about 90% of returns looked push-driven.reached_5_reactionsis NULL until 8 days after signup.super_usergets its own segment.v_user_dayattributes reactions to the send day; thev_experiment_userwindow is open-ended, so bound it in readouts.