From bf7a5792b2eadfc3fc45c37541c39b2a12cc05b9 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Mon, 29 Jun 2026 17:36:39 +0530 Subject: [PATCH] feat: add hours saved metric --- .../captain/assistants/overview/Index.vue | 10 +++--- stats.md | 34 +++++++++++++++++++ 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/app/javascript/dashboard/routes/dashboard/captain/assistants/overview/Index.vue b/app/javascript/dashboard/routes/dashboard/captain/assistants/overview/Index.vue index 1722a47f3..94715c441 100644 --- a/app/javascript/dashboard/routes/dashboard/captain/assistants/overview/Index.vue +++ b/app/javascript/dashboard/routes/dashboard/captain/assistants/overview/Index.vue @@ -44,11 +44,11 @@ const metrics = computed(() => [ trendGood: true, }, { - key: 'flagged', - label: t('CAPTAIN.OVERVIEW.METRICS.FLAGGED.LABEL'), - hint: t('CAPTAIN.OVERVIEW.METRICS.FLAGGED.HINT'), - value: '1.9%', - trend: '-0.4%', + key: 'hoursSaved', + label: t('CAPTAIN.OVERVIEW.METRICS.HOURS_SAVED.LABEL'), + hint: t('CAPTAIN.OVERVIEW.METRICS.HOURS_SAVED.HINT'), + value: '612h', + trend: '+22.1%', trendGood: true, }, { diff --git a/stats.md b/stats.md index f485edbb8..b5344582b 100644 --- a/stats.md +++ b/stats.md @@ -181,6 +181,40 @@ WHERE account_id = :account_id AND created_at BETWEEN :start AND :end; ``` +## Hours Saved + +Definition: A headline "what did Captain save us" number for execs: the volume of replies Captain +sent multiplied by the team's average response time. Reads as agent time deflected. + +Caveat (important): the multiplier here is the team's average *response time* (`first_response` / +`reply_time`), which is how long a customer *waited*, not how long an agent actually *worked* on a +reply. Wait time is typically much larger than handling time, so this number overstates true labor +saved by a wide margin and should be presented as a directional/estimate figure, not measured +labor. Counting every Captain message (including ones in conversations later handed off to a human) +also inflates it. See the conversation that produced this file for the more conservative +"deflected conversations × handling time" alternative if a defensible number is needed. + +```sql +SELECT + ( + SELECT COUNT(*) + FROM messages m + WHERE m.account_id = :account_id + AND m.sender_type = 'Captain::Assistant' + AND m.sender_id = :assistant_id + AND m.message_type = 1 + AND m.private = false + AND m.created_at BETWEEN :start AND :end + ) + * ( + SELECT AVG(re.value) + FROM reporting_events re + WHERE re.account_id = :account_id + AND re.name = 'reply_time' + AND re.created_at BETWEEN :start AND :end + ) / 3600.0 AS hours_saved; +``` + ## Knowledge Base Coverage Definition: How much knowledge backs this assistant — approved vs. still-pending FAQ responses,