mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-04-08 03:00:28 -04:00
Introduces an analytics/ layer that wraps production Postgres data in safe, read-only views exposed under the analytics schema. - 14 documented query files in queries/ (one per Looker data source) covering auth activities, user activity, execution metrics, onboarding funnel, and cohort retention (login + execution, weekly + daily) - setup.sql — one-time schema creation and role/grant setup for the analytics_readonly role (auth, platform, analytics schemas) - generate_views.py — reads queries/*.sql and applies CREATE OR REPLACE VIEW analytics.<name> to the database; supports --dry-run, --only, and --db-url flags - views.sql — pre-generated combined reference output - README.md — full setup, deployment, and integration guide Looker, PostHog Data Warehouse, and Supabase MCP (for Otto) all connect to the same analytics.* views instead of raw tables.
97 lines
4.7 KiB
SQL
97 lines
4.7 KiB
SQL
-- =============================================================
|
|
-- View: analytics.retention_login_onboarded_weekly
|
|
-- Looker source alias: ds101 | Charts: 2
|
|
-- =============================================================
|
|
-- DESCRIPTION
|
|
-- Weekly cohort retention from login sessions, restricted to
|
|
-- users who "onboarded" — defined as running at least one
|
|
-- agent within 365 days of their first login.
|
|
-- Filters out users who signed up but never activated,
|
|
-- giving a cleaner view of engaged-user retention.
|
|
--
|
|
-- SOURCE TABLES
|
|
-- auth.sessions — Login session records
|
|
-- platform.AgentGraphExecution — Used to identify onboarders
|
|
--
|
|
-- OUTPUT COLUMNS
|
|
-- Same as retention_login_weekly (cohort_week_start, user_lifetime_week,
|
|
-- retention_rate_bounded, retention_rate_unbounded, etc.)
|
|
-- Only difference: cohort is filtered to onboarded users only.
|
|
--
|
|
-- EXAMPLE QUERIES
|
|
-- -- Compare week-4 retention: all users vs onboarded only
|
|
-- SELECT 'all_users' AS segment, AVG(retention_rate_bounded) AS w4_retention
|
|
-- FROM analytics.retention_login_weekly WHERE user_lifetime_week = 4
|
|
-- UNION ALL
|
|
-- SELECT 'onboarded', AVG(retention_rate_bounded)
|
|
-- FROM analytics.retention_login_onboarded_weekly WHERE user_lifetime_week = 4;
|
|
-- =============================================================
|
|
|
|
WITH params AS (SELECT 12::int AS max_weeks, 365::int AS onboarding_window_days),
|
|
events AS (
|
|
SELECT s.user_id::text AS user_id, s.created_at::timestamptz AS created_at,
|
|
DATE_TRUNC('week', s.created_at)::date AS week_start
|
|
FROM auth.sessions s WHERE s.user_id IS NOT NULL
|
|
),
|
|
first_login_all AS (
|
|
SELECT user_id, MIN(created_at) AS first_login_time,
|
|
DATE_TRUNC('week', MIN(created_at))::date AS cohort_week_start
|
|
FROM events GROUP BY 1
|
|
),
|
|
onboarders AS (
|
|
SELECT fl.user_id FROM first_login_all fl
|
|
WHERE EXISTS (
|
|
SELECT 1 FROM platform."AgentGraphExecution" e
|
|
WHERE e."userId"::text = fl.user_id
|
|
AND e."createdAt" >= fl.first_login_time
|
|
AND e."createdAt" < fl.first_login_time
|
|
+ make_interval(days => (SELECT onboarding_window_days FROM params))
|
|
)
|
|
),
|
|
first_login AS (SELECT * FROM first_login_all WHERE user_id IN (SELECT user_id FROM onboarders)),
|
|
activity_weeks AS (SELECT DISTINCT user_id, week_start FROM events),
|
|
user_week_age AS (
|
|
SELECT aw.user_id, fl.cohort_week_start,
|
|
((aw.week_start - DATE_TRUNC('week',fl.first_login_time)::date)/7)::int AS user_lifetime_week
|
|
FROM activity_weeks aw JOIN first_login fl USING (user_id)
|
|
WHERE aw.week_start >= DATE_TRUNC('week',fl.first_login_time)::date
|
|
),
|
|
bounded_counts AS (
|
|
SELECT cohort_week_start, user_lifetime_week, COUNT(DISTINCT user_id) AS active_users_bounded
|
|
FROM user_week_age WHERE user_lifetime_week >= 0 GROUP BY 1,2
|
|
),
|
|
last_active AS (
|
|
SELECT cohort_week_start, user_id, MAX(user_lifetime_week) AS last_active_week FROM user_week_age GROUP BY 1,2
|
|
),
|
|
unbounded_counts AS (
|
|
SELECT la.cohort_week_start, gs AS user_lifetime_week, COUNT(*) AS retained_users_unbounded
|
|
FROM last_active la
|
|
CROSS JOIN LATERAL generate_series(0, LEAST(la.last_active_week,(SELECT max_weeks FROM params))) gs
|
|
GROUP BY 1,2
|
|
),
|
|
cohort_sizes AS (SELECT cohort_week_start, COUNT(DISTINCT user_id) AS cohort_users FROM first_login GROUP BY 1),
|
|
cohort_caps AS (
|
|
SELECT cs.cohort_week_start, cs.cohort_users,
|
|
LEAST((SELECT max_weeks FROM params),
|
|
GREATEST(0,((DATE_TRUNC('week',CURRENT_DATE)::date-cs.cohort_week_start)/7)::int)) AS cap_weeks
|
|
FROM cohort_sizes cs
|
|
),
|
|
grid AS (
|
|
SELECT cc.cohort_week_start, gs AS user_lifetime_week, cc.cohort_users
|
|
FROM cohort_caps cc CROSS JOIN LATERAL generate_series(0, cc.cap_weeks) gs
|
|
)
|
|
SELECT
|
|
g.cohort_week_start,
|
|
TO_CHAR(g.cohort_week_start,'IYYY-"W"IW') AS cohort_label,
|
|
TO_CHAR(g.cohort_week_start,'IYYY-"W"IW')||' (n='||g.cohort_users||')' AS cohort_label_n,
|
|
g.user_lifetime_week, g.cohort_users,
|
|
COALESCE(b.active_users_bounded,0) AS active_users_bounded,
|
|
COALESCE(u.retained_users_unbounded,0) AS retained_users_unbounded,
|
|
CASE WHEN g.cohort_users>0 THEN COALESCE(b.active_users_bounded,0)::float/g.cohort_users END AS retention_rate_bounded,
|
|
CASE WHEN g.cohort_users>0 THEN COALESCE(u.retained_users_unbounded,0)::float/g.cohort_users END AS retention_rate_unbounded,
|
|
CASE WHEN g.user_lifetime_week=0 THEN g.cohort_users ELSE 0 END AS cohort_users_w0
|
|
FROM grid g
|
|
LEFT JOIN bounded_counts b ON b.cohort_week_start=g.cohort_week_start AND b.user_lifetime_week=g.user_lifetime_week
|
|
LEFT JOIN unbounded_counts u ON u.cohort_week_start=g.cohort_week_start AND u.user_lifetime_week=g.user_lifetime_week
|
|
ORDER BY g.cohort_week_start, g.user_lifetime_week;
|