Дашборд
Главный экран биллинга: показатели за день, тревоги, касса и финансовая динамика. С него начинается рабочий день оператора.
Содержание раздела
1. Дашборд
Как читать главную страницу: период и организация, ключевые показатели, сводки по модулям, деньги, цели и работа с телефона.
Главная страница админки по адресу /admin/welcome/.
Перестроена после /critique-аудита: иерархия KPI с hero-метрикой, единый
визуальный язык компактных карточек (.dash-tile), все блоки скрываются автоматически
при отсутствии данных.

Виджет SORM в правой колонке показывает статус выгрузок:

- Имя конфига → ссылка на
/admin/equipment/sorm_list/<id>/ - Vendor (СпецТехПитон / СигналТек / ...)
- FTP-хост и путь
- Время выгрузки
- Бейдж с числом отчётов
- Статус последней выгрузки: ✓ зелёный N/M файлов / ⚠ оранжевый partial / ✗ красный provаl / ⏳ синий running
- Дата + кол-во строк + значок облака (✅ если ftp_uploaded)
- Сводка за 7 дней (счётчики success/partial/failed)
«Горячие клиенты» + «Платежи: день × час» теперь в одном ряду:

Карта клиентов (была пустой до v966):

Период и организация — общие для всей страницы
Дашборд отвечает на два вопроса сразу: по какой компании смотрим и за какой срок. Оба ответа задаются один раз и действуют на все блоки «за период».

