Dashboard
The Pact home screen — a single tenant-scoped summary of pipeline, velocity, engagement, and consent, served from one cached endpoint.
Dashboard
The dashboard is your Pact home screen. It renders KPI tiles, pipeline and
velocity charts, top accounts, playbook activity, a consent funnel, and a
recent-activity feed — everything on the page is derived from one call to
GET /v1/dashboard/summary.
Live
The dashboard is fully backed. api/routes/dashboard.py runs the aggregations,
the four scope-aware metrics delegate to the single source of truth in
core.analytics, and the whole payload is tenant-scoped via get_tenant_id.
Time range
Pass range to scope every metric to a trailing window:
GET /v1/dashboard/summary?range=30d
Accepted values are 7d, 14d, 30d, 90d, and all. all removes the
date cutoff entirely; anything else returns 400 Bad Request. The response
echoes the resolved range and a generated_at timestamp.
What's in the payload
| Section | What it drives |
|---|---|
kpis | Total accounts, open + probability-weighted pipeline value, average cycle days, win rate, sequence open rate, and consent opt-in rate |
pipeline_by_stage | The pipeline bar chart, from core.analytics.pipeline_by_stage |
velocity_trend | Deal-velocity line over the selected range |
open_rate_trend | Email open-rate trend |
top_accounts | Highest-value accounts by owner revenue |
playbook_activity | Recent playbook runs |
consent_funnel | Opt-in / opt-out breakdown for the consent donut |
recent_activity | The activity feed |
The win_rate, top_owner_revenue, sequence_open_rate, and
pipeline_by_stage metrics are computed in core.analytics per the
canonical-paths charter, so the number you see on the dashboard matches the
number on /analytics. The dashboard-only roll-ups (pipeline aggregate,
average cycle days, consent opt-in rate) are computed inline in the _kpis
helper.
Caching and freshness
The route reads from a replica connection (get_replica_db_conn) and computes
a SHA-256 ETag over the serialized body. The frontend sends
If-None-Match; when nothing has changed the endpoint returns
304 Not Modified with no body — so a background refresh is cheap. The ETag
flips whenever any underlying row changes, and it folds in the effective
"viewing as" scope so a manager and a rep never share a cached body.
Freshness over OLAP
The homepage deliberately runs many small aggregations against the operational
store rather than the analytics warehouse — for the home screen Pact optimizes
for freshness, not warehouse-scale slicing. Heavier analysis lives under
/v1/analytics/*.
Viewing as
The summary honors the "viewing as" scope (viewing_as_dep). Managers see
roll-ups across their reporting line; individual contributors see their own
book. Scope is derived server-side from the auth context and folded into the
ETag, never taken from the request body.
Performance instrumentation
The route supports an opt-in timing trace: set DASHBOARD_TIMING=1 and each
call emits one log line with the per-section millisecond breakdown, used for
tuning against the baselines in docs/qa/baselines/.