Граф Wiki

Личный кабинет абонента и мобильные приложения

Эта страница — единственный источник правды для всего, что касается ЛК и мобильных приложений: брендинг, функциональные модули, безопасность входа, версионирование, push-уведомления.

Содержание раздела

Обзор и возможности

Личный кабинет — Главная (десктоп) Личный кабинет — Главная (мобильная)

Возможности личного кабинета:

Раздел «ЛК и мобильные» в админке

Все user-facing настройки ЛК и мобильных приложений собраны на одной странице: /admin/settings/lk/ с 5 вкладками. Это позволяет оператору перепродавать биллинг под собственным брендом или скрывать неиспользуемые модули без правки шаблонов и деплоя.

Картинки разделов ниже добавим после Phase D (когда Playwright освободится).

Вкладки

ВкладкаURLЧто настраивается
Обзор/admin/settings/lk/overview/ 4 KPI-cards (push-токенов / Telegram / VK / активных сессий) + сводка брендинга и мобильных версий + таблица последних 10 входов в ЛК (login/IP/канал/метод) + круговая диаграмма каналов входа за 30 дней
Брендинг/admin/settings/lk/branding/ 9 LK-overrides поверх CompanyBranding: brand_short, контакты поддержки, соцсети VK/MAX, color-override
Функции/admin/settings/lk/features/ 12 toggle-флагов для скрытия/показа модулей в ЛК и мобиле
Безопасность/admin/settings/lk/security/ 16 ключей: метод авторизации, лимиты входа, требования к паролю, TTL сессии, 2FA, audit
Мобильное/admin/settings/lk/mobile/ Android + iOS параллельно: текущая/мин. версия, force-update URLs, push-настройки, mobile features

Сохранение настроек идёт через единый endpoint POST /admin/settings/lk/save/ с полем _tab= для определения какие ключи обновлять. Все изменения пишутся в AuditOperations через write_audit(table_name='LK_SETTINGS'). После сохранения 60-секундный кеш lk_brand context_processor инвалидируется автоматически.

Последние входы и каналы

На вкладке «Обзор» добавлены два аналитических блока:

Audit-запись успешного входа создаётся во всех 4 точках авторизации:

Канал определяется хелпером _detect_lk_channel(user_agent) по User-Agent: UA smit_billing_app/X.Y.Z (мобильное приложение) → android или ios в зависимости от платформенных маркеров; iPhone/iPad UA → ios; Android browser → android; Mozilla/Chrome/Safari/Firefox/Edge → web; иначе unknown.

Брендинг

На вкладке выводится read-only сводка из CompanyBranding (логотип, название, цвет, юр. реквизиты) с CTA-кнопкой «Изменить брендинг компании» ведущей в общие настройки /admin/settings/system/?tab=branding. Логотип/реквизиты не дублируются — единая точка правды.

LK-overrides (9 полей):

В правой колонке — iframe-превью /lk/login/ (sticky-top), перезагружается после каждого save.

Функции (feature flags)

12 toggle-switches скрывают/показывают модули в ЛК и мобильном приложении:

Применение мгновенное: lk_features context_processor (60-сек кеш) подставляет флаги во все шаблоны ЛК. В sidebar пункты обёрнуты в {% if lk_features.X %}…{% endif %}. Mobile API возвращает флаги в GET /mobile-api/v1/features.

«Только Mobile» бейдж: 4 флага (LK_FEATURE_IPTV, LK_FEATURE_PAPER_INVOICE, LK_FEATURE_IPV6, LK_FEATURE_BALANCE_HISTORY_CHART) в текущей версии веб-ЛК не имеют читателей в lk/templates/lk/base.html — они реализованы только в Mobile App через GET /mobile-api/v1/features. В админке эти 4 toggle отмечены синим бейджем «только Mobile» чтобы оператор не ожидал эффекта в веб-кабинете. Если потребуется — добавить {% if lk_features.iptv %}…{% endif %} блоки в шаблоны ЛК.

Promise Pay management — 5 числовых ключей в Features tab, реализуют политики доступности обещанного платежа в lk/views/promise_pay.py::_check_promise_pay_eligibility():

При нарушении любой из политик возвращается понятное сообщение («Между двумя обещанными платежами должно пройти 30 дней (подождите ещё 12 дн.)»), и кнопка активации становится disabled. Аналогичные проверки в mobile_api/views/finance.py::promise_pay() через reuse того же хелпера — реакция API: HTTP 400 с {"detail": "...", "eligibility_error": "..."}.

Phantom-cleanup: из Security tab удалены 10 ключей которые раньше отображались как настройки, но не имели читателя в коде: LK_AUTH_METHOD, LK_AUTH_OTP_LENGTH/_TTL_SECONDS, LK_LOGIN_CAPTCHA_AFTER, LK_PASSWORD_HISTORY_CHECK, LK_PASSWORD_EXPIRY_DAYS, LK_SESSION_TTL_MINUTES/_IDLE_LOGOUT/_SINGLE_DEVICE, LK_TOTP_REQUIRED_FOR_PAYMENT_ABOVE. Это были «фантомные» настройки — UI создавал ощущение что они работают, на деле — нет. Будут добавлены обратно вместе с реальной реализацией.

Push-настройки — теперь подключены в billing/tasks/push_notifications.py:

Срочные broadcast-уведомления (авария) могут передавать respect_quiet=False и пройти через quiet-hours. send_push_to_abonent(force=True) игнорирует и quiet-hours, и daily-limit.

Sprint B — реализация legacy LK-флагов

В 12 LK-настроек были мигрированы из VpnConst в SystemSettings, но в коде ЛК ещё не подключены — на UI они отображались с warning-бейджем «будет реализовано». В все они подключены и переведены в статус «работает».