Наверху — период, ниже ключевые показатели, под ними сводки по модулям.
Показатели по выбранной организации
Селектор компаний в шапке админки управляет и дашбордом: клиенты, должники, заявки, деньги, график, карта платежей и топ тарифов считаются в границах выбранной организации. «Все организации» показывает то, к чему у сотрудника есть доступ.
flowchart LR SEL["Селектор компании
в шапке"] --> F{"Фильтр организации"} F --> KPI["Клиенты · должники · заявки"] F --> FIN["Поступления · списания · ARPU"] F --> CH["График · карта платежей"] F --> TILES["Сводки модулей"] INFRA["Сеть: NAS · IP-пулы · СОРМ"] -.->|общие для установки| PAGE["Дашборд"] KPI --> PAGE FIN --> PAGE CH --> PAGE TILES --> PAGE
Единый период
Кнопки 7 дней · 30 дней · Квартал · Год в правой части шапки задают срок для всех блоков «за период»: поступления и списания, ARPU, новые клиенты, заявки, график и карта платежей. Выбор запоминается за сотрудником, поэтому при возврате на главную период остаётся прежним. Заголовки блоков называют выбранный срок — «Итого за период · 30 дней», «ARPU (квартал)», «Новых за год».
Сводки по модулям
Под ключевыми показателями — строка компактных плиток: две-три цифры и ссылка в свой раздел. Плитка появляется только если модуль включён, поэтому на тарифе без модуля строка просто короче.

| Плитка | Что показывает | Куда ведёт |
|---|---|---|
| Сделки в работе | Открытые сделки всех воронок и число просроченных задач | Воронка CRM |
| На складе | Серийные единицы на складе и на руках у монтажников | Склад |
| Заявки с сайтов | Обращения с лендингов за неделю и за сегодня | Лендинги |
| Звонки за сутки | Все звонки и те, у которых не определился клиент | Журнал звонков |
| Разбор выписок | Строки выписок в очереди и проведённые за месяц | Очередь выписок |
| Камеры | Включённые камеры из общего числа | Объекты видеонаблюдения |
flowchart TB
MOD{"Модуль включён?"} -->|нет| SKIP["Плитки нет"]
MOD -->|да| DATA["Считаем по выбранной организации"]
DATA --> OK{"Есть что показать?"}
OK -->|нет| SKIP2["Плитку пропускаем"]
OK -->|да| TILE["Плитка: цифра · пояснение · ссылка"]
TILE --> ATT{"Требует внимания?"}
ATT -->|просрочки, очередь| WARN["Оранжевый значок"]
ATT -->|всё ровно| CALM["Спокойный значок"]
Тёмная тема и телефон
На узком экране слова, которые не несут смысла без контекста («Просмотрено», «Обновление выкл.», «собираемость»), уступают место цифрам, а периоды сокращаются до «7 д · 30 д · 3 м · Год». Сумма дня показывается коротким числом — «154К ₽» вместо «153 957,80 ₽», точное значение остаётся в подсказке.
Шапка: 6 KPI-карточек
Верхний ряд — финансовый/операционный обзор. Hero-карточка «Должников» в 2×
ширину с явным CTA «Все должники →» (единственный btn-primary
на странице — даёт глазу первую точку фиксации). Остальные 5 KPI равноценные:
- 🔵 Всего — все клиенты + топ-3 подкатегории (SMIT / Все / EBS-импорт)
- 🟢 Активных + бейдж «Заблокированных»
- 🟢 Серверов доступа (NAS) с подзаголовком «Онлайн сейчас»
- 🟠 Должников (hero) — с CTA
- 🟡 Открытых заявок + «за 30 дней / всего»
- 🔵 Новых за месяц + «за 7 дней»
Все 6 градиентов унифицированы на linear-gradient(135deg, A, B) в одной палитре
в одной палитре.
IP-пулы + EBS Синхронизация
Две компактные карточки в одну строку (~110px высоты вместо 200+):
- IP-пулы — сводка
used / total (%, N пулов)+ статус-pill (✓ В норме / ⚠ ≥90%: N / 🚨 Опасно при наличии пула ≥99%) + топ-3 «опасных» с горизонтальными mini-bar (красный/оранжевый/жёлтый). - EBS Синхронизация — 3 строки cron-расписаний:
- Импорт: каждые 10 мин, последний запуск + длительность + last tx_id
- Сверка: раз в час, скорректировано N балансов
- Клиенты: ежедневно 04:00 МСК, последний запуск + ETA до следующего
Унифицированные бейджи .dash-pill с цветовым кодированием
(is-ok/is-warn/is-danger/is-info).
JS-обновление каждые 60 сек через /admin/dictionary/ip_pull_stats/ и
/admin/ebs_sync_status/.
Свежие проблемы (alerts feed)
. Отображается только при наличии алертов. Источники:
- 🔴 NAS DOWN сейчас — последний event=down per NAS из
NasStatusLog, с возрастом события - 🔴/🟡 IP-пул ≥99% / 100% через
get_pool_stats(pool) - 🟡 EBS sync failed за 24ч (status=failed в EBS_SYNC_STATE)
- 🟡 Backup failed за 24ч
Каждая строка кликабельна → ведёт в соответствующий раздел. Левый красный бордер 3px, максимум 6 алертов. Видна всем, не только cash-группе.
Касса месяца
. Расчёт по календарному месяцу (с 1-го числа) из
FinanceOperations:

- Начислено — сумма всех
op_summa < 0 - Оплачено — сумма всех
op_summa > 0(зелёный) + Δ-pill «темп vs тот же день прошлого месяца» («+17,4% к апрелю») + hint «прошлый месяц к N-му: X ₽» - Прогноз закрытия — линейная экстраполяция
paid × days_in_month / day_of_month(синий) + Δ-pill «к плану» + hint «прошлый месяц закрыли: X ₽» - Прогресс месяца — цветной progress-bar (зелёный ≥100% / синий 70–99% / оранжевый <70%) + «N/M дн.»
Сверху справа бейдж «✓ Сбор N%» (зелёный/синий/оранжевый по тем же порогам).
Видна только для группы cash.
Платежи сегодня vs вчера
. 4 ячейки + sparkline по часам:
- Платежей (count, шт) + hint «вчера к HH:00 — N»
- Сумма ₽ (зелёный) + hint «вчера — X ₽»
- Средний чек ₽ (бирюзовый) + hint «вчера всего: M / X ₽»
- По часам — 24 столбика sparkline за сегодня. Текущий час голубой с glow, будущие часы серые, оси 0/6/12/18/24.
В шапке — Δ-pill «к вчера» (≥+5% зелёный, ≤−5% оранжевый, иначе ≈ синий).
Горячие клиенты + CRM сегодня
. Две карточки в одной строке: «Горячие клиенты» (col-lg-8) + «CRM сегодня» (col-lg-4).

Горячие клиенты 24ч — скоринг и интерпретация
Топ-5 клиентов, кому стоит уделить внимание прямо сейчас. Алгоритм в
billing/views/auth.py::welcome.
Скоринг (суммируется):
- Разрывы сессий за 24 часа (≥3 завершённых сессий): 3–9 → 30 pts, 10–29 → 40 pts, ≥30 → 60 pts
- Открытые тикеты (status 1=Открыта, 2=В работе) с обращением за 24 часа: 1 шт → 10 pts, ≥2 → 25 pts
- «Оплатил, но заблокирован» (b_negbal=true + положительный платёж сегодня) → 50 pts — критично, клиент заплатил, но биллинг не разблокировал
В блок попадают клиенты со score ≥ 15, отсортированные по убыванию.
Цвет строки: ≥50 — красный, ≥25 — оранжевый, <25 — синий.
Что значат коды разрыва (END_REASON в RADIUS_SESSIONS):
Lost-Carrier— NAS перестал видеть клиента: PPP-keepalive не пришёл, физический линк упал, или MikroTik сам разорвал по idle-timeout. Самый частый код у проблемных клиентов.User-Request— клиент сам инициировал отключение (PPPoE-disconnect от устройства клиента). Часто маршрутизатор «дёргает» PPP при потере WAN или по таймеру.NAS-Request— NAS принял решение отключить (CoA Disconnect, смена тарифа, остановка сервиса биллингом).Synthetic (no Start): User-Request— искусственный Stop-пакет, созданныйradius_accounting.py, потому что NAS прислал Stop без предшествующего Accounting-Start. Бывает после рестарта FreeRADIUS или потери Start-пакета.Stale: no Interim-Update— наш cleanup-таск убил «зомби»-сессию: Interim-Update не приходил >10 минут.
Корневые причины (паттерны):
- Массовые Lost-Carrier каждые 4–10 минут (100+ разрывов за сутки) — обрыв физики: гнилой коннектор RJ-45, плохая обжимка, попадание воды в муфту, проблема PoE-инжектора, MAC-конфликт на порту коммутатора. Это не баг биллинга и не пароль (тот дал бы Access-Reject). Действие: выезд монтажника на точку.
- Десятки User-Request с короткими сессиями (~2 минуты)
— клиентский роутер сам разрывает PPP. Возможно: двойной PPPoE-клиент в прошивке,
жёсткий
idle-timeoutв настройках, скрипт автоматического переподключения. Действие: связаться с клиентом, проверить настройки роутера. - Lost-Carrier раз в 30–60 минут — нестабильный канал, наводки, перегрев SFP/коммутатора. Менее острый сигнал, но повод заявить в техобслуживание.
- «Оплатил, но заблокирован» (50 pts) — смотрим в карточке
последние FinanceOperations и AbonentsBlock. Обычно это сбой автоматики
разблокировки после платежа. Жмём «Разблокировать» вручную, проверяем что
в Celery-beat работает task
recheck_blocks.
Что смотреть в карточке клиента:
- Вкладка «RADIUS» — последние 50 сессий с
END_REASON, длительностью, IP, NAS. Главный диагностический инструмент. - Вкладка «История» — кто и когда менял состояние блокировок.
- Вкладка «HelpDesk» — все тикеты клиента + быстрая ссылка в HelpDesk.
Состав строки в блоке: цветной score-badge → имя клиента (ссылка на карточку) → список причин («N разрывов», «тикет», «оплатил, но заблокирован») → баланс (красный если долг) → стрелка перехода в карточку.
CRM сегодня — сводка из HelpDesk (mailbox=1) за календарный день:
- Открыто — count
createdAt >= 00:00 - Закрыто — count status=closed с
updatedAt >= 00:00 - Среднее закрытие —
avg(updatedAt − createdAt)для закрытых сегодня (мин/ч/д) - Бейдж ⚠ Висят: N — активные старше 30 мин без assignee
Под цифрами — 3 последних тикета с цветной точкой статуса
(active/pending/closed/spam), темой #N · subject (truncate 60 симв,
кликабельно → адрес поддержки/conversation/<id>), клиент + исполнитель + возраст.
Кеш 5 мин по ключу dashboard_crm_24h.
Heat-map + Цели + Что нового
. Три узких карточки в одной строке.

