From 76dc037c1a3f7c8d9801b839e00a42b5f5771e76 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Tue, 30 Jun 2026 19:04:07 +0530 Subject: [PATCH] chore: remove queries scratch file --- queries.md | 214 ----------------------------------------------------- 1 file changed, 214 deletions(-) delete mode 100644 queries.md diff --git a/queries.md b/queries.md deleted file mode 100644 index 50a71f543..000000000 --- a/queries.md +++ /dev/null @@ -1,214 +0,0 @@ -# Captain Overview — effective SQL per stat - -These are the queries `Captain::AssistantStatsBuilder` effectively runs for -`account_id = 1`, `assistant_id = 1`, over a **30-day current window** -(`created_at >= NOW() - INTERVAL '30 days'`). Each metric runs once for the -current window and once for the previous equal-length window -(`NOW() - INTERVAL '60 days'` to `NOW() - INTERVAL '30 days'`); only the current -window is shown below. Swap the interval bounds for the previous window. - -Knowledge stats are point-in-time (no window, no previous). - ---- - -## 1. Conversations handled - -Distinct conversations the assistant authored any message in. - -```sql -SELECT COUNT(DISTINCT conversation_id) -FROM messages -WHERE account_id = 1 - AND sender_type = 'Captain::Assistant' - AND sender_id = 1 - AND created_at >= NOW() - INTERVAL '30 days'; -``` - -Indexes that matter: `messages (account_id, ...)`, plus the `sender_type/sender_id` -filter. This is the "handled set" reused as a subquery by stats 2 and 3. - ---- - -## 2 & 3. Auto-resolution rate + handoff rate (combined) - -`auto_resolution = resolved / handled * 100` and `handoff = handoff / handled * 100` -share the same handled-set subquery, so they fold into a single pass with -conditional aggregation. This runs the (costly) `messages` handled-set subquery -**once** and scans `reporting_events` once, instead of twice each. - -```sql -SELECT - COUNT(DISTINCT conversation_id) - FILTER (WHERE name IN ('conversation_captain_inference_resolved', - 'conversation_bot_resolved')) AS resolved, - COUNT(DISTINCT conversation_id) - FILTER (WHERE name IN ('conversation_captain_inference_handoff', - 'conversation_bot_handoff')) AS handoff -FROM reporting_events -WHERE account_id = 1 - AND name IN ('conversation_captain_inference_resolved', 'conversation_bot_resolved', - 'conversation_captain_inference_handoff', 'conversation_bot_handoff') - AND conversation_id IN ( - SELECT conversation_id - FROM messages - WHERE account_id = 1 - AND sender_type = 'Captain::Assistant' - AND sender_id = 1 - AND created_at >= NOW() - INTERVAL '30 days' - ); -``` - -The rates are still computed in Ruby (`resolved / handled`, `handoff / handled`), -so divide-by-zero guarding stays in the builder. The two rates do **not** sum to -100%: a handled conversation may carry neither event (still open) or both -(handed off then later resolved). - -Note: the event rows themselves are **not** date-filtered; the window is applied -via the handled-set subquery (the conversations the assistant touched in the -window). - -### Optional: fold in "handled" too (one query for all three) - -Materialize the handled set once in a CTE and derive all three numbers from it. -Useful because the page also displays `handled`, and every metric runs for both -the current and previous window. - -```sql -WITH handled AS ( - SELECT DISTINCT conversation_id - FROM messages - WHERE account_id = 1 - AND sender_type = 'Captain::Assistant' - AND sender_id = 1 - AND created_at >= NOW() - INTERVAL '30 days' -) -SELECT - (SELECT COUNT(*) FROM handled) AS handled, - COUNT(DISTINCT re.conversation_id) - FILTER (WHERE re.name IN ('conversation_captain_inference_resolved', - 'conversation_bot_resolved')) AS resolved, - COUNT(DISTINCT re.conversation_id) - FILTER (WHERE re.name IN ('conversation_captain_inference_handoff', - 'conversation_bot_handoff')) AS handoff -FROM reporting_events re -JOIN handled h ON h.conversation_id = re.conversation_id -WHERE re.account_id = 1 - AND re.name IN ('conversation_captain_inference_resolved', 'conversation_bot_resolved', - 'conversation_captain_inference_handoff', 'conversation_bot_handoff'); -``` - -Keep `handled` sourced from the CTE count (not `COUNT(*)` over the join), so -conversations with no event row still count toward `handled`. - ---- - -## 4. Hours saved - -`public_outgoing_count * avg_reply_time_seconds / 3600`, rounded. Two queries. - -Public outgoing replies the assistant sent: - -```sql -SELECT COUNT(*) -FROM messages -WHERE account_id = 1 - AND sender_type = 'Captain::Assistant' - AND sender_id = 1 - AND message_type = 1 -- outgoing - AND private = false - AND created_at >= NOW() - INTERVAL '30 days'; -``` - -Average reply time across the account in the window (seconds): - -```sql -SELECT AVG(value) -FROM reporting_events -WHERE account_id = 1 - AND name = 'reply_time' - AND created_at >= NOW() - INTERVAL '30 days'; -``` - ---- - -## 5. Conversation depth (messages / conversation) - -`public_outgoing_count / distinct_conversations`. Reuses query 4's count plus: - -```sql -SELECT COUNT(DISTINCT conversation_id) -FROM messages -WHERE account_id = 1 - AND sender_type = 'Captain::Assistant' - AND sender_id = 1 - AND message_type = 1 -- outgoing - AND private = false - AND created_at >= NOW() - INTERVAL '30 days'; -``` - ---- - -## 6. Reopen-after-resolve rate - -`reopened / resolved * 100`, where "resolved" is the inbox-based Captain-resolved -set. Two queries. - -Resolved (inbox-scoped) in the window: - -```sql -SELECT COUNT(DISTINCT conversation_id) -FROM reporting_events -WHERE account_id = 1 - AND name = 'conversation_captain_inference_resolved' - AND inbox_id IN ( - SELECT inbox_id FROM captain_inboxes WHERE captain_assistant_id = 1 - ) - AND created_at >= NOW() - INTERVAL '30 days'; -``` - -Of those, the ones later reopened (`conversation_opened` with `value > 0`): - -```sql -SELECT COUNT(DISTINCT conversation_id) -FROM reporting_events -WHERE account_id = 1 - AND name = 'conversation_opened' - AND value > 0 - AND conversation_id IN ( - SELECT conversation_id - FROM reporting_events - WHERE account_id = 1 - AND name = 'conversation_captain_inference_resolved' - AND inbox_id IN ( - SELECT inbox_id FROM captain_inboxes WHERE captain_assistant_id = 1 - ) - AND created_at >= NOW() - INTERVAL '30 days' - ); -``` - -Note: the `conversation_opened` events are **not** date-filtered; a reopen counts -whenever it happened, as long as the resolve fell in the window. - ---- - -## 7. Knowledge (point-in-time, no window) - -Approved / pending FAQ counts: - -```sql -SELECT status, COUNT(*) -FROM captain_assistant_responses -WHERE assistant_id = 1 -GROUP BY status; --- status: 0 = pending, 1 = approved -``` - -Document count: - -```sql -SELECT COUNT(*) -FROM captain_documents -WHERE assistant_id = 1; -``` - -`coverage = approved / (approved + pending) * 100`, computed in Ruby.