# PRODUCTION CHECKLIST: VPBX -> Bitrix24

Этот документ нужен для простой и безопасной эксплуатации интеграции VPBX -> Bitrix24 в production.

Документ написан простым языком. Все секреты здесь указываются только как плейсхолдеры:

- `ADMIN_API_KEY`
- `VPBX_WEBHOOK_SECRET`

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

## 1. Что делает приложение

Приложение принимает события о звонках из VPBX и обрабатывает их дальше для Bitrix24.

По рабочей логике сервис делает следующее:

- принимает события звонков из VPBX через webhook;
- сохраняет событие и данные звонка локально;
- ищет контакт в Bitrix24 по номеру телефона, а если контакта нет, создаёт его;
- ищет открытую сделку по этому контакту и переиспользует её, если она уже есть;
- если открытой сделки нет, создаёт новую сделку;
- создаёт нативные звонковые активности Bitrix24 через telephony API;
- обновляет тему звонковой активности, чтобы в ленте было понятно, что это был за звонок;
- прикрепляет запись звонка в Bitrix24, если запись у звонка есть;
- автоматически продлевает подписку VPBX на webhook, если это включено настройками;
- удаляет локальную копию записи после успешной загрузки в Bitrix24, если это включено настройками;
- умеет отдельно чистить старые локальные файлы записей по TTL.

Если сказать совсем просто: сервис соединяет VPBX и Bitrix24 так, чтобы звонок попадал в CRM как нормальная сущность со звонковой активностью, контактом, сделкой и записью разговора.

## 2. Где находится приложение

Основные production-параметры:

- путь к проекту: `/var/www/html/VPBXBeeline`
- имя процесса в PM2: `VPBXBeeline`
- локальный порт приложения: `3010`
- публичный домен: `https://vpbx.n-e.kz`
- webhook path: `/vpbx/webhook`

Полный production webhook URL должен выглядеть так:

```text
https://vpbx.n-e.kz/vpbx/webhook?secret=VPBX_WEBHOOK_SECRET
```

Важно: в реальной жизни вместо `VPBX_WEBHOOK_SECRET` будет настоящее секретное значение, но его нельзя вставлять в документы, чаты, тикеты и скриншоты.

## 3. Важные переменные `.env`

Ниже перечислены важные переменные окружения и их смысл. Здесь нет и не должно быть реальных значений.

### База и Bitrix24

- `DATABASE_URL`
  Строка подключения к PostgreSQL. Без неё приложение не стартует.

- `BITRIX_WEBHOOK_URL`
  Базовый URL входящего REST webhook Bitrix24. Через него сервис создаёт контакты, сделки, активности и загружает данные в CRM.

- `BITRIX_DEFAULT_TELEPHONY_USER_ID`
  Bitrix ID пользователя, который используется как telephony user по умолчанию для входящих звонков, когда звонок пришёл на общий номер или конкретный менеджер не определился.
  Сейчас это должен быть ID пользователя Call-центр, например `593`.

- `BITRIX_DEFAULT_ASSIGNED_BY_ID`
  Bitrix ID ответственного по умолчанию, если не сработало правило по номеру и не удалось определить конкретного сотрудника.

- `BITRIX_RECORDS_FOLDER_ID`
  ID папки Bitrix Disk, куда загружаются записи звонков.

### Защита доступа

- `ADMIN_API_KEY`
  Секретный ключ для всех маршрутов `/admin/*`.
  Без него admin endpoints должны отдавать `401 Unauthorized`.

- `VPBX_WEBHOOK_SECRET`
  Секрет для маршрута `/vpbx/webhook`.
  VPBX должен отправлять этот secret в query string или в заголовке `X-VPBX-Webhook-Secret`.
  Без него production webhook должен отдавать `401 Unauthorized webhook`.

### Автоматическая логика по сделкам и записям

- `AUTO_CREATE_DEALS`
  Если `true`, после получения webhook приложение автоматически запускает создание или переиспользование сущностей в Bitrix24.

- `AUTO_UPLOAD_RECORDS`
  Если `true`, запись звонка автоматически скачивается и прикрепляется к звонку в Bitrix24.

- `DELETE_LOCAL_RECORD_AFTER_ATTACH`
  Если `true`, локальный аудиофайл удаляется после успешного прикрепления записи к звонку в Bitrix24.

- `RECORDS_CLEANUP_ENABLED`
  Если `true`, разрешена ручная и фоновая очистка старых локальных аудиофайлов.

### Настройки VPBX

- `VPBX_BASE_URL`
  Базовый URL API VPBX. Если переменная не задана, код использует стандартный URL Beeline Cloud PBX.

- `VPBX_PROFILE_ID`
  ID профиля VPBX, для которого оформляется подписка и делаются запросы в API.

- `VPBX_WEBHOOK_URL`
  URL, который приложение регистрирует в VPBX как адрес для доставки событий. В production это должен быть публичный URL с `secret`.

- `VPBX_API_TOKEN`
  Токен доступа к API VPBX. Нужен для подписки, продления подписки и работы с записями звонков.

- `VPBX_SUBSCRIPTION_AUTO_RENEW`
  Если `true`, сервис автоматически продлевает подписку VPBX по таймеру.

- `VPBX_SUBSCRIPTION_RENEW_INTERVAL_MS`
  Интервал автопродления в миллисекундах.

### Важные пояснения

- `ADMIN_API_KEY` нужен для всех маршрутов `/admin/*`.
- `VPBX_WEBHOOK_SECRET` нужен для `/vpbx/webhook`.
- `BITRIX_DEFAULT_TELEPHONY_USER_ID` сейчас должен указывать на пользователя Call-центр, например `593`.
- В этот документ нельзя вставлять реальные секреты, токены и полный рабочий webhook URL с настоящим `secret`.

## 4. Быстрая проверка сервиса

Основные команды:

```bash
cd /var/www/html/VPBXBeeline
pm2 list
curl http://127.0.0.1:3010/health
```

Что проверять:

- в `pm2 list` процесс `VPBXBeeline` должен быть в статусе `online`;
- `curl` на `/health` должен вернуть JSON;
- поле `ok` должно быть `true`;
- поле `db` должно быть `ok`;
- поле `security.adminApiKeyConfigured` должно быть `true`;
- поле `security.vpbxWebhookSecretConfigured` должно быть `true`.

Пример того, что считается нормальным ответом:

```json
{
  "ok": true,
  "service": "VPBXBeeline",
  "db": "ok",
  "security": {
    "adminApiKeyConfigured": true,
    "vpbxWebhookSecretConfigured": true
  }
}
```

Если `ok=false` или `db=error`, значит сервис жив, но не может нормально работать с базой.

Если `adminApiKeyConfigured=false` или `vpbxWebhookSecretConfigured=false`, значит security-настройка не завершена.

## 5. Проверка admin endpoints

Проверка с правильным ключом:

```bash
curl -H "X-Admin-Key: ADMIN_API_KEY" \
  "http://127.0.0.1:3010/admin/calls/recent?limit=5"
```

Проверка без ключа:

```bash
curl -i \
  "http://127.0.0.1:3010/admin/calls/recent?limit=5"
```

Что должно быть:

- без заголовка `X-Admin-Key` должен быть ответ `401`;
- с правильным `X-Admin-Key` должен быть ответ `200`;
- в успешном ответе должен прийти JSON с `ok: true` и списком звонков.

Смысл проверки простой: admin-маршруты не должны быть доступны посторонним.

## 6. Проверка webhook

Проверка без secret:

```bash
curl -i -X POST \
  "http://127.0.0.1:3010/vpbx/webhook" \
  -H "Content-Type: application/json" \
  -d '{}'
```

Проверка с secret:

```bash
curl -i -X POST \
  "http://127.0.0.1:3010/vpbx/webhook?secret=VPBX_WEBHOOK_SECRET" \
  -H "Content-Type: application/json" \
  -d '{}'
```

Что должно быть:

- без secret должен быть `401`;
- с правильным secret должен быть `200`;
- в успешном ответе обычно будет JSON с `ok: true` и `received: true`.

Важно: в production webhook проверяет secret либо в query string, либо в заголовке `X-VPBX-Webhook-Secret`. Для эксплуатационной проверки обычно проще использовать query string с плейсхолдером.

## 7. Проверка подписки VPBX

Команда:

```bash
curl -H "X-Admin-Key: ADMIN_API_KEY" \
  "http://127.0.0.1:3010/admin/vpbx/subscriptions"
```

Что проверять в свежей подписке:

- статус должен быть `ACTIVE`;
- `uri` должен быть вида `https://vpbx.n-e.kz/vpbx/webhook?secret=...`;
- `expires_at` должен быть в будущем;
- у актуальной подписки должен быть правильный публичный адрес именно с `secret`.

Если в списке есть старая подписка без secret:

- это не критично прямо сейчас;
- она безопасно отвалится, потому что `/vpbx/webhook` без secret возвращает `401`;
- но такую старую подписку лучше позже удалить или отписать, чтобы VPBX не слал лишние запросы в неверный URL.

## 8. Smoke-тесты

Ниже минимальный набор сценариев, который стоит проверить после релиза, правок в правилах маршрутизации или проблем с интеграцией.

### 1. Входящий на групповой принят

Проверить:

- сделка создана или переиспользована корректно;
- ответственный у новой сделки назначился правильно;
- в Bitrix есть звонковая активность;
- `subject` активности читаемый, например в стиле "входящий звонок принят";
- запись прикрепилась, если разговор записывался;
- локальный файл удалён после attach, если включено удаление локальных копий.

### 2. Входящий на групповой пропущен

Проверить:

- сделка создана или переиспользована корректно;
- новая сделка уходит на Call-центр, если это общий номер;
- в Bitrix есть звонковая активность именно по пропущенному звонку;
- `subject` активности понятный, чтобы менеджер видел, что звонок был пропущен;
- запись прикрепилась, если у такого сценария есть запись;
- локальный файл удалён после attach.

### 3. Входящий на номер конкретного менеджера

Проверить:

- сделка создана или переиспользована корректно;
- новая сделка назначилась именно на этого менеджера;
- в Bitrix есть звонковая активность;
- `subject` активности понятный;
- запись прикрепилась, если была;
- локальный файл удалён после attach.

### 4. Исходящий успешный

Проверить:

- сделка создана или переиспользована корректно;
- ответственный правильный;
- звонковая активность есть;
- `subject` показывает, что исходящий звонок был успешным;
- запись прикрепилась, если запись велась;
- локальный файл удалён после attach.

### 5. Исходящий занято/сброс

Проверить:

- сделка создана или переиспользована корректно;
- ответственный правильный;
- звонковая активность есть;
- `subject` показывает, что это был занято/сброс или безуспешный звонок;
- запись прикрепилась, если запись была;
- локальный файл удалён после attach.

### 6. Повторный звонок клиента

Проверить:

- если у контакта уже есть открытая сделка, сервис должен переиспользовать её;
- новая лишняя сделка не должна создаваться без необходимости;
- ответственный у уже существующей открытой сделки не должен самопроизвольно меняться;
- звонковая активность должна появиться по новому звонку;
- запись должна прикрепиться, если она есть;
- локальный файл должен удалиться после attach.

## 9. Правила ответственных

Это одна из самых важных частей интеграции.

Логика такая:

- если звонок пришёл на групповой или рекламный номер, новая сделка создаётся на Call-центр;
- если звонок пришёл на номер конкретного менеджера, новая сделка создаётся на этого менеджера;
- если открытая сделка уже существует, сервис переиспользует её;
- при переиспользовании открытой сделки ответственный у этой сделки не меняется;
- создатель сделки в Bitrix может быть `Admin 53`, потому что REST webhook создан от него, и это нормально;
- ответственный и создатель сделки в Bitrix24 это разные поля.

Важно понимать разницу:

- "кто создал сделку" зависит от того, от чьего webhook работает интеграция;
- "кто ответственный" зависит от логики маршрутизации и правил назначения.

## 10. Что делать, если звонки не приходят

Проверять по порядку:

```bash
cd /var/www/html/VPBXBeeline
pm2 list
curl http://127.0.0.1:3010/health
curl -H "X-Admin-Key: ADMIN_API_KEY" \
  "http://127.0.0.1:3010/admin/vpbx/subscriptions"
pm2 logs VPBXBeeline --lines 100 --nostream
```

Что смотреть:

- процесс `VPBXBeeline` должен быть `online`;
- `/health` должен показывать `ok: true` и `db: ok`;
- в подписках VPBX должна быть актуальная активная запись;
- у подписки должен быть правильный webhook URL с `secret`;
- в логах не должно быть ошибок про `Unauthorized webhook`, ошибки VPBX API, ошибки Bitrix API или проблемы с базой.

Практический смысл такой:

- если процесс не запущен, webhook просто некому принимать;
- если база недоступна, событие может не сохраниться;
- если подписка VPBX указывает на старый URL, звонки уйдут не туда;
- если secret в webhook не совпадает, сервер будет отдавать `401`.

## 11. Что делать, если сделка не создалась

Сначала посмотреть последние звонки:

```bash
curl -H "X-Admin-Key: ADMIN_API_KEY" \
  "http://127.0.0.1:3010/admin/calls/recent?limit=10"
```

В ответе проверить поля:

- `bitrix_status`
- `error_text`
- `client_phone`
- `bitrix_contact_id`
- `bitrix_deal_id`

Как читать эти поля:

- если нет `client_phone`, CRM нечего искать по номеру;
- если нет `bitrix_contact_id`, возможно контакт не нашёлся и не создался;
- если нет `bitrix_deal_id`, сделка не была создана или не была переиспользована;
- `bitrix_status` показывает, на каком этапе остановилась обработка;
- `error_text` обычно содержит самое полезное короткое объяснение причины.

## 12. Что делать, если запись не прикрепилась

Сначала посмотреть звонок через:

```bash
curl -H "X-Admin-Key: ADMIN_API_KEY" \
  "http://127.0.0.1:3010/admin/calls/recent?limit=10"
```

Проверять поля:

- `record_status`
- `bitrix_call_id`
- `bitrix_record_file_id`
- `bitrix_record_attached_at`
- `error_text`

Как понимать результат:

- если нет `bitrix_call_id`, звонок не зарегистрирован в Bitrix Telephony, и attach записи некуда делать;
- если `record_status=error`, надо смотреть `error_text`;
- если `bitrix_record_file_id` пустой, запись в Bitrix не прикрепилась;
- если `bitrix_record_attached_at` пустой, успешного attach ещё не было.

Полезные команды для ручного восстановления:

```bash
curl -H "X-Admin-Key: ADMIN_API_KEY" -X POST \
  "http://127.0.0.1:3010/admin/calls/CALL_UUID/redownload-record"
```

```bash
curl -H "X-Admin-Key: ADMIN_API_KEY" -X POST \
  "http://127.0.0.1:3010/admin/calls/CALL_UUID/process-record"
```

Как использовать:

- `redownload-record` заново скачивает запись из VPBX;
- `process-record` пытается прикрепить запись к звонку в Bitrix24;
- вместо `CALL_UUID` нужно подставить UUID нужного звонка.

## 13. Что делать, если ответственный неправильный

Нужные маршруты:

```bash
curl -H "X-Admin-Key: ADMIN_API_KEY" \
  "http://127.0.0.1:3010/admin/source-rules"
```

```bash
curl -H "X-Admin-Key: ADMIN_API_KEY" \
  "http://127.0.0.1:3010/admin/calls/CALL_UUID/deal-assignment-preview"
```

```bash
curl -H "X-Admin-Key: ADMIN_API_KEY" \
  "http://127.0.0.1:3010/admin/calls/CALL_UUID/deal-debug"
```

Что смотреть:

- для группового номера source-rule должен указывать `bitrix_assigned_by_id=593`;
- для конкретного менеджера `deal-assignment-preview` должен показывать причину `employee_user`, если менеджер определён напрямую;
- если есть source-rule для рекламного или группового номера, приоритет обычно будет у этого правила;
- в `deal-debug` можно сравнить ожидаемого и фактического ответственного.

На что обратить внимание:

- `source-rules` отвечают за привязку номера линии к источнику, воронке, стадии и ответственному;
- `deal-assignment-preview` показывает, кого сервис собирается назначить до создания сделки;
- `deal-debug` помогает понять, что ожидалось и что реально получилось в Bitrix.

## 14. Проверка локальных записей

Команды:

```bash
curl -H "X-Admin-Key: ADMIN_API_KEY" \
  "http://127.0.0.1:3010/admin/records/local-stats"
```

```bash
curl -H "X-Admin-Key: ADMIN_API_KEY" -X POST \
  "http://127.0.0.1:3010/admin/records/cleanup"
```

Что это значит:

- после успешной загрузки записи в Bitrix локальный файл должен удаляться, если включён `DELETE_LOCAL_RECORD_AFTER_ATTACH=true`;
- статистика `local-stats` показывает, сколько локальных файлов сейчас осталось;
- cleanup удаляет старые локальные аудиофайлы, если включён `RECORDS_CLEANUP_ENABLED=true`;
- старые `failed` или `debug` файлы должны со временем чиститься по TTL.

Если локальных файлов слишком много, это обычно значит одно из двух:

- записи не доходят до Bitrix;
- автоматическая очистка выключена или не срабатывает.

## 15. Безопасность

Основные правила:

- не показывать `ADMIN_API_KEY`;
- не показывать `VPBX_WEBHOOK_SECRET`;
- не отправлять скриншоты с полным webhook URL, если в нём есть `secret`;
- не вставлять реальные секреты в документы, задачи, переписки и shell history;
- если `secret` засветился, его надо поменять в `.env` и заново подписать VPBX на новый webhook URL.

Отдельно важно:

- `/admin/*` даёт доступ к служебным данным и отладке;
- `/vpbx/webhook` должен принимать только доверенные запросы от VPBX с правильным secret;
- даже внутренние скриншоты и видео лучше делать без секретов на экране.

## 16. Команды перезапуска

Если нужен аккуратный перезапуск процесса:

```bash
cd /var/www/html/VPBXBeeline
pm2 restart VPBXBeeline --update-env
sleep 3
curl http://127.0.0.1:3010/health
```

После перезапуска обязательно проверить:

- процесс снова `online`;
- `/health` снова отвечает;
- `ok=true`;
- `db=ok`.

Важно: `pm2 restart` допустим, а `pm2 restart` других приложений трогать не нужно.

## 17. Что НЕ делать

- не запускать `apt install` без явной необходимости;
- не трогать другие PM2 приложения;
- не менять Apache без бэкапа;
- не удалять БД;
- не публиковать `.env`;
- не удалять `source-rules` без понимания, зачем они были созданы.

Дополнительный практический смысл этих ограничений:

- эта интеграция зависит не только от Node.js-кода, но и от базы, маршрутизации, внешних API и production-конфигурации;
- лишние "починки" на сервере часто ломают соседние сервисы;
- удаление правил маршрутизации почти всегда приводит к неправильным ответственным, источникам и воронкам.