Heat-map платежей 7×24 (фиолетовая палитра) — день недели × час, цветовая
интенсивность rgba(#6f42c1, alpha) от количества платежей. SQL:
SELECT EXTRACT(ISODOW FROM "OP_DATE"), EXTRACT(HOUR FROM "OP_DATE"), COUNT(*)
FROM finance_operations WHERE "OP_DATE" >= now() - 7 days AND "OP_SUMMA" > 0
GROUP BY 1, 2;
Hover увеличивает ячейку 1.4× с tooltip «N пл.». Помогает увидеть паттерн — например, пик платежей в Пн ~17:00.
KPI с целями — читает SystemSettings:
DASH_MONTHLY_REVENUE_TARGET— план кассы за месяц (₽)DASH_ACTIVE_ABONENTS_TARGET— план активных клиентовDASH_NEW_MONTH_TARGET— план подключений за календарный месяц
Без таргетов карточка скрыта. Цветной progress-bar (зелёный ≥100% / синий ≥70–80% / оранжевый ниже).
Меняются через /admin/settings/system/?tab=params
(категория dashboard) без релиза.
Что нового — 2 секции из dev_reports/:
- Отчёты — 4 свежих
.mdфайла из подкаталога «Отчёты» (по mtime DESC). Заголовок = первая Markdown H1 строка. - Планы — 4 свежих из подкаталога «Планы».
Каждая запись с нумерацией 1–4, кликабельна → /admin/reports/dev/?file=<path>.
Подкаталог Документация исключён.
Итого за период + Финансовая динамика (старые блоки)
Сохранены: 3-row «Итого за период» (Поступления/Списания/Баланс с дельтами)
и линейный график «Финансовая динамика» с переключателями типа (Область/Линия/Столбцы)
и периода (7д/14д/30д/90д/180д/1г). Кнопки в чистом стиле ( — фикс «серой губой»
заливки .btn-outline-secondary).

Auto-refresh
Переключатель в шапке: Выкл / 30с / 1м / 2м / 5м / 10м.
Состояние сохраняется в localStorage.dashboard_refresh_sec. Дефолт — выкл.
Кнопка «Обновить сейчас» и таймер «Просмотрено: N сек/мин назад» рядом.