MCPcopy Create free account
hub / github.com/colbymchenry/codegraph / retention

Function retention

telemetry-dashboard/src/api.ts:704–760  ·  view source on GitHub ↗

* For machines first seen in the range, the share still active k days later. * * Read entirely off `machine_days` + `machine_first_seen`, neither of which the * retention purge touches, so this answers for any range in history. * * The denominator is per-k, not the whole cohort: a machine first

(env: Env, range: Range)

Source from the content-addressed store, hash-verified

702 * elapsed contributes zero to day k by construction.
703 */
704async function retention(env: Env, range: Range): Promise<ApiResult> {
705 const batch = await env.DB.batch([
706 env.DB.prepare(
707 `SELECT CAST(julianday(d.day) - julianday(f.first_day) AS INTEGER) AS k,
708 count(DISTINCT d.machine_id) AS machines
709 FROM machine_first_seen f
710 JOIN machine_days d ON d.machine_id = f.machine_id
711 WHERE f.first_day BETWEEN ? AND ?
712 AND d.day >= f.first_day
713 AND d.day <= date(f.first_day, ?)
714 GROUP BY k`,
715 ).bind(range.from, range.to, `+${RETENTION_DAYS} days`),
716 env.DB.prepare(
717 `SELECT first_day AS day, count(*) AS machines
718 FROM machine_first_seen WHERE first_day BETWEEN ? AND ? GROUP BY first_day`,
719 ).bind(range.from, range.to),
720 env.DB.prepare(`SELECT max(day) AS day FROM machine_days`),
721 ]);
722
723 const retained = new Map(
724 rowsOf<{ k: number; machines: number }>(batch[0]).map((r) => [r.k, r.machines ?? 0]),
725 );
726 const cohortDays = rowsOf<{ day: string; machines: number }>(batch[1]);
727 const cohortSize = cohortDays.reduce((n, r) => n + (r.machines ?? 0), 0);
728 const latestDay = firstOf<{ day: string | null }>(batch[2])?.day ?? utcDay(Date.now());
729
730 const rows = [];
731 for (let k = 0; k <= RETENTION_DAYS; k++) {
732 // Machines whose first day is early enough that day k has already happened.
733 const cutoff = addDays(latestDay, -k);
734 const eligible = cohortDays.reduce((n, r) => (r.day <= cutoff ? n + (r.machines ?? 0) : n), 0);
735 const back = retained.get(k) ?? 0;
736 rows.push({
737 day: k,
738 eligible,
739 retained: back,
740 rate: eligible > 0 ? back / eligible : null,
741 });
742 }
743
744 return {
745 body: {
746 range,
747 cohort: cohortSize,
748 window_days: RETENTION_DAYS,
749 labels: rows.map((r) => `Day ${r.day}`),
750 datasets: [
751 {
752 label: 'Retained',
753 data: rows.map((r) => (r.rate === null ? null : Math.round(r.rate * 1000) / 10)),
754 },
755 ],
756 rows,
757 },
758 cacheControl: CACHE_CONTROL,
759 };
760}
761

Callers 1

handleApiFunction · 0.70

Calls 6

rowsOfFunction · 0.85
firstOfFunction · 0.85
utcDayFunction · 0.70
addDaysFunction · 0.70
prepareMethod · 0.65
getMethod · 0.65

Tested by

no test coverage detected