Sales Analytics

An Analytics tab inside the sales pipeline that turns every lead's real timestamps into conversion, speed, stage-time and throughput numbers without anyone entering data.

What it is

A full analytics panel mounted as a tab on the Sales Pipeline (Pipeline / Analytics / Leaderboard). It reads the durable lifecycle event log — one row per lead created, stage move, won/lost, project complete — and derives every number by subtracting stored timestamps. KPI cards, a pipeline-by-stage bar, stage dwell times, an SOP scorecard, a daily throughput area chart, an activity heatmap, an owner leaderboard and a group-compare panel all run off one request, so a filter applied at the top changes every chart below it.

Also called: sales reports · lead analytics · pipeline analytics · conversion reporting · where are my deals getting stuck

See it
Sales Analytics
New lead 4
Marlin Hoover
$22k
Delia Yoder
$48k
Contacted 3
Sutter Kline
$48k
Ronan Petsch
$66k
Estimate 2
Ivy Brubaker
$69k
Gideon Alt
$51k
Sold 3
Marlin Hoover
$54k
Delia Yoder
$71k
The full Analytics tab scrolling: KPI row, Pipeline by Stage next to Stage Dwell Time, then SOP performance, throughput and the heatmap. Rendered by src/components/analytics/AnalyticsView.tsx. Sample data — no customer information appears here.
How it works
  1. 1Every stage move, lead creation, won/lost flip and project completion writes an append-only row to stage_transition_log with the real event time, the owner snapshot, the stage label and the seconds spent in the stage just left.
  2. 2The Analytics tab POSTs a date range, pipeline ('sales' or 'project') and an optional set of rep ids to /api/analytics.
  3. 3The route pages the log (1000 rows a page, up to 50 pages), groups rows by opportunity into per-lead timelines, and computes averages, medians and 90th percentiles in TypeScript — there is no database report to maintain.
  4. 4The response is one fixed payload (overview, funnel, stageDurations, leaderboard, timeOfDay, throughput, sop) that the panel renders section by section.
  5. 5Range presets (7/30/90 days, all time, custom) and the rep/role filter re-issue the same request, so nothing on the page can be looking at a different window than anything else.
Why we built it

Because durations kept being stored as numbers and then going stale or wrong. Migration 096's header sets the rule: 'store only TIMESTAMPS (one row per key event…). Every duration/metric is DERIVED later by subtraction.' It also explains why the log denormalises the owner, stage label and contact onto each row — 'so a row stays meaningful even if the opportunity is later edited, re-linked, or deleted.' The route header adds the second rule: 'ALL math is done in TypeScript by subtraction over the stored timestamps — there is no in-DB RPC', and 'Never throws to the client — any error returns a graceful 500', because a broken report should not take the pipeline down with it.

The problem
  • Owner cannot answer 'how many leads became jobs last quarter' without manual counting.
  • Stage durations were never stored, so 'how long does an estimate sit' had no answer.
  • Reports drifted from reality when a deal was reassigned or a contact renamed.
Sound familiar?
What you get
Every number is derived from work already done — nobody fills in a report.
One date range and one rep filter drive every chart, so the page can't contradict itself.
History survives reassignment, renames and deletions because each event row carries its own snapshot.
What's inside
Lifecycle event log
An append-only record of every lead created, stage move, won/lost and project completion, stamped with who owned it, who moved it and how long it sat.
Headline sales numbers
Seven cards across the top of Analytics: time to first contact, time to won, time to completion, win rate, leads per week, total leads and active leads.
Pipeline by stage
A bar per pipeline stage showing how many leads are sitting there right now and what share of the pipeline that is — counted the same way the board counts them.
Stage dwell time
Average, median and 90th-percentile time a lead spent in each stage before moving on, with the sample size behind every bar.
Daily throughput
A four-series area chart of leads created, stage moves performed, deals won and projects completed, per day.
Activity by hour and day
A 7×24 grid where each square is one hour of one weekday, shaded by how much lead activity happened in it.
Owner performance table
A sortable table of deals owned, won, win rate, average time to won, average dwell and moves performed, per person.
Group compare
Pick two or three cohorts — role groups or individuals — and see win rate, time to won, average dwell and lead volume side by side.
Global rep and role filter
One picker at the top of Analytics — All reps, Sales reps, Managers, or a named person — that re-scopes every chart on the page.
Date range presets and custom range
Last 7 / 30 / 90 days, all time, or a custom from-to range, applied to every chart at once.
Rep-level analytics privacy
The analytics endpoint enforces its own visibility: admins and owners see the org, sales managers see their configured team, a plain rep sees only their own leads, and crew roles are refused.
Stage SOP performance
For every sales stage, how often each checklist step was actually ticked before the deal moved on — with the notes reps wrote under those steps.
Analytics where the work is
Analytics and Leaderboard are tabs on the sales pipeline rather than separate nav items, permission-gated and mounted only while open.

See it on your own jobs

Twenty minutes, your numbers, no slide deck. We’ll build one of your real buildings in front of you and send you the estimate link at the end — yours to keep either way.

or keep browsing features →