ФлагГде реализовано
LK_SHOW_SERVICESsidebar в base.html + новый раздел /lk/services/ (lk/views/services.py) с каталогом услуг и формами connect/disconnect
LK_SHOW_AUDITsidebar в base.html + новый раздел /lk/audit/ — FinanceOperations за 12 мес с KPI поступления/списания
LK_SHOW_HELPDESKусловный show пункта «Поддержка» в sidebar
LK_SHOW_DETAILED_TRAFFICsessions.html: переключение между in/out (детально) и компактным total_bytes
LK_HIDE_TARIFF_SPEEDdashboard.html: скрытие Мбит/с в карточке тарифа
LK_HIDE_TARIFF_TABскрытие пункта «Тарифы» в sidebar (запрет смены)
LK_HIDE_PAYMENT_TABскрытие пунктов «Платежи» и «Оплатить» в sidebar
LK_ALLOW_MAC_CHANGEcard в profile.html + action change_mac в lk/views/profile.py с валидацией формата AA:BB:CC:DD:EE:FF и audit LK_MAC_CHANGE
LK_TARIFF_REQUIRE_RANGEфильтр в lk/views/tariff.py: при смене тарифа предлагаются только тарифы с тем же usluga_range_type_id
LK_REQUIRE_SAME_IPLkAuthMiddleware сохраняет IP в session['lk_login_ip'] при логине и завершает сессию при смене IP (с redirect на /lk/login/)
LK_AUTOLOGIN_BY_IPLkAuthMiddleware: если пользователь не залогинен и ровно один Users с ip=client_ip и enabled=True — автоматический вход. Public-paths (/lk/login, /lk/auth/, webhook'и) исключены. Audit LK_LOGIN_SUCCESS с method=autologin_ip
LK_DISABLE_PASSWORD_CHANGEchange_password() возвращает redirect с error на dashboard; пункт «Сменить пароль» скрыт в sidebar
Раздел «Услуги абонента» (/lk/services/)

Новый раздел в ЛК для управления подключёнными услугами. Использует 5 ранее не подключённых полей Usluga:

Audit LK_SERVICE_CONNECT и LK_SERVICE_DISCONNECT при каждой операции. Excludes услуг с system_type=11 (это обещанный платёж — управляется отдельно).

Legacy LK-настройки (мигрированы, реализованы) — 9 toggle, отображаются ниже основных feature-toggle во вкладке «Функции»:

Безопасность

16 настроек на 4 секции:

Lockout фактически работает в lk/views/auth.py::login_view: per-login + per-IP keying в Redis-cache, окно отслеживания = lockout_minutes × 2. После исчерпания попыток — все логины с этого IP+login получают «Слишком много неудачных попыток. Попробуйте через N мин», audit-запись LK_LOGIN_LOCKOUT.

Legacy LK-настройки безопасности — 3 дополнительных переключателя, мигрированы из старого раздела «Настройки системы»:

Мобильное (Android + iOS, force-update)

Двухколоночный layout: Android | iOS. Параллельные настройки:

Общие настройки (применяются к обеим платформам):

На вкладке есть тест-кнопка «Превью force-update»POST /admin/settings/lk/mobile/preview_force_update/ принимает platform=android|ios&version=X.Y.Z и показывает JSON-ответ как для мобилки. Удобно проверить что must_update=true срабатывает для нужных версий.

Авторизация

Поддерживается три способа входа:

Страница входа в ЛК

Telegram Login Widget требует регистрации домена в BotFather: /setdomain → укажите домен сайта (например, billing.example.com).

Настройки интеграций

Все параметры интеграций настраиваются через панель управления без необходимости редактирования файлов.

Настройки хранятся в базе данных (таблица system_settings) с Redis-кэшированием (5 мин). Изменения применяются мгновенно без перезапуска сервера.

Страницы настроек

РазделURLПараметры
Telegram/admin/settings/integrations/?tab=telegramBot token, username, webhook secret
VK/admin/settings/integrations/?tab=vkApp ID, secret key, community token
FreeScout/admin/settings/integrations/?tab=freescoutURL, API key, mailbox ID
AIDA AI/admin/settings/integrations/?tab=aidaURL, API key, LK/Mobile/Monitor toggles
TVIP Media/admin/settings/integrations/?tab=tvipURL, login/password, provider ID
LFStream/admin/settings/integrations/?tab=lfstreamURL, login/password
Платежи/admin/settings/payment/YooKassa/W1 credentials, commission
Email/SMS/admin/settings/messaging/SMTP, SMSAero, sender name
Firebase/admin/settings/messaging/?tab=firebaseFirebase credentials path
IPTV-пакеты/admin/settings/iptv_mappings/Маппинг услуг на ТВ-пакеты
API Адреса/admin/settings/integrations/?tab=address_apiПубличный API автоподсказок и проверки покрытия

API проверки адреса

Публичный API для сайта провайдера — автоподсказки адресов и проверка возможности подключения. Не требует авторизации, поддерживает CORS.

Настройки: вкладка API Адреса на странице интеграций. Включает: лимит результатов, разрешённые домены CORS, настройки AI-ассистента для автоматической проверки адресов.

Настройки API адресов

JS-виджет для подключения на сайте: /static/js/address_widget.js. Подробная документация: Разработка → Документация → API адреса интеграция.

Миграция с .env

При обновлении с предыдущей версии выполните одноразовый перенос настроек из .env в базу данных:

docker compose exec web python manage.py migrate_env_to_db

Команда безопасна для повторного запуска — создаёт только отсутствующие ключи.

Инфраструктурные параметры (DB_*, REDIS_URL, SECRET_KEY, DEBUG) по-прежнему задаются в .env файле. В панель вынесены только настройки интеграций и платежей.

Telegram-бот для уведомлений

Бот используется для двух целей: OAuth-авторизация в ЛК и push-уведомления абоненту (списание, пополнение, блокировка).

Telegram-бот настройки

Создание бота:

  1. Написать @BotFather в Telegram
  2. /newbot — создать бота, получить токен
  3. /setdomain → указать домен сайта (для Login Widget)
  4. Прописать токен в Настройки → Интеграции → Telegram

Регистрация вебхука:

docker compose exec web python manage.py setup_telegram_webhook \
  --url https://billing.example.com/lk/telegram/webhook/

# Проверка:
docker compose exec web python manage.py setup_telegram_webhook --info

Как абонент привязывает Telegram:

  1. В ЛК → Профиль → блок «Уведомления в Telegram» → кнопка «Привязать»
  2. ЛК генерирует одноразовый токен (действует 10 минут) и показывает ссылку вида https://t.me/BotName?start=TOKEN
  3. Абонент переходит в бот, отправляет /start TOKEN
  4. Бот сохраняет telegram_chat_id в профиль абонента
  5. После привязки уведомления отправляются автоматически через Celery-задачи
Важно: Один бот — один вебхук. Если тот же бот используется в FreeScout — необходимо создать отдельного бота специально для биллинга.

Telegram-бот для операторов (admin bot)

Отдельный бот для технического персонала оператора. Позволяет управлять абонентами, мониторить NAS и выполнять экстренные операции прямо из Telegram — без доступа к веб-интерфейсу.

Безопасность: Все команды доступны только пользователям из списка Администраторы бота (Telegram user IDs). Настройка: Настройки → Интеграции → Telegram.

Настройка

  1. Создать бота через @BotFather/newbot
  2. Прописать токен в Настройки → Интеграции → Telegram
  3. Добавить администратора в блок Администраторы бота — по Telegram ID или @username. Бот отобразит аватарку, имя и ссылку на профиль
  4. Указать Chat ID и Thread ID (топик) супергруппы для алармов
  5. Зарегистрировать webhook кнопкой «Зарег. webhook» или командой:
    docker compose exec web python manage.py setup_telegram_webhook --url https://yourdomain.ru/lk/telegram/webhook/

Команды диагностики

КомандаОписание
/billdiagПолный диагностический отчёт: состояние сервисов (PostgreSQL, Redis, FreeRADIUS, Celery), метрики БД (размер, соединения, медленные запросы), NAS (онлайн/оффлайн), абоненты (активные, RADIUS-ready, онлайн)
/statsСводная статистика: всего абонентов, активных, онлайн, тарифов, NAS, должников
/debtorsДолжники: количество абонентов с отрицательным балансом и суммарный долг
/revenue [today|week|month]Выручка за период (сумма входящих платежей). Без параметра — за текущий месяц

Управление абонентами

КомандаОписание
/find <запрос>Поиск абонента по имени, логину, номеру договора или IP-адресу. Возвращает до 5 результатов с ID, именем, балансом и статусом
/balance <id>Детальная карточка абонента: баланс, тариф, статус (активен/заблокирован), логин, IP
/block <id> [причина]Заблокировать абонента (устанавливает флаг b_admin). Причина блокировки сохраняется в комментарии
/unblock <id>Разблокировать абонента (снимает все административные блокировки)
/disconnect <id>Принудительно отключить активную сессию абонента: сначала через RADIUS CoA Disconnect-Request, при неудаче — через SSH (для MikroTik)
/pay <id> <сумма>Зачислить платёж на счёт абонента. Создаёт запись в FinanceOperations и обновляет баланс

Мониторинг NAS / Сеть

КомандаОписание
/nasСписок всех NAS с IP-адресами и количеством онлайн-абонентов из биллинга (USERS_RADIUSAUTH)
/sessions <nas_id>Активные PPPoE сессии на конкретном NAS (через SSH или MikroTik API): логин, IP, uptime
/sync <nas_id>Принудительная синхронизация сессий NAS ↔ биллинг: сравнивает онлайн-пользователей, отключает «призраков», обновляет статусы

Экстренные операции

КомандаОписание
/logs <service> [N]Последние N строк лога контейнера. Сервисы: web, celery, radius, beat, db. По умолчанию 20 строк
/restart radiusПерезапуск контейнера app-freeradius-1 (регенерация clients.conf из таблицы NAS)
/restart celeryПерезапуск Celery workers (app-celery-1)
/broadcast "<текст>"Массовая рассылка сообщения всем активным абонентам через все доступные каналы (SMS, Email, Telegram)

Алармы (автоматические уведомления)

Система автоматически отправляет алармы в супергруппу (Chat ID + Thread ID) при следующих событиях:

СобытиеТриггерНастройка
NAS offlineNAS не отвечает на ping (TCP-connect)NAS offline
RADIUS ошибкаИсключение в authorize() или accounting()RADIUS
Медленные запросы БДPostgreSQL: запрос выполняется >10 секSQL
Сервис упалPostgreSQL / Redis недоступныСервисы
Проблемы синхронизацииМного «призраков» или рассинхрон >порогаNAS sync

Уведомления о документах разработки

Бот автоматически отправляет уведомления в настроенные чаты при появлении новых .md-файлов в папке dev_reports/. Настройка выполняется в Настройки → Интеграции → Telegram (/admin/settings/integrations/?tab=telegram):

Прокси для Telegram

Если сервер находится в России, прямой доступ к api.telegram.org может быть заблокирован. Настройте SOCKS5-прокси в Настройки → Интеграции → Telegram → Прокси. Система использует socks5h (DNS через прокси) для корректной работы.

# Проверка прокси вручную
curl -x socks5h://user:pass@proxy_host:port https://api.telegram.org

Оплата через YooKassa

Абоненты могут пополнять счёт банковской картой через YooKassa (бывший ЮMoney Business). Оплата доступна из личного кабинета на сайте и из мобильного приложения.

Оплата через ЮKassa в ЛК Платежи — мобильная версия

Поддерживаемые протоколы

Система автоматически определяет протокол по формату секретного ключа:

ПротоколФормат ключаОписание
REST API v3 (рекомендуется)Начинается с live_ или test_Современный протокол. Создание платежа через JSON API, webhook — JSON.
HTTP-протокол (старый)Любой другой (например, SmitSecretKey)Старый Yandex.Kassa. Форма POST на yoomoney.ru/eshop.xml, webhook — XML с MD5.

Настройка через админ-панель

Перейдите в Настройки → Настройки ЮKassa (/admin/settings/payment/). На странице можно:

Настройка вручную через .env

Переменные окружения для YooKassa:

ПеременнаяОписаниеПример
LK_YOOKASSA_SHOP_IDID магазина267304
LK_YOOKASSA_SECRET_KEYСекретный ключ (REST API v3) или shopPassword (HTTP)live_ABC... или SmitSecretKey
LK_YOOKASSA_SCIDНомер витрины (только HTTP-протокол)2487841
LK_YOOKASSA_SUCCESS_URLURL после успешной оплатыhttps://billing.example.com/lk/payments/result/
LK_YOOKASSA_FAIL_URLURL при ошибке оплатыhttps://billing.example.com/lk/payments/result/?status=failure

Webhook (уведомления об оплате)

В настройках магазина ЮKassa укажите URL для уведомлений:

# Для обоих протоколов (checkUrl, avisoUrl, HTTP-уведомления):
https://billing.example.com/lk/payments/webhook/

Webhook обрабатывает:

Как работает зачисление

  1. ЮKassa отправляет POST на webhook
  2. Система проверяет подпись (MD5 или JSON)
  3. Находит абонента по customerNumber / metadata.abonent_id
  4. Увеличивает баланс (account.ostatok)
  5. Создаёт запись в истории операций: «Онлайн-оплата (YooKassa)»
Важно: После смены домена или сервера необходимо обновить checkUrl / avisoUrl в кабинете ЮKassa — иначе уведомления об оплате не будут приходить и зачисление не произойдёт.

Мобильное приложение

Android-приложение «СмИТ Биллинг» для абонентов. Работает через Mobile API (/mobile-api/v1/).

Возможности приложения

Оплата в приложении

При нажатии «Пополнить» приложение вызывает POST /mobile-api/v1/finance/pay. Ответ содержит URL платёжной страницы — приложение открывает его в браузере. После оплаты баланс обновляется автоматически.

Mobile API

Авторизация: JWT (simplejwt). Эндпоинты:

МетодURLОписание
POST/mobile-api/v1/auth/loginАвторизация (contract + password → JWT)
POST/mobile-api/v1/auth/refreshОбновление токена
GET/mobile-api/v1/account/statusБаланс, тариф, блокировки, уведомление, последний платёж
GET/mobile-api/v1/account/tariffsДоступные тарифы
POST/mobile-api/v1/account/tariffСмена тарифа
GET/mobile-api/v1/finance/historyИстория платежей (фильтр, пагинация)
POST/mobile-api/v1/finance/payСоздание платежа (YooKassa)
GET/POST/DELETE/mobile-api/v1/finance/promise_payОбещанный платёж
GET/POST/mobile-api/v1/support/ticketsТикеты (список + создание)
POST/mobile-api/v1/push/registerРегистрация FCM/APNS токена

Public Mobile API

Три новых публичных эндпоинта без auth для конфига приложения при старте. Кэшируются на стороне клиента 5 мин (Cache-Control header).

МетодURLОписание
GET/mobile-api/v1/branding Снимок брендинга: logo, colors, name, support contacts, social (VK/MAX), legal (ИНН/КПП/адрес). Источник: CompanyBranding + LK-overrides.
GET/mobile-api/v1/features Feature flags (12 LK + 3 mobile-only): iptv, chat_ai, voluntary_block, promise_pay, tariff_change, sessions_history, payment_history, paper_invoice, ipv6, speed_test, referral, balance_history_chart, biometry, offline_mode, dark_theme_default.
GET/mobile-api/v1/version/check?platform=android|ios&version=X.Y.Z Force/soft-update check. Возвращает must_update, should_update, store_url, title, text. Для iOS дополнительно distribution: testflight|appstore.

Эти endpoints вызываются Flutter-приложением при старте, чтобы:

  1. Применить актуальный primary_color к Theme
  2. Обновить контакты поддержки в Profile-tab без релиза приложения
  3. Скрыть/показать табы по feature flags
  4. Показать force-update диалог если установленная версия < min

Force-update механизм

При запуске Flutter-приложения вызывает GET /mobile-api/v1/version/check:

Семвер-сравнение делается через split('.') и числовой compare. Robust к мусорным значениям — при ошибках возвращает [0,0,0].

iOS: TestFlight ↔ App Store

iOS-приложение проходит несколько стадий релиза:

  1. TestFlight (beta): пока приложение не в App Store — MOBILE_FORCE_UPDATE_URL_IOS ведёт на testflight.apple.com/join/..., MOBILE_IOS_DISTRIBUTION=testflight. На вкладке Мобильное жёлтый бейдж «TestFlight (beta)».
  2. App Store (production): после релиза оператор:
    • Меняет URL на https://apps.apple.com/app/...
    • Переключает MOBILE_IOS_DISTRIBUTION на appstore
    • Вкладка показывает зелёный бейдж «App Store (production)»

Никакой пересборки биллинга не требуется. Mobile API сразу начинает отдавать новую информацию, Flutter-клиенты подхватывают её при следующем version/check запросе.

Поддержка через FreeScout

Абоненты могут создавать обращения и переписываться с операторами прямо из ЛК. Для работы требуется настроенная интеграция с FreeScout (см. раздел 4.3).

Поддержка — Открытые обращения Поддержка — мобильная версия

Возможности раздела поддержки в ЛК:

AI-ассистент (Claude / AIDA)

Встроенный чат с AI-ассистентом. Основной провайдер — Claude (Anthropic); при отсутствии ключа автоматически используется резервный провайдер AIDA. Отвечает на вопросы абонента о балансе, тарифе, оплате и технических проблемах. При невозможности помочь — автоматически передаёт вопрос оператору.

AI-чат (десктоп) AI-чат (мобильная версия)

Возможности AI-чата:

ПровайдерПеременная .envУсловие
Claude (Anthropic)ANTHROPIC_API_KEYИспользуется при наличии ключа (основной)
AIDAAIDA_API_URL + AIDA_API_KEYРезервный — при отсутствии Claude-ключа
Настройка: В .env задайте ANTHROPIC_API_KEY. Claude API-запросы проходят через прокси из настроек Telegram (TELEGRAM_PROXY_HOST/PORT) — это необходимо, так как api.anthropic.com заблокирован с российских IP-адресов.
Требование: У абонента должен быть указан email в профиле — именно по нему FreeScout идентифицирует клиента.

Профиль абонента

Профиль абонента Профиль — мобильная версия

В разделе «Профиль» абонент может:

Развёртывание и SSL

ЛК входит в тот же Docker Compose проект, что и биллинг — отдельная установка не требуется. Nginx проксирует запросы:

Профиль абонента в ЛК

SSL-сертификат для домена биллинга автоматически покрывает и ЛК. Если ЛК работает на отдельном поддомене — выпустить сертификат через certbot:

certbot --nginx -d lk.example.com

Для PWA-режима обязателен HTTPS. После перехода на HTTPS абоненты могут добавить ЛК на рабочий стол смартфона как приложение.

Firebase Push-уведомления

Push-уведомления для мобильного приложения (Android и iOS) реализованы через Firebase Cloud Messaging (FCM). Настройка в административном разделе Настройки → Интеграции → Firebase (/admin/settings/firebase/).

Firebase Push-уведомления

Настройка Firebase

  1. Откройте Firebase Console → «Настройки проекта» → «Аккаунты служб»
  2. Нажмите «Создать закрытый ключ» — скачается JSON-файл сервисного аккаунта
  3. Укажите путь к этому файлу в поле Service Account JSON

Регистрация токена (Mobile API)

Мобильное приложение регистрирует FCM/APNS-токен при запуске:

POST /mobile-api/v1/push/register
Content-Type: application/json

{
  "token": "fcm_device_token_here",
  "platform": "android"   // или "ios"
}

Автоматические задачи (Celery beat)

ЗадачаРасписаниеОписание
push-low-balance Ежедневно Уведомляет абонентов с низким балансом (low_balance_alerts)
push-promise-expiring Ежедневно Напоминает об истечении обещанного платежа (promise_pay_expiring)

Ручная отправка

Доступны также функции разовой отправки:

Исходный код задач: billing/tasks/push_notifications.py

Тестирование: Откройте карточку абонента → раздел «Отпр. сообщения» → установите флажок «Push-уведомление» → введите текст → «Отправить».

Claude AI — конфигурация AI-ассистента

Управление параметрами AI-ассистента: Настройки → Интеграции (/admin/settings/integrations/) — вкладка AIDA / AI.

Claude AI / AIDA настройки

Переменные окружения (.env)

ПеременнаяОписание
ANTHROPIC_API_KEYAPI-ключ Claude (Anthropic). При наличии — используется как основной провайдер.
AIDA_API_URLURL эндпоинта AIDA (резервный провайдер)
AIDA_API_KEYAPI-ключ AIDA
TELEGRAM_PROXY_HOSTХост прокси-сервера для Claude API
TELEGRAM_PROXY_PORTПорт прокси-сервера
TELEGRAM_PROXY_LOGINЛогин прокси (если требует аутентификации)
TELEGRAM_PROXY_PASSWORDПароль прокси
Почему нужен прокси? Домен api.anthropic.com не имеет IPv4-записей и недоступен из России напрямую. Docker-контейнер не может маршрутизировать IPv6-трафик без настройки. Прокси (например, Telegram-прокси) решает эту проблему.

Переключатели в панели управления

НастройкаОписание
AI в личном кабинетеВключить/выключить AI-чат на странице /lk/chat/
AI в мобильном приложенииВключить/выключить чат в Mobile API (/mobile-api/v1/chat/message)
Мониторинг биллингаРазрешить AIDA/Claude обращаться к данным абонентов через REST API

Эндпоинты чата

URLОписание
GET /lk/chat/Страница чата в личном кабинете
POST /mobile-api/v1/chat/messageОтправить сообщение AI (Mobile API)
POST /mobile-api/v1/chat/escalateПередать переписку оператору FreeScout
GET /mobile-api/v1/chat/statusПроверить доступность AI

Логирование

Модуль billing/services/claude_logger.py записывает диалоги в FreeScout (отдельная база MySQL на сервере поддержки) и параллельно — в локальную PostgreSQL-таблицу ai_chat_log биллинга. Если один из источников недоступен — логирование во второй проходит без ошибки.

AI-ассистент — обучение и управление промптом (build 603-607)

Раздел Настройки → AI-ассистент (/admin/settings/ai/) — единая точка управления системными промптами, эталонными примерами (few-shot) и автотестами AI-чата. Все три канала — Личный кабинет, Мобильное приложение и Email / FreeScout — настраиваются раздельно.

Что значит «обучить Claude»? В нашем контексте это не дообучение весов модели (Anthropic такую возможность не предоставляет). Это: правка system prompt, добавление few-shot примеров «вопрос → идеальный ответ», прогон автотестов и A/B-варианты. Полная инструкция: /admin/reports/dev/?file=Документация%2F2026-05-08_Инструкция_обучение_Claude_агента_поддержки.md.

Вкладка «Промпт»

Редактирование system prompt с версионированием и откатом. Поддерживается prompt caching Anthropic — статическая часть кешируется на 5 минут, экономия до 90% на повторных запросах.

Раздел AI-настроек: вкладка Промпт
ПолеНазначение
System promptТекст инструкции для Claude — стиль, правила, сценарии. Динамические данные клиента (имя, баланс, тариф) добавляются автоматически на каждый запрос.
МодельHaiku 4.5 (по умолчанию — быстро и дёшево), Sonnet 4.6 (точнее), Opus 4.7 (лучшее качество)
Max tokensМаксимальная длина ответа (1024 для LK / 512 для Mobile)
Temperature0.0–1.0; для биллинга рекомендуется 0.3 (фактическая точность важнее креативности)
Ключевые слова эскалацииПри наличии в сообщении клиента — пропуск AI-ответа, прямой переход к оператору
Prompt cachingВключает заголовок anthropic-beta: prompt-caching-2024-07-31 и кеширует статическую часть промпта

История версий справа сохраняет последние 30 правок. Кнопка ↶ восстанавливает любую версию — текущая при этом тоже сохраняется в истории, можно вернуться обратно.

Вкладка «Few-shot»

Эталонные пары «сообщение клиента → идеальный ответ Алисы». Топ-8 по приоритету подмешиваются в статическую часть промпта — попадают в кеш, не пересчитываются на каждый запрос.

Few-shot примеры — карточки user/ideal

На канал LK при первом деплое сидируется 5 эталонных примеров (миграция 0126_ai_fewshot_seed): баланс положительный, баланс отрицательный, диагностика «нет интернета», явная эскалация, OOD-отказ (нерелевантные темы).

Поле карточкиНазначение
ИнтентМетка для группировки (balance / promise_pay / diag / escalation / ood)
Приоритет (0–100)Цветовой бар; чем выше — тем чаще пример попадает в промпт
Сообщение клиентаРеальный (или гипотетический) запрос абонента
Эталонный ответ АлисыОбразцовая формулировка — длина, стиль, структура

Вкладка «Eval»

Автотесты промпта на eval-датасете dev_reports/Документация/ai_eval_dataset.jsonl (58 кейсов в 14 категориях). Каждый кейс проверяется на must_contain, must_not_contain, корректную эскалацию и лимит слов.

История прогонов eval-датасета

Кнопка «Запустить» (с опциональным limit) дёргает реальный API синхронно — 30–60 секунд на полный прогон. После завершения история обновляется, видна pass rate с цветовым кодом: ≥90% зелёный, ≥75% оранжевый, ниже — красный.

CLI-вариант для cron / CI:

docker compose exec web python manage.py ai_eval \
  --channel lk --note "after weekly review N"

Кнопка «Подробнее» на строке прогона открывает модал со всеми кейсами: ID, интент, сообщение, ответ AI, проваленные проверки, время выполнения, токены.

Дашборд AI-чата

Страница Отчёты → AI-чат: дашборд (/admin/reports/ai_chat_dashboard/) — KPI и графики по реальной нагрузке.

AI-чат дашборд: KPI + графики
KPIЧто показывает
СессийУникальных диалогов за выбранный период (1/3/7/14/30 дней)
Помогло (👍)Доля положительных оценок от всех проставленных
Не помогло (👎)Доля негативных + общий процент сессий, в которых клиент поставил оценку
ЭскалацийСколько сессий завершилось передачей оператору в FreeScout
ТокеныСуммарный input/output расход на API за период

Графики:

Telegram-алерты

Celery-задача ai-health-check запускается каждые 15 минут и проверяет показатели за последний час. Если escalation_pct ≥ 40% или down_feedback_pct ≥ 40% — отправляет алерт в Telegram-канал nas_down. Дедуп по severity и дате (один алерт на проблему в сутки).

Управляющие настройки в SystemSettings (категория ai):

КлючЗначение
AI_HEALTH_TELEGRAM_ALERT1 = включено, 0 = выключено
AI_ESCALATION_ALERT_PCTПорог % эскалаций для алерта (по умолчанию 40)
AI_DOWN_FEEDBACK_ALERT_PCTПорог % 👎-оценок для алерта (по умолчанию 40)
AI_HEALTH_MIN_SAMPLEМинимальный размер выборки (по умолчанию 5)

A/B-варианты промпта

Модель AIPromptVariant позволяет тестировать новые версии промпта на доле трафика. Сплит детерминированный: hash(channel:abonent.pk) % 100 — один абонент в одном канале всегда получает один и тот же вариант.

Создание варианта (через Django shell, UI пока не реализован):

from billing.models.ai import AIPromptVariant
AIPromptVariant.objects.create(
    channel='lk', name='exp_v1', weight=30,
    prompt='...новый вариант текста...',
    model='claude-haiku-4-5-20251001',
    max_tokens=1024, temperature=0.3,
    enable_caching=True, is_active=True,
    note='Тест нового сценария для негбала'
)

30% абонентов начнут получать exp_v1, остальные останутся на control. В ai_chat_log каждое сообщение помечено ab_variant — для аналитики через GROUP BY ab_variant можно сравнить escalation_pct, токены, 👍/👎 по группам.

Регламент использования

Раздел «Интеграции» — единый центр

Страница /admin/settings/integrations/ — единая точка управления всеми внешними сервисами биллинга. После реструктуризации — 7 разделов вместо 11: связанные интеграции объединены в группы со sub-tabs и общими info-карточками.

Вкладка «Обзор»

Сводная таблица всех интеграций со статусами, KPI-карточками и кнопками «Проверить все» / «Остановить» / «Обновить статусы». Last-test, ссылки на документацию и шестерёнки для перехода в нужный раздел.

Обзор всех интеграций

Вкладка IPTV (TVIP + LFStream)

Объединяет двух IPTV-провайдеров. Sub-pills переключают между TVIP Media (middleware) и LFStream «Смотрёшка» (CMS). Info-карточка сверху — общий контекст и счётчики маппингов услуг.

IPTV — TVIP

Тесты используют production-клиенты billing/services/iptv/tvip.py::TvipClient и billing/services/iptv/lfstream.py::LfstreamClient с правильной авторизацией (HTTP Basic для TVIP, session-based через CMS /login + CSRF для LFStream).

IPTV — LFStream

Вкладка География (Адреса + Карта)

Геокодер DaData/Яндекс и тайловый слой карты абонентов. KPI-блок сверху: всего адресов, с координатами, точность дома, с абонентами.

География — Адреса География — Карта

Вкладка FreeScout + Claude AI

HelpDesk-интеграция (FreeScout API + MySQL + webhook + автосинхронизация) и Claude AI-ассистент в одном разделе. Claude используется в трёх местах: ЛК-чат, мобильное приложение, FreeScout-модуль (отдельные настройки на support.smit34.ru/claudeai/settings).

FreeScout — основные настройки Claude AI как подраздел FreeScout

Блок «Статистика» показывает количество AI-ответов сегодня (из FreeScout MySQL claudeai_messages) и ссылку на console.anthropic.com/billing для контроля баланса API.

Футер всех страниц админки показывает живой статус AI после блока «Диск»:

Футер с AI статусом

Источник — server_load_api возвращает ai_status из IntegrationStatusCache (последний результат теста Claude) + ai_messages_today (cached 5 мин). Возможные значения:

ЗнакЗначение
✓ AIClaude доступен (последний тест успешен)
✗ AIClaude отвечает с ошибкой
⏸ AIAI отключён в настройках
? AIНе настроен или ещё не тестировался

Если в системе зафиксированы AI-ответы за сегодня — отображается «✓ AI: 12 сегодня». Tooltip показывает текст последнего теста.

Batch-тест всех интеграций

Кнопка «Проверить все» на Обзоре прогоняет последовательно все настроенные интеграции и выдаёт сводный отчёт:

Batch-тест: все интеграции зелёные

Каждый тест получает зелёную/красную иконку, сообщение endpoint'а, обновление last-test в таблице ниже. Пропущенные «Не настроено»-интеграции выводятся в финальной строке summary.

Info-иконки

Каждый функциональный блок (карточка) имеет контурную серую info-иконку сразу после названия — клик открывает соответствующий раздел документации в новой вкладке. Реализовано через relocateInfoIcons() JS-функцию + MutationObserver для динамически добавленных блоков.

Test endpoints (для разработки)

SlugEndpointЧто проверяет
telegramPOST /admin/settings/telegram/test/Bot token через getMe, опционально через прокси
telegram_proxyPOST /admin/settings/telegram/proxy_test/SOCKS5 прокси соединение с api.telegram.org
telegram_alarmPOST /admin/settings/telegram/alarm_test/Отправка тестового аларма в чат
freescoutPOST /admin/settings/freescout/test/API-ключ + хост + список conversations
freescout_dbPOST /admin/settings/freescout/db_test/MySQL соединение к БД FreeScout
aidaPOST /admin/settings/aida/test/HTTP GET /health на AIDA URL
claudePOST /admin/settings/claude/test/Anthropic API /v1/messages (через прокси)
tvipPOST /admin/settings/tvip/test/TvipClient через /api/provider/accounts
lfstreamPOST /admin/settings/lfstream/test/LfstreamClient через CMS-логин + /candidates/
gcsPOST /admin/settings/gcs/test/list_blobs с object-level permission
address_apiPOST /admin/settings/integrations/dadata_test/DaData API token + лимиты
status_jsonGET /admin/settings/integrations/status_json/Все статусы (для auto-poll бейджей)

JSON-формат ответа у всех test endpoints:

{
  "ok": true|false,
  "message": "Подключено. Тикетов: 50",  // human-readable
  "diag": {  // опционально, для модалки расширенной диагностики
    "url": "https://...",
    "http_status": 200,
    "latency_ms": 145,
    "body_preview": "..."
  }
}

История изменений

BuildДатаИзменения
4322026-04-25Sprint 1: статус-бейджи на вкладках, history теста, sticky-save (Telegram)
4632026-05-06Sprint A: integration_tester.js, кнопка «Проверить все», auto-refresh
4642026-05-06GCS test fix (object-level permission через list_blobs)
4652026-05-06Реструктуризация: TVIP+LFStream→IPTV, Адреса+Карта→География, Claude→FreeScout (variant A); AI в футере
4662026-05-06LFStream/TVIP test через production-клиенты; fallback на settings; контурные серые info-иконки рядом с названиями блоков

Дизайн-система ЛК v489 — выравнивание со стилем админки

Содержание раздела

Build 489 переводит весь Личный Кабинет на единую дизайн-систему с админкой биллинга. До этого ЛК использовал собственный teal-брендинг #5BA89D и отдельный набор CSS-переменных (--lk-*) — это создавало визуальный разрыв при переключении между ЛК и админкой.

Токены дизайн-системы

В lk/templates/lk/base.html :root теперь содержит полный набор токенов админки (theme-smit.css):

КатегорияТокеныИсточник правды
Brand--brand-primary #43b77a, --brand-primary-dark, --brand-primary-bgСовпадает с админкой
Status--smit-state-{ok,warn,danger,info,muted}Скопировано из админки
Surface--surface-page #f5f6f8, --surface-card #fff, --surface-mutedСкопировано из админки
Border--border-subtle, --border-defaultСкопировано из админки
Text--text-primary, --text-secondary, --text-mutedСкопировано из админки
Radii--radius-{xs,sm,md,lg,pill} (3/4/6/8/999)Скопировано из админки
Shadows--shadow-{sm,md,lg}Скопировано из админки
Spacing 8-pt--space-{1..6} (4/8/12/16/24/32)Скопировано из админки
Focus--focus-ring rgba(67,183,122,.30), --focus-outline #43b77aСкопировано из админки
Backwards-compat--lk-bg, --lk-card-bg, --lk-text, --lk-muted, --lk-borderАлиасы на новые токены — старый код не сломан

Для dark-темы ([data-bs-theme="dark"]) переопределены: surface, border, text, shadow — те же значения что в админском body.dark-theme.

Hero-карточки на всех ключевых страницах

Введён единый класс .lk-hero-card (lk/static/lk/css/lk-hero.css, ~190 строк) — gradient-карточка с иконкой/аватаром, title+meta+actions. Используется на:

Мобильная версия

В base.html добавлена секция @media (max-width: 767px):

Hero-карточки на mobile (@media (max-width: 767px)):

Скриншоты

12 скриншотов (6 страниц × desktop+mobile) сохранены в docs/img/v489_lk/:

СтраницаDesktop (1440×900)Mobile (390×844, iOS UA)
Дашбордdashboard_desktop.pngdashboard_mobile.png
Профильprofile_desktop.pngprofile_mobile.png
ОПpromise_pay_desktop.pngpromise_pay_mobile.png
Платежиpayments_desktop.pngpayments_mobile.png
Тарифtariff_desktop.pngtariff_mobile.png
Speedtestspeedtest_desktop.pngspeedtest_mobile.png

История доработок ЛК (builds 484-489)

BuildДатаЧто изменилось
4842026-05-07Hero-карточка /lk/tariff/: все параметры текущего тарифа, фильтрация доступных по allow_change_to + transfer_only_more_money + usluga_range_type; чипы delta-price; empty-state с support-ссылкой
4852026-05-07Fix _get_address(): использовался несуществующий home.city_name вместо home.city → адрес «Не указан». Унифицирован через template-фильтр home_city_street()
4862026-05-07Speedtest: при NETWORK_MODE=external или VPN — кнопка disabled с иконкой 🚫 и tooltip; убран confirm() dialog
4872026-05-07E1 mobile_api проверен (баг отсутствует, использует home_city_street) + _get_address унифицирован. E2 hero-карточка тарифа на дашборде: description, speed_in/out, линейка, upgrade_count. E3 inline-edit email/SMS вместо read-only
4882026-05-07F-prep lk-hero.css: 4 chip-цвета (success/warning/danger/info), dark-mode, mobile-адаптив. F1 hero /lk/profile/. F2 hero /lk/promise-pay/ с countdown. F3 hero /lk/payments/ с last/next
4892026-05-07Brand #5BA89D#43b77a (выравнивание с админкой). Полный набор токенов админки в :root. Mobile-секция в base.html: ≥44px touch, 16px inputs, safe-area. card-stat/buttons/focus-states выровнены

Страницы Личного Кабинета

Содержание раздела

Что видит абонент на каждой странице ЛК и какие действия ему доступны.

Дашборд (/lk/)

Главная страница ЛК — сводный обзор состояния аккаунта.

Профиль (/lk/profile/)

Управление контактными данными и привязками.

Пополнение баланса (/lk/payments/pay/)

Форма для онлайн-оплаты услуг.

История платежей (/lk/payments/)

Список финансовых операций абонента.

История операций (/lk/audit/)

Подробный аудит начислений и списаний за последний год.

Обещанный платёж (/lk/promise-pay/)

Управление услугой временного кредитования.

Подключения (/lk/sessions/)

История RADIUS-сессий абонента.

Тест скорости (/lk/speedtest/)

Замер фактической скорости интернета через Cloudflare Speed.

Сообщения (/lk/messages/)

Рассылки и системные уведомления от оператора.

Тарифы (/lk/tariff/)

Просмотр текущего тарифа и смена на другой.

Услуги (/lk/services/)

Подключение/отключение дополнительных услуг.

Реферальная программа (/lk/referral/)

Приглашение друзей с бонусом за подключение.

Добровольная блокировка (/lk/block/)

Временная приостановка услуг на период отъезда.

Поддержка (/lk/support/)

Список обращений в техподдержку через FreeScout.

Заполнение контактов (/lk/profile/contacts-required/)

Принудительный сценарий заполнения контактов при первом входе в ЛК (если включён в настройках).

Иллюстрации страниц:

Дашборд История платежей Профиль Тарифы