| contacts 生命周期 | | | | | | |
| 1 | total | integer | overview | contacts.lifecycle_stage | COUNT(*),全量(无时间窗) | Performance · 概览 |
| 2 | leads | integer | overview | contacts.lifecycle_stage | COUNT(*) FILTER (WHERE lifecycle_stage = 'lead') | Performance · 概览 |
| 3 | members | integer | overview | contacts.lifecycle_stage | COUNT(*) FILTER (WHERE lifecycle_stage = 'member') | Performance · 概览 |
| 4 | churned | integer | overview | contacts.lifecycle_stage | COUNT(*) FILTER (WHERE lifecycle_stage = 'churned') | Performance · 概览 |
| calls 量(近 30 天) | | | | | | |
| 5 | total | integer | overview | calls.start_time | COUNT(*) (近 30 天) | Performance · Call Volume |
| 6 | inbound | integer | overview | calls.direction | COUNT(*) FILTER (WHERE direction = 'Inbound') | Performance · Call Volume |
| 7 | outbound | integer | overview | calls.direction | COUNT(*) FILTER (WHERE direction = 'Outbound') | Performance · Call Volume |
| 8 | missed | integer | overview | calls.result | COUNT(*) FILTER (WHERE result IN ('Missed','No Answer','Voicemail')) | Performance · Call Volume |
| 9 | avgDuration | integer(秒) | overview | calls.duration | ROUND(AVG(duration)) | Performance · Call Volume |
| 10 | todayTotal | integer | overview | calls.start_time | COUNT(*) FILTER (WHERE start_time::date = CURRENT_DATE) | Performance · 概览 |
| 11 | yesterdayTotal | integer | overview | calls.start_time | COUNT(*) FILTER (WHERE start_time::date = CURRENT_DATE - 1) | Performance · 概览 |
| messages(近 30 天) | | | | | | |
| 12 | total | integer | overview | messages.type | COUNT(*) FILTER (WHERE type = 'SMS') | Performance · 概览 |
| 13 | unread | integer | overview | messages.read_status | COUNT(*) FILTER (WHERE read_status = 'Unread') | Performance · 概览 |
| 14 | todayTotal | integer | overview | messages.creation_time | COUNT(*) FILTER (WHERE creation_time::date = CURRENT_DATE) | Performance · 概览 |
| leadFunnel(本周 vs 上周) | | | | | | |
| 15 | received | integer | overview | contacts.lifecycle_stage + contacts.created_at | lead 且近 14 天创建,按本周 / 上周 7 天分桶 | Performance · Lead Funnel |
| 16 | contacted | integer | overview | contacts + calls JOIN | 存在 contact.created_at 之后的 outbound calls 即算 contacted | Performance · Lead Funnel |
| 17 | booked | integer | overview | contacts.lead_status | COUNT(*) FILTER (WHERE lead_status = 'booked') | Performance · Lead Funnel |
| 18 | speedToLead.medianMinutes | numeric | overview | contacts.created_at + first outbound calls.start_time | PERCENTILE_CONT(0.5) 分钟差(近 30 天样本) | Performance · Lead Funnel |
| 19 | speedToLead.sampleSize | integer | overview | 同上 | 中位数样本数 | Performance · Lead Funnel |
| pipeline 漏斗分布 | | | | | | |
| 20 | pipeline[] | jsonb [{status, count}] | overview | contacts.lead_status | GROUP BY lead_status WHERE lifecycle_stage='lead' AND lead_status IS NOT NULL | Performance · Pipeline |
| dailyActivity(近 7 天趋势) | | | | | | |
| 21 | dailyActivity[] | jsonb [{day, calls, messages, newLeads}] | overview | calls.start_time + messages.creation_time + contacts.created_at | 按天分组 COUNT | Performance · Trend |
| summary KPI(当期 vs 上期) | | | | | | |
| 22 | totalCalls | integer | summary | calls.start_time | COUNT(*)(当期) | Performance · KPI |
| 23 | outbound | integer | summary | calls.direction | COUNT(*) FILTER (WHERE direction = 'Outbound') | Performance · KPI |
| 24 | introsBooked | integer | summary | calls.primary_outcome_result + calls.primary_category | COUNT(*) FILTER (WHERE primary_outcome_result='success' AND primary_category='revenue_impacting') ⚠️ 名字叫 introsBooked,实际口径是"成交结果为 success 的 revenue_impacting 通话",不按 primary_subcategory='intro_booking' 筛 — 与 multi-store 的 introBooking 口径不同 | Performance · KPI |
| 25 | cancelSaves | integer | summary | calls.primary_outcome_result | COUNT(*) FILTER (WHERE primary_outcome_result = 'retained') | Performance · KPI |
| 26 | tasksClosed | integer | summary | tasks.status + tasks.closed_at | COUNT(*) FILTER (WHERE status='closed' AND closed_at >= 当期起点) | Performance · KPI |
| 27 | delta | jsonb {metric: pct} | summary | 上述 26 指标 | (当期 - 上期) / 上期 × 100;上期 0 且当期 > 0 → 100;都为 0 → null | Performance · KPI |
| multi-store(跨门店) | | | | | | |
| 28 | totalCalls | integer | multi-store | calls.call_state | COUNT(*) FILTER (WHERE call_state IS DISTINCT FROM 'voicemail') ⚠️ 排除 voicemail | My Stores |
| 29 | outboundCalls | integer | multi-store | calls.direction | COUNT(*) FILTER (WHERE direction='Outbound') | My Stores |
| 30 | introBooking | integer | multi-store | calls.primary_subcategory | COUNT(*) FILTER (WHERE primary_subcategory = 'intro_booking')(不限 outcome,与 summary 口径不同) | My Stores |
| 31 | membershipsSold | integer | multi-store | calls.primary_category + primary_subcategory + primary_outcome_result | FILTER (WHERE primary_category='revenue_impacting' AND primary_subcategory IN ('membership_purchase_related','reactivation_purchase') AND primary_outcome_result='success') | My Stores |
| 32 | cancellationCalls | integer | multi-store | calls.primary_subcategory | FILTER (WHERE primary_subcategory = 'membership_cancel') | My Stores |
| 33 | cancelSaved | integer | multi-store | calls.primary_subcategory + primary_outcome_result | FILTER (WHERE primary_subcategory='membership_cancel' AND primary_outcome_result='retained') | My Stores |
| 34 | tasksCreated | integer | multi-store | tasks.created_at | 当期 created_at 落在区间内 COUNT(*) | My Stores |
| 35 | tasksClosed | integer | multi-store | tasks.closed_at | 当期 closed_at 落在区间内 COUNT(*) | My Stores |
| 36 | tasksOverdue | integer | multi-store | tasks.status + tasks.due_at | FILTER (WHERE status='open' AND due_at < NOW()) 实时算,不限当期区间 | My Stores |
| 37 | trend | text | multi-store | calls(当期 vs 上期 totalCalls) | up / down / flat | My Stores |
| 38 | delta | numeric | multi-store | 同上 | (当期 - 上期) / 上期 × 100 | My Stores |
| 39 | totals | jsonb | multi-store | 上述 9 个 store-level 指标 | 求和 + storeCount | My Stores · 汇总 |
| staff endpoint | | | | | | |
| 40 | calls | integer | staff | calls.staff_name | COUNT(*) per staff ⚠️ SQL 过滤 call_state IN ('human_conversation','voicemail') AND staff_name IS NOT NULL | Team Tab |
| 41 | inbound / outbound | integer | staff | calls.direction | FILTER (WHERE direction=...) per staff | Team Tab |
| 42 | introCalls | integer | staff | calls.primary_subcategory | FILTER (WHERE primary_subcategory='intro_booking') per staff | Team Tab |
| 43 | membershipSales | integer | staff | calls.primary_category + primary_subcategory + primary_outcome_result | 同 metric #31 但 per staff | Team Tab |
| 44 | cancellationSaves | integer | staff | calls.primary_subcategory + primary_outcome_result | 同 metric #33 但 per staff | Team Tab |
| 45 | taskCompletionRate | numeric | staff | tasks.closed_by_staff_name + tasks.status | closed / total per staff;当前 SQL 只看 closed_by_staff_name IS NOT NULL 的 task,见 §3 | Team Tab |
| 46 | coachingFlagRate | numeric | staff | calls.practical_coaching_* + calls.duration | coaching_worthy / eligible_calls(eligible = duration > 60s + 有 coaching 内容) | Team Tab |
| 47 | wowDirection | text | staff | calls(当期 vs 上期) | up / down / flat | Team Tab |
| leadFunnel 牵引 | | | | | | |
| 48 | Lead Follow-up 数 | integer | overview | overview.leadFunnel | 同 metric #15-19 | Performance · 快捷牵引 |
| 49 | Task Queue 数(open tasks) | integer | tasks list endpoint(非 dashboard-*) | tasks.status | WHERE status='open' 计数 — /v3/dashboard/overview 不返回 task 计数,前端从 tasks list endpoint 拉 | Performance · 快捷牵引 |
| 50 | Manager Review 数 | integer | coaching-highlights | calls.practical_coaching_scenario + practical_coaching_feedback | 待 review 通话计数(实际 SQL 用 practical_coaching_scenario IS NOT NULL AND NOT ILIKE 'No coaching%',见 dashboard-coaching-highlights.ts:54-87)。Planned: 切到 calls.review_category 一旦该字段接线(coaching-schema 标"未接线") | Performance · 快捷牵引 |