restore(ui): recover frontend deleted in 8e51290 (login/operator/supervisor/analyst/admin/sales)

This commit is contained in:
Codex
2026-08-10 12:28:12 +00:00
parent d57c50bdc4
commit 210106eaa0
19 changed files with 27867 additions and 0 deletions
+7927
View File
File diff suppressed because it is too large Load Diff
+454
View File
@@ -0,0 +1,454 @@
<!doctype html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>KonturCC Аналитика</title>
<link rel="icon" href="/operator/assets/favicon.svg" type="image/svg+xml" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@500;600;700;800&family=IBM+Plex+Sans:wght@400;500;600&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="/operator/assets/styles.css?v=track45-voice-name-flow-v1" />
</head>
<body>
<div class="app-shell">
<aside class="sidebar">
<div class="brand">
<div class="brand-mark">K</div>
<div>
<div class="brand-title">KonturCC</div>
<div class="brand-sub">Центр аналитики</div>
</div>
</div>
<nav class="nav-menu">
<div class="nav-group">
<div class="nav-label">Рабочие зоны</div>
<a class="nav-link" data-shell="operator" data-roles="admin,supervisor,operator,analyst" href="/operator"><span class="nav-bullet"></span>Оператор</a>
<a class="nav-link" data-shell="supervisor" data-roles="admin,supervisor" href="/supervisor"><span class="nav-bullet"></span>Супервизор</a>
<a class="nav-link active" data-shell="analyst" data-roles="admin,supervisor,analyst" href="/analyst"><span class="nav-bullet"></span>Аналитика</a>
<a class="nav-link" data-shell="sales" data-roles="admin,supervisor,operator,analyst" href="/sales"><span class="nav-bullet"></span>Продажи</a>
<a class="nav-link" data-shell="admin" data-roles="admin" href="/admin"><span class="nav-bullet"></span>Администрирование</a>
</div>
<div class="nav-group">
<div class="nav-label">Разделы</div>
<a class="nav-link" href="#analyticsPanel"><span class="nav-bullet"></span>Обзор</a>
<a class="nav-link" href="#voiceNameAnalyticsPanel"><span class="nav-bullet"></span>Сбор имени</a>
<a class="nav-link" href="#aiAnalyticsPanel"><span class="nav-bullet"></span>AI</a>
<a class="nav-link" href="#agentAnalyticsPanel"><span class="nav-bullet"></span>Агенты</a>
<a class="nav-link" href="#analyticsTrendBlock"><span class="nav-bullet"></span>Тренд</a>
<a class="nav-link" href="#analyticsQueuesBlock"><span class="nav-bullet"></span>Очереди</a>
</div>
</nav>
<div class="sidebar-footer">
<strong>Рабочее место аналитика</strong>
<p>Историческая картина по обращениям, каналам, очередям и качеству сценариев без перехода в операционный экран.</p>
<p class="hint" id="sessionInfo">Сессия проверяется...</p>
<button id="logoutBtn" class="btn ghost" type="button">Выйти</button>
</div>
</aside>
<section class="workspace">
<header class="workspace-topbar reveal">
<div class="analytics-topbar-intro">
<strong>Историческая аналитика сервиса</strong>
<p>Периоды, каналы, очереди, AI и агентские срезы в одном окне.</p>
</div>
<div class="topbar-actions">
<div class="status-pill" id="gatewayStatus">Данные: проверка...</div>
<button id="refreshBtn" class="btn ghost" type="button">Обновить данные</button>
<div class="profile-chip">
<div class="avatar-badge">AN</div>
<div class="profile-meta">
<div class="profile-name" id="profileName">Центр аналитики</div>
<div class="profile-role" id="profileRole">Историческая аналитика</div>
</div>
</div>
</div>
</header>
<main class="layout">
<section class="page-hero reveal">
<p class="eyebrow">История сервиса</p>
<h1>Аналитика контакт-центра</h1>
<p class="hint">Исторические KPI, тренды и структура потока по каналам и очередям в одной витрине.</p>
</section>
<section class="panel reveal analytics-dashboard-panel" id="analyticsPanel">
<div class="analytics-head">
<div>
<p class="eyebrow">Сводка периода</p>
<h2>Ключевые метрики и тренды</h2>
<p class="hint">Сравнивайте выбранный период с предыдущим окном и быстро переключайтесь между очередями и каналами.</p>
</div>
<div class="actions compact-actions">
<button id="analyticsRefreshBtn" class="btn" type="button">Обновить данные</button>
<button id="analyticsResetBtn" class="btn ghost" type="button">Сбросить</button>
</div>
</div>
<div class="analytics-filter-bar">
<div class="row">
<label for="analyticsPreset">Период</label>
<select id="analyticsPreset">
<option value="today">Сегодня</option>
<option value="7d" selected>7 дней</option>
<option value="30d">30 дней</option>
</select>
</div>
<div class="row">
<label for="analyticsFrom">С</label>
<input id="analyticsFrom" type="datetime-local" />
</div>
<div class="row">
<label for="analyticsTo">По</label>
<input id="analyticsTo" type="datetime-local" />
</div>
<div class="row">
<label for="analyticsQueue">Очередь</label>
<select id="analyticsQueue">
<option value="all">Все очереди</option>
</select>
</div>
<div class="row">
<label for="analyticsChannel">Канал</label>
<select id="analyticsChannel">
<option value="all">Все каналы</option>
<option value="voice">Голос</option>
<option value="telegram">Telegram</option>
<option value="whatsapp">WhatsApp</option>
<option value="webchat">Веб-чат</option>
<option value="email">Email</option>
</select>
</div>
</div>
<div class="analytics-toolkit">
<div class="analytics-toolkit-group">
<div class="row">
<label for="analyticsCompareMode">Сравнение</label>
<select id="analyticsCompareMode">
<option value="previous" selected>С предыдущим окном</option>
<option value="off">Только текущий срез</option>
</select>
</div>
<p id="analyticsSavedViewMeta" class="hint analytics-inline-meta">Сохранённых видов пока нет.</p>
</div>
<div class="analytics-toolkit-group analytics-toolkit-group-wide">
<div class="row">
<label for="analyticsSavedViewSelect">Сохранённый вид</label>
<select id="analyticsSavedViewSelect">
<option value="">Без сохранённого вида</option>
</select>
</div>
<div class="row">
<label for="analyticsSavedViewName">Название вида</label>
<input id="analyticsSavedViewName" type="text" placeholder="Например, Telegram за 30 дней" />
</div>
<div class="actions analytics-toolkit-actions">
<button id="analyticsSaveViewBtn" class="btn ghost" type="button">Сохранить вид</button>
<button id="analyticsDeleteViewBtn" class="btn ghost" type="button">Удалить</button>
<button id="analyticsExportBtn" class="btn" type="button">Экспорт CSV</button>
</div>
</div>
</div>
<p class="hint analytics-filter-note" id="analyticsRangeHint">Выберите период и при необходимости уточните канал или очередь.</p>
<div id="analyticsEmptyState" class="analytics-empty-state" hidden></div>
<div id="analyticsNarrative" class="analytics-narrative"></div>
<div id="analyticsComparePanel" class="analytics-compare-panel" hidden></div>
<div id="analyticsOverview" class="summary-grid analytics-overview-grid"></div>
<section class="analytics-voice-panel" id="voiceNameAnalyticsPanel">
<div class="analytics-subhead">
<div>
<p class="eyebrow">Сценарий имени</p>
<h3>Сценарий сбора имени в голосе</h3>
<p class="hint">Отдельная аналитика по тому, как сценарий берёт имя на старте, как помогает downstream AI и сколько звонков уходит оператору без подтверждённого имени.</p>
</div>
<div class="row analytics-trend-selector">
<label for="voiceNameAnalyticsTrendMetric">Метрика</label>
<select id="voiceNameAnalyticsTrendMetric">
<option value="scenario_calls">Звонки в сценарии</option>
<option value="start_capture_rate">Имя взято сразу</option>
<option value="downstream_rescue_rate">Имя добрал downstream AI</option>
<option value="handoff_unconfirmed_rate">Handoff без имени</option>
<option value="manual_correction_rate">Ручное исправление</option>
</select>
</div>
</div>
<div id="voiceNameAnalyticsEmptyState" class="analytics-empty-state" hidden></div>
<div id="voiceNameAnalyticsOverview" class="summary-grid analytics-overview-grid voice-name-analytics-overview"></div>
<div class="analytics-sections">
<article class="analytics-subpanel analytics-subpanel-wide">
<h3>Тренд по voice name-flow</h3>
<p class="hint">Динамика показывает, как меняется качество сбора имени по выбранному периоду, очереди и голосовому потоку.</p>
<div id="voiceNameAnalyticsTrendChart" class="analytics-chart-shell"></div>
</article>
<article class="analytics-subpanel">
<h3>Этапы сценария</h3>
<p class="hint">Funnel помогает быстро увидеть, где чаще всего теряется имя: на старте, в follow-up или уже перед handoff.</p>
<div id="voiceNameAnalyticsFunnel" class="analytics-table-shell"></div>
</article>
</div>
<div class="analytics-sections">
<article class="analytics-subpanel">
<h3>По языкам</h3>
<p class="hint">Сравнение сценария по языкам помогает увидеть, где стартовый сбор имени работает стабильнее, а где чаще требуется downstream AI.</p>
<div id="voiceNameAnalyticsLanguageTable" class="analytics-table-shell"></div>
</article>
<article class="analytics-subpanel">
<h3>По очередям</h3>
<p class="hint">Срез по очередям показывает, в каких очередях voice name-flow чаще доходит до handoff без подтверждённого имени.</p>
<div id="voiceNameAnalyticsQueueTable" class="analytics-table-shell"></div>
</article>
</div>
<article class="analytics-subpanel">
<h3>Handoff по имени</h3>
<p class="hint">Здесь видно, сколько звонков оператор получил уже с подтверждённым именем, а сколько ушло без него.</p>
<div id="voiceNameAnalyticsHandoffTable" class="analytics-table-shell"></div>
</article>
</section>
<section class="analytics-ai-panel" id="aiAnalyticsPanel">
<div class="analytics-subhead">
<div>
<p class="eyebrow">AI-аналитика</p>
<h3>AI-сессии в цифровых каналах</h3>
<p class="hint">Отдельный блок по Telegram и WhatsApp: закрытие AI, передача оператору, задержка ответа и закрытия без оператора без доступа к текстам сообщений.</p>
</div>
<div class="row analytics-trend-selector">
<label for="aiAnalyticsTrendMetric">AI-метрика</label>
<select id="aiAnalyticsTrendMetric">
<option value="containment_rate">Закрыто AI</option>
<option value="handoff_rate">Передано оператору</option>
<option value="ai_latency_avg_ms">Задержка AI</option>
<option value="closed_without_operator_rate">Закрыто без оператора</option>
<option value="human_touched_rate">С участием оператора</option>
</select>
</div>
</div>
<div id="aiAnalyticsEmptyState" class="analytics-empty-state" hidden></div>
<div id="aiAnalyticsOverview" class="summary-grid analytics-overview-grid ai-analytics-overview"></div>
<div class="analytics-sections">
<article class="analytics-subpanel analytics-subpanel-wide">
<h3>AI-тренд по периоду</h3>
<p class="hint">Динамика AI по выбранной метрике строится по тем же фильтрам периода, канала и очереди, что и основная витрина.</p>
<div id="aiAnalyticsTrendChart" class="analytics-chart-shell"></div>
</article>
<article class="analytics-subpanel">
<h3>Покрытие AI-данных</h3>
<p class="hint">Проверяем, насколько AI-сессии связаны с обращениями, очередями и данными по задержке ответа для корректной интерпретации отчёта.</p>
<div id="aiAnalyticsCoverage" class="analytics-coverage"></div>
</article>
</div>
<article class="analytics-subpanel">
<h3>AI и оператор по каналам</h3>
<p class="hint">Сравнение полностью автоматических и затронутых оператором сессий по Telegram и WhatsApp без текстов сообщений, записей и AI-сводок.</p>
<div id="aiAnalyticsChannelComparison" class="analytics-table-shell"></div>
</article>
<div class="analytics-sections">
<article class="analytics-subpanel">
<h3>Исходы AI-сессий</h3>
<p class="hint">Клик по исходу открывает полноэкранную детализацию по AI-сессиям только на уровне метаданных.</p>
<div id="aiAnalyticsOutcomeTable" class="analytics-table-shell"></div>
</article>
<article class="analytics-subpanel">
<h3>Причины передачи оператору</h3>
<p class="hint">Нажмите на причину, чтобы открыть срез по передачам оператору с той же группой причин.</p>
<div id="aiAnalyticsReasonTable" class="analytics-table-shell"></div>
</article>
</div>
</section>
<section class="analytics-agent-panel" id="agentAnalyticsPanel">
<div class="analytics-subhead">
<div>
<p class="eyebrow">Агенты</p>
<h3>Агентская аналитика</h3>
<p class="hint">Нагрузка, обработка и текущие состояния агентов по фактам reporting и данным supervisor без локальных заглушек.</p>
</div>
</div>
<div id="agentAnalyticsEmptyState" class="analytics-empty-state" hidden></div>
<div id="agentAnalyticsOverview" class="summary-grid analytics-overview-grid agent-analytics-overview"></div>
<div id="agentAnalyticsStateStrip" class="agent-analytics-state-strip"></div>
<div class="analytics-sections">
<article class="analytics-subpanel analytics-subpanel-wide">
<div class="analytics-subhead">
<div>
<h3>Тренд по агентам</h3>
<p class="hint">Динамика по агентам помогает оценить нагрузку, стабильность обработки и изменение FCR по выбранному окну.</p>
</div>
<div class="row analytics-trend-selector">
<label for="agentAnalyticsTrendMetric">Метрика</label>
<select id="agentAnalyticsTrendMetric">
<option value="interactions_per_agent">Нагрузка на агента</option>
<option value="agents_with_activity">Агенты с активностью</option>
<option value="avg_handle_seconds">AHT</option>
<option value="fcr_rate">FCR</option>
</select>
</div>
</div>
<div id="agentAnalyticsTrendChart" class="analytics-chart-shell"></div>
</article>
<article class="analytics-subpanel">
<h3>Команды и очереди</h3>
<p class="hint">Сводка по командам и очередям, где сейчас сосредоточена агентская нагрузка.</p>
<div id="agentAnalyticsTeamTable" class="analytics-table-shell"></div>
</article>
</div>
<article class="analytics-subpanel">
<h3>Агенты по выбранному периоду</h3>
<p class="hint">Клик по строке открывает полноэкранную детализацию по обращениям выбранного агента без изменения фильтров витрины.</p>
<div id="agentAnalyticsTable" class="analytics-table-shell"></div>
</article>
<div class="analytics-sections">
<article class="analytics-subpanel">
<h3>Смены</h3>
<p class="hint">Сравнение ночной, дневной и вечерней смен по обращениям, обработке и FCR.</p>
<div id="agentAnalyticsShiftTable" class="analytics-table-shell"></div>
</article>
</div>
</section>
<div class="analytics-sections">
<article class="analytics-subpanel analytics-subpanel-wide" id="analyticsTrendBlock">
<div class="analytics-subhead">
<div>
<h3>Тренд по периоду</h3>
<p class="hint">Динамика по выбранной метрике помогает быстро увидеть изменение нагрузки и качества.</p>
</div>
<div class="row analytics-trend-selector">
<label for="analyticsTrendMetric">Метрика</label>
<select id="analyticsTrendMetric">
<option value="volume">Обращения</option>
<option value="SL">SL</option>
<option value="ASA">Ожидание</option>
<option value="Abandon">Потери</option>
</select>
</div>
</div>
<div id="analyticsTrendChart" class="analytics-chart-shell"></div>
</article>
<article class="analytics-subpanel">
<h3>Каналы</h3>
<p class="hint">Сравнение каналов по объёму, обработке и доле ответа за выбранный период.</p>
<p class="hint analytics-drilldown-note">Нажмите на строку, чтобы открыть точную детализацию по обращениям этого канала.</p>
<div id="analyticsChannelTable" class="analytics-table-shell"></div>
</article>
</div>
<div class="analytics-sections">
<article class="analytics-subpanel analytics-subpanel-wide" id="analyticsQueuesBlock">
<h3>Очереди</h3>
<p class="hint">Очереди отсортированы по объёму. Нажмите на строку, чтобы сфокусировать всю витрину на одной очереди.</p>
<p class="hint analytics-drilldown-note">Клик по строке открывает точный срез по очереди и не меняет фильтры витрины.</p>
<div id="analyticsQueueTable" class="analytics-table-shell"></div>
</article>
</div>
</section>
</main>
</section>
</div>
<div id="analyticsDrilldownBackdrop" class="analytics-drawer-backdrop" hidden></div>
<aside
id="analyticsDrilldownDrawer"
class="analytics-drawer"
hidden
role="dialog"
aria-modal="true"
aria-labelledby="analyticsDrilldownTitle"
aria-describedby="analyticsDrilldownMeta"
tabindex="-1"
>
<div class="analytics-drawer-head">
<div>
<p class="eyebrow">Детализация обращений</p>
<h2 id="analyticsDrilldownTitle">Детализация обращений</h2>
<p id="analyticsDrilldownMeta" class="hint">Выберите карточку обращений, канал или очередь на витрине, чтобы открыть список обращений.</p>
</div>
<button id="analyticsDrilldownCloseBtn" class="btn ghost" type="button">Закрыть</button>
</div>
<div id="analyticsDrilldownFilters" class="analytics-filter-chips analytics-drawer-filters"></div>
<div class="analytics-drawer-toolbar">
<div class="row analytics-drawer-toolbar-search">
<label for="analyticsDrilldownSearch">Поиск</label>
<input id="analyticsDrilldownSearch" type="search" placeholder="ID, тема или назначенный" autocomplete="off" />
</div>
<div class="row">
<label for="analyticsDrilldownStatus">Статус</label>
<select id="analyticsDrilldownStatus">
<option value="all" selected>Все статусы</option>
<option value="new">Новая</option>
<option value="in_progress">В работе</option>
<option value="escalated">Эскалация</option>
<option value="closed">Закрыта</option>
<option value="abandoned">Потеряна</option>
</select>
</div>
<div class="row">
<label for="analyticsDrilldownSort">Сортировка</label>
<select id="analyticsDrilldownSort">
<option value="created_at:desc" selected>Создано: новые сверху</option>
<option value="created_at:asc">Создано: старые сверху</option>
<option value="updated_at:desc">Обновлено: новые сверху</option>
<option value="updated_at:asc">Обновлено: старые сверху</option>
<option value="subject:asc">Тема: А</option>
<option value="subject:desc">Тема: Я-А</option>
</select>
</div>
<div class="actions compact-actions analytics-drawer-toolbar-actions">
<button id="analyticsDrilldownClearBtn" class="btn ghost" type="button">Сбросить</button>
<button id="analyticsDrilldownExportBtn" class="btn" type="button">Экспорт CSV</button>
</div>
</div>
<div class="analytics-drawer-body">
<section class="analytics-drawer-list-shell">
<div class="analytics-drawer-list-head">
<strong>Список обращений</strong>
<span id="analyticsDrilldownPageMeta" class="hint">0 из 0</span>
</div>
<div id="analyticsDrilldownList" class="analytics-drawer-list"></div>
<div class="analytics-drawer-pager">
<button id="analyticsDrilldownPrevBtn" class="btn ghost" type="button">Назад</button>
<button id="analyticsDrilldownNextBtn" class="btn ghost" type="button">Дальше</button>
</div>
</section>
<section class="analytics-drawer-detail-shell">
<div class="analytics-drawer-list-head">
<strong>Карточка обращения</strong>
<span class="hint">Лента событий и базовые поля без записей, транскриптов и канального контента.</span>
</div>
<div id="analyticsDrilldownDetail" class="analytics-drawer-detail"></div>
</section>
</div>
</aside>
<input id="sessionUser" type="hidden" value="analyst" />
<input id="sessionRole" type="hidden" value="analyst" />
<script src="/analyst/assets/app.js?v=track45-voice-name-flow-v1"></script>
</body>
</html>
+207
View File
@@ -0,0 +1,207 @@
{
"queue_options": [
{ "queue_id": "sales_kz", "name": "Продажи KZ" },
{ "queue_id": "support_kz", "name": "Поддержка KZ" },
{ "queue_id": "vip_kz", "name": "VIP-линия" },
{ "queue_id": "retention_kz", "name": "Удержание" }
],
"agents": [
"agent.aigerim",
"agent.dias",
"agent.nurdaulet",
"agent.madina",
"agent.ruslan",
"agent.tomiris"
],
"queue_factors": {
"sales_kz": 1.08,
"support_kz": 0.96,
"vip_kz": 0.58,
"retention_kz": 0.72
},
"channel_base": {
"voice": { "total": 620, "answered": 584, "abandoned": 36 },
"telegram": { "total": 214, "answered": 205, "abandoned": 9 },
"whatsapp": { "total": 182, "answered": 171, "abandoned": 11 },
"webchat": { "total": 141, "answered": 132, "abandoned": 9 },
"email": { "total": 108, "answered": 94, "abandoned": 14 }
},
"ai_reason_labels": {
"requested_human": "Запрос оператора",
"knowledge_or_tool_gap": "Не хватило знаний или инструмента",
"policy_or_sensitive": "Чувствительный сценарий",
"delivery_or_runtime_error": "Ошибка доставки или runtime",
"manual_claim": "Ручной takeover",
"other": "Другая причина"
},
"interaction_statuses": [
"closed",
"in_progress",
"closed",
"new",
"closed",
"escalated"
],
"agent_state_cycle": [
"READY",
"BUSY",
"READY",
"BREAK",
"BUSY",
"OFFLINE"
],
"coverage_note": "Показаны демонстрационные данные для временного наполнения витрины.",
"dashboard_coverage": {
"implemented_metrics": ["SL", "ASA", "AHT", "Abandon", "FCR", "DigitalShare"],
"dimensions": ["queue", "channel", "agent", "shift"],
"supported_filters": ["preset", "from_ts", "to_ts", "queue_id", "channel"]
},
"ai_channel_rows": [
{
"channel": "telegram",
"sessions_started": 176,
"ai_only_sessions": 106,
"human_touched_sessions": 58,
"handoff_rate": 24.4,
"ai_latency_avg_ms": 1380,
"containment_rate": 60.2,
"closed_without_operator_rate": 52.1
},
{
"channel": "whatsapp",
"sessions_started": 142,
"ai_only_sessions": 80,
"human_touched_sessions": 54,
"handoff_rate": 28.9,
"ai_latency_avg_ms": 1524,
"containment_rate": 56.4,
"closed_without_operator_rate": 48.6
}
],
"voice_name_flow": {
"totals": {
"scenario_calls": 196,
"start_obtained": 118,
"downstream_ai_obtained": 34,
"followup_required": 18,
"name_not_obtained": 26,
"manual_corrected": 12,
"handoff_confirmed_name": 14,
"handoff_unconfirmed_name": 28,
"needed_downstream": 78
},
"languages": [
{
"language": "ru",
"share": 0.58,
"start_capture_rate": 66.2,
"downstream_rescue_rate": 47.4,
"handoff_unconfirmed_rate": 31.8,
"manual_correction_rate": 14.6
},
{
"language": "kz",
"share": 0.29,
"start_capture_rate": 61.7,
"downstream_rescue_rate": 51.3,
"handoff_unconfirmed_rate": 28.4,
"manual_correction_rate": 11.8
},
{
"language": "unknown",
"share": 0.13,
"start_capture_rate": 44.8,
"downstream_rescue_rate": 36.1,
"handoff_unconfirmed_rate": 46.5,
"manual_correction_rate": 23.0
}
],
"queues": [
{
"queue_id": "sales_kz",
"share": 0.31,
"start_capture_rate": 68.4,
"downstream_rescue_rate": 49.6,
"handoff_unconfirmed_rate": 24.1,
"manual_correction_rate": 11.2
},
{
"queue_id": "support_kz",
"share": 0.39,
"start_capture_rate": 61.2,
"downstream_rescue_rate": 46.9,
"handoff_unconfirmed_rate": 31.8,
"manual_correction_rate": 15.4
},
{
"queue_id": "vip_kz",
"share": 0.11,
"start_capture_rate": 73.5,
"downstream_rescue_rate": 52.8,
"handoff_unconfirmed_rate": 18.6,
"manual_correction_rate": 8.9
},
{
"queue_id": "retention_kz",
"share": 0.19,
"start_capture_rate": 55.1,
"downstream_rescue_rate": 39.4,
"handoff_unconfirmed_rate": 37.9,
"manual_correction_rate": 19.7
}
],
"coverage": {
"sessions_with_start_decision": 192,
"sessions_with_final_ai_state": 184,
"sessions_with_manual_overlay": 12,
"note": "Мок-данные по voice name-flow показывают стартовый захват имени, добор AI и ручное исправление оператором."
},
"trend_profiles": {
"scenario_calls": { "base": 24, "step": 2.4, "cycle": 4 },
"start_capture_rate": { "base": 60.5, "step": 2.2, "cycle": 4 },
"downstream_rescue_rate": { "base": 40.2, "step": 1.9, "cycle": 5 },
"handoff_unconfirmed_rate": { "base": 33.1, "step": 2.4, "cycle": 4 },
"manual_correction_rate": { "base": 14.4, "step": 1.5, "cycle": 3 }
},
"empty_note": "За выбранный период нет звонков, прошедших через сценарий сбора имени."
},
"voice_name_labels": {
"scenario_calls": "Звонки в сценарии",
"start_obtained": "Имя взято сразу",
"needed_downstream": "Потребовался AI после старта",
"downstream_ai_obtained": "Имя добрал AI после follow-up",
"handoff_confirmed_name": "Передача с подтверждённым именем",
"handoff_unconfirmed_name": "Передача без подтверждённого имени",
"confirmed_name": "Передача с подтверждённым именем",
"unconfirmed_name": "Передача без подтверждённого имени"
},
"agent_shift_rows": [
{
"shift_key": "night",
"label": "Ночная смена",
"agents_with_activity": 2,
"interactions_total": 18,
"answered_total": 17,
"avg_handle_seconds": 356,
"fcr_rate": 69.5
},
{
"shift_key": "day",
"label": "Дневная смена",
"agents_with_activity": 5,
"interactions_total": 52,
"answered_total": 53,
"avg_handle_seconds": 318,
"fcr_rate": 76.8
},
{
"shift_key": "evening",
"label": "Вечерняя смена",
"agents_with_activity": 3,
"interactions_total": 30,
"answered_total": 30,
"avg_handle_seconds": 334,
"fcr_rate": 73.4
}
]
}