# Установка и обслуживание ## Подключения и запуск `HOCKEY_DATABASE_URL` — удалённая PostgreSQL с хоккейными данными и сессиями. `WFL_DATABASE_URL` — база аккаунтов для авторизации; приложению нужен доступ чтения соответствующих учётных записей. Производственный режим не использует SQLite. Перед запуском выполните `python check_remote_database.py`. Основные параметры окружения: ```env HOCKEY_DATABASE_URL=postgresql+psycopg://USER:PASSWORD@HOST:5432/hockey WFL_DATABASE_URL=postgresql+psycopg://USER:PASSWORD@HOST:5432/wfl HOCKEY_AUTH_MODE=wfl STAT2TV_LOGIN=... STAT2TV_PASSWORD=... ``` Stat2TV также может использовать существующий локальный файл credentials. Не заменяйте реальные секреты значениями из примера. Для HTTPS используйте соответствующую настройку secure-cookie и прокси с поддержкой WebSocket. Штатная команда сервера — `python -m uvicorn app:app --host 0.0.0.0 --port 8000`. Используйте один worker без `--reload`: назначения Agent, WebSocket и очереди живут в памяти процесса. Увеличение workers требует отдельного общего брокера состояния. `GET /api/health` — публичная проверка процесса, не проверка всей цепочки до vMix. `/api/hockey/database/status` проверяет подключение БД и может требовать авторизацию. Для существующего Linux-сервиса основной скрипт — `deploy_hockey.sh`; `deploy.sh` оставлен совместимым коротким входом. Перед использованием проверьте в скрипте адрес репозитория, каталог, имя сервиса и путь environment-файла. ## Обновление и восстановление В BUILD200 обновляются сервер и веб-интерфейс. Agent 1.5.6 остаётся прежним. После установки перезапустите сервер и перезагрузите операторские вкладки через Ctrl+F5. Проверьте F2, выключенное разрешение плашек нового матча, 2+4 минуты на разных сторонах и гол большинства с малым/двойным малым штрафом. 1. Остановите эфирные команды/службу в согласованное окно. 2. Сохраните копию проекта и резервную копию PostgreSQL. 3. Сохраните `.env`, `settings/local/` или внешний `HOCKEY_UI_DATA_DIR`, локальные credentials/PIN, настройки mapping, `agent/agent_config.json`, `khl_site/data/` и пользовательские материалы. 4. Замените код, установите зависимости, проверьте БД, затем запустите сервис. 5. Проверьте авторизацию, два независимых матча, зрителя, Agent и титры vMix. Обновление кода не требует сброса пользовательских настроек. Root-файлы `settings/ui_builder_*.json` — начальные значения для миграции, а не активный UI. Действующие настройки находятся в `settings/local/` либо абсолютном каталоге `HOCKEY_UI_DATA_DIR`. Перед сменой этого каталога остановите сервер и перенесите туда содержимое текущего рабочего каталога настроек. Для BUILD190 обязательно повторите установку `python -m pip install -r requirements.txt`: добавлена база часовых поясов `tzdata` для Windows. Для ускоренной отправки Mapping в BUILD194 обновите также Windows Agent до **1.5.5**: закройте его через tray → «Выход», замените `agent.exe` из пакета и запустите снова. Сохраните существующий `agent_config.json`. Версия видна в окне Agent; прежний Agent продолжит работать с ограниченными пакетами. Зависимости Python с BUILD193 не изменились. Три целочисленных поля публикации Mapping добавляются существующим механизмом миграции схемы. После запуска проверьте `/api/health`: версия `2026.11.05.1`. BUILD195 исправляет HTTP 500 при применении конфига с новым Agent: обёртка журнала теперь передаёт параметры проверки подключения и поколения в отправитель. Обновление устанавливается на сервер с последующим перезапуском службы. Windows Agent 1.5.5 совместим с этой сборкой. BUILD196 исправляет сохранение работающих таймеров, смену большинства и загрузку составов; добавляет задержку связанных плашек. Установите накопительный update ZIP и перезапустите сервер. Значения задержек вводятся в интерфейсе и сохраняются в существующих конфигурациях; их файлы обновлением не заменяются. BUILD197 отправляет Mapping после загрузки составов обеих команд и обновляет его при последующих изменениях состава. Окно загрузки показывает реальные этапы, ожидает подтверждение Agent и предлагает продолжить работу при задержке/отсутствии данных. Через 45 с показывается предупреждение; отправка Mapping не прерывается и не запускается повторно из-за этого срока. Дополнительных настроек не требуется. BUILD198 исправляет взаимодействие выбора управления с окном загрузки, порядок текста/IN, снятие связанных плашек и общую задержку одного Input/Overlay. Обновите сервер и Agent до **1.5.6**: остановите Agent, замените EXE, сохранив `agent_config.json`, затем запустите его и перезапустите сервер. Старый Agent сохраняет совместимость, но новую срочную очередь поддерживает версия 1.5.6. В режиме зрителя работает DATA/Mapping своему разрешённому Agent; команды управления матчем и эфиром требуют оператора. Чужой занятый Agent не переназначается. Для разбора задержки откройте журнал, раздел `vmix`, событие `command.latency`: один `trace_id` связывает ожидание в браузере, подготовку, отправку и ответ Agent. Для обновления существующей VM используйте пакет только изменённых файлов; полный архив содержит снимок настроек из присланной копии и предназначен для восстановления/новой установки. Не заменяйте им более свежие настройки эфира. Для каждой новой сборки добавляйте в CHANGELOG.md и UPDATE.txt короткую строку `Commit: BUILD198 — что изменилось`, подставляя текущий номер BUILD. История UI сохраняется при реальном изменении конфигурации, максимум 40 копий на тип после сохранения. Старые backup-файлы переносятся один раз: служебный маркер `.ui_backups_migrated_v1.json` предотвращает их повторное появление после удаления. Черновик и опубликованная версия восстанавливаются отдельно через редактор. ## Хранение журнала По умолчанию журнал хранится в `logs/`, отдельно от PostgreSQL матчей и WFL. При необходимости задайте `HOCKEY_LOG_DIR` абсолютным путём к постоянному диску. Процессу службы нужны права на создание/запись файлов в этом каталоге. Файлы разделены по московским календарным месяцам. Хранятся текущий и предыдущий месяцы: в октябре — сентябрь и октябрь; с 1 ноября сентябрь удаляется. Очистка выполняется при старте и автоматически при смене даты, без перезапуска сервера. Старые файлы удаляются только внутри выделенного каталога журнала; произвольные файлы и символические ссылки не затрагиваются. Запись идёт через ограниченную очередь отдельным потоком, чтение и выгрузка — вне основного цикла HTTP/WebSocket. В журнале показаны счётчики очереди, потерь при перегрузке и ошибок чтения/записи. При ненулевых счётчиках проверьте доступное место, права каталога и нагрузку диска. Журнал не обещает сохранение каждой записи при аварии диска/принудительном завершении процесса. Доступ к просмотру и скачиванию требует аккаунта администратора. Время хранится в UTC, фильтры и отображение используют Europe/Moscow. Не открывайте сам каталог `logs/` через веб-сервер статических файлов. ## Скорость веб-интерфейса HTML и данные API всегда обновляются. Скрипты и стили с версией в URL кэшируются браузером; при изменении сборки/содержимого URL меняется. Ответы сжимаются GZip, если браузер поддерживает его. Reverse proxy должен сохранять Content-Encoding, Vary и Cache-Control; не задавайте общий публичный кэш для API. Независимые запросы запуска выполняются параллельно. Runtime не строит список всех полей для редактора на каждом live-обновлении, а несколько внешних обновлений данных в одном кадре объединяются в одну перерисовку. Движок таймеров и немедленные операторские команды продолжают работать отдельно. С BUILD192 массовые операции импорта входят в общий пул БД по одной; остальные ожидают асинхронно. Сетевые загрузки остаются параллельными. Размер общего пула не увеличивается: по умолчанию `HOCKEY_DB_WORKERS=8`. Для одновременного импорта и операторских запросов нужны хотя бы два worker и доступные соединения БД. При настроенном пределе один выполнение остаётся последовательным. В журнале выберите раздел `import`. Событие `import.queue_wait` показывает ожидание от 250 мс; `import.finished` — завершение операции с долгим ожиданием или выполнением от одной секунды; `import.failed` — ошибку. В деталях есть название операции, время очереди и длительность выполнения. Отмена запроса в очереди предотвращает запуск; уже начавшаяся транзакция завершается целиком. ## Безопасная очистка копии VM Остановите сервер и Agent. Сначала просмотрите план: ```bash python cleanup_project.py --dry-run ``` Применение: ```bash python cleanup_project.py --apply ``` Утилита удаляет только bytecode в известных пакетах, старый `agent.log.1`, проверенную старую неиспользуемую копию UI и резервные копии из `settings/backups/`, которые уже идентично перенесены в `settings/local/backups/` и имеют маркер миграции. Активный `agent.log`, `settings/local/`, секреты, конфигурация Agent и данные КХЛ не удаляются. Изменённая старая копия UI автоматически сохраняется. Исторические документы удаляются только при совпадении имени из allowlist и SHA-256 с копией в `docs/history.zip`. Изменённые пользователем старые инструкции сохраняются. Одинаковые старые XML заменяются жёсткими ссылками: их имена, байты и пути в БД сохраняются. Файлы снимков после этого следует считать неизменяемыми. Если файловая система не поддерживает hardlink, соответствующий шаг пропускается. ZIP-распаковка может снова создать отдельные копии; очистку можно повторить на VM. Новые XML сохраняются по hash, одинаковые данные не создают новые файлы. XML не удаляются по возрасту: на них ссылается история PostgreSQL. Для полного архивирования уникальных XML требуется отдельно согласованная политика БД. Автоматически чистятся только самостоятельные `*_games_discovery.json`: сохраняются минимум 40 последних, более старые удаляются после 30 дней. ## Проверки После обновления выполните целевые проверки mapping/прав/нескольких матчей и `python -m pytest tests/test_build190_mapping_delivery.py tests/test_mapping_publications.py tests/test_program_log.py tests/test_web_observability.py tests/test_storage_maintenance.py tests/test_stage1_match_access.py tests/test_stage2_ui_storage.py`. Полный набор для разработки: `python -m pytest -q` в отдельной тестовой копии. Дополнительно к зависимостям приложения нужны pytest и Node.js: проверки интерфейса исполняют настоящие функции JavaScript. Исторические тесты таймеров и интерфейса актуализированы в BUILD191; номера в именах файлов сохраняют историю появления. Живой vMix и рабочая PostgreSQL должны проверяться на отдельном прогоне перед эфиром. Совместную работу трёх матчей и шести Agents можно повторить командой `python tests/multi_match_harness.py --run --ticks 60 --fields 64 --phase-timeout 900 --output multi-match-result.json`. Без `--run` скрипт только показывает план. Он использует временную SQLite, локальные API и поддельные WebSocket, проверяет ACK, переподключение, медленный источник и передачу управления. Производительность PostgreSQL и настоящего vMix проверяется отдельно на рабочем оборудовании. Очередь импорта можно проверить командой `python tests/import_admission_harness.py --run --output import-admission-result.json`. Без `--run` выводится только план. Сценарий задерживает настоящий участок импорта до записи в временную SQLite и проверяет доступность управления тремя матчами, Mapping и шести Agents до снятия задержки. Внешние подключения блокируются.