Files
hockey_new/README.md

342 lines
26 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Hockey Stat2TV / UI Builder — BUILD 2026.07.20.13
## Базы данных
Проект использует две удалённые PostgreSQL-базы:
```text
WFL_DATABASE_URL → только чтение аккаунтов WFL для авторизации
HOCKEY_DATABASE_URL → все хоккейные данные и рабочие сессии
```
Локальная SQLite отключена. Файл `data/hockey.sqlite3` не создаётся и не
используется. Если `HOCKEY_DATABASE_URL` отсутствует, указывает не на
PostgreSQL или сервер недоступен, приложение прекращает запуск.
## Настройка
1. Создайте отдельную PostgreSQL-базу `hockey` рядом с WFL либо используйте уже
подготовленную удалённую базу.
2. Скопируйте `.env.example` в `.env`.
3. Укажите реальные строки подключения:
```env
HOCKEY_AUTH_MODE=wfl
WFL_DATABASE_URL=postgresql+psycopg://postgres:password@localhost:5432/wfl_db
HOCKEY_DATABASE_URL=postgresql+psycopg://postgres:password@localhost:5432/hockey
HOCKEY_COOKIE_SECURE=false
```
Подробная настройка прав: `REMOTE_DATABASE.md`.
## Запуск
```powershell
START.bat
```
Перед запуском интерфейса скрипт проверяет удалённую базу. При успешном
соединении выводится:
```text
[Hockey DB] PostgreSQL connection OK: server:5432/hockey
```
Проверка из браузера после запуска:
```text
http://127.0.0.1:8000/api/hockey/database/status
```
Ответ содержит безопасные сведения о подключении без логина и пароля:
```json
{
"ok": true,
"backend": "postgresql",
"host": "server",
"port": 5432,
"database": "hockey",
"remote_only": true
}
```
## Что хранится в удалённой hockey-базе
- турниры, расписание и матчи;
- счёт, периоды, ОТ/Б и арены;
- команды, игроки, тренеры, судьи и страны;
- составы и назначения судей;
- события и удаления;
- сезонная и турнирная статистика;
- `powerplay`, `rank`, `shots` и доступность необязательных ресурсов;
- операторские и веб-сессии;
- кэш полученных XML/JSON и история синхронизации.
Stat2TV остаётся внешним источником XML/JSON, а не базой приложения.
## Автоматическая схема
При первом запуске на пустой базе приложение создаёт таблицы автоматически.
При обновлении сборки оно добавляет отсутствующие неключевые поля. Пользователю
`hockey_app` необходимы права `CREATE`, `ALTER`, `SELECT`, `INSERT`, `UPDATE`,
`DELETE` и права на sequences в схеме базы.
## Интерфейс
Сборка включает загрузку матчей Stat2TV, отдельную информационную вкладку «Расписание», события, play-by-play, карты бросков,
матчевую и сезонную статистику, турнирные таблицы, большинство, рейтинг,
справочники игроков/тренеров/судей/стран, операторские события и vMix JSON.
## Расписание команд
Вкладка «Расписание» содержит два режима:
- «Матчи дня» — информационные карточки всех матчей выбранной лиги на текущую дату;
- «Матчи команд» — полный календарь команд текущего открытого матча: левая команда слева, правая справа.
В командном режиме доступны фильтры по статусу, месту проведения и сортировке. Очные матчи выбранных команд выделяются золотой рамкой и подписью «Очная встреча». Карточки остаются информационными и не открывают другой матч.
## Управление периодом и буллитами
В шапке выбранного матча доступен ручной выбор текущего периода. Состояние сохраняется в хоккейной PostgreSQL-базе.
Для турниров со стадией `regular` после вкладки «Игра» появляется вкладка «Буллиты». В ней можно выбрать основную серию на 3 или 5 попыток, назначать игроков обеих команд, отмечать гол/промах и при равном счёте добавлять дополнительные серии по одной попытке каждой команде.
## BUILD 2026.07.20.7
- Выпадающий список текущего периода больше не закрывается при обновлении таймера и фоновой синхронизации.
- В регулярном чемпионате доступны три периода, один овертайм, буллиты и завершение матча.
- В плей-офф буллиты скрыты и запрещены на сервере.
- Для плей-офф поддерживается неограниченная последовательность овертаймов: после выбора текущего овертайма автоматически появляется следующий.
- Старое значение `ot` в плей-офф автоматически преобразуется в `ot1`.
## BUILD 2026.07.20.7
Во вкладке «Буллиты» добавлен независимый быстрый поиск для левой и правой команды. Поиск фильтрует состав по номеру, фамилии и имени.
## BUILD 2026.07.20.8 — таймер и численные составы
В общих настройках Stat2TV добавлен раздел «Таймер матча»:
- длительность обычного периода;
- длительность овертайма регулярного чемпионата;
- длительность каждого овертайма плей-офф;
- автоматический сброс основного таймера при смене периода.
При смене периода сбрасывается только основной таймер. Активные удаления и журнал удалений сохраняются. Для нового матча используется длительность обычного периода.
Добавлен раздел «Удаления и численные составы»:
- базовый состав для основного времени, овертайма регулярки и овертайма плей-офф;
- минимальное количество полевых игроков;
- отдельный режим подписи для каждой фазы: `PP`, только состав (`5×4`, `4×3`) или `PP + состав`;
- настраиваемые подписи большинства и меньшинства;
- опциональное отображение `PK`.
По умолчанию основное время отображает `PP`, овертайм регулярки — фактический состав `4×3`, овертайм плей-офф — `PP`. Текущее численное соотношение и подписи также доступны в `scoreboard.json` и `penalties.json`.
## BUILD 2026.07.20.9 — видимые настройки таймеров
В административном окне «Настройки» появилась отдельная вкладка **«Таймеры и составы»**. В ней можно менять длительность обычного периода, овертайма регулярного чемпионата и каждого овертайма плей-офф, автоматический сброс времени при смене периода, базовые численные составы и правила подписей PP/PK. Значения сохраняются через общий `/api/hockey/settings` и применяются без перезапуска.
## BUILD 2026.07.20.10 — двуязычная матрица численных составов
В разделе **Шестерёнка → Таймеры и составы** добавлены отдельные RU/EN-подписи
для каждого численного состояния основного времени, овертайма регулярного
чемпионата и овертайма плей-офф.
Овертайм регулярки теперь учитывает совпадающие удаления без взаимного
погашения: одно удаление — 4×3, два удаления одной команды — 5×3, по одному
у каждой команды — 4×4, по два — 5×5.
## BUILD 2026.07.20.11 — мгновенное отображение численного состава
- Подготовленное удаление учитывается в численном составе сразу после выбора игрока/команды, нарушения и длительности.
- Запуск таймера удаления больше не требуется для появления `5×4`, `4×4`, `5×3`, `4×3` и настроенной RU/EN-подписи в верхнем счёте.
- Незавершённые заготовки без команды, нарушения или длительности в расчёт не попадают.
- Ответ сохранения таймеров немедленно передаётся в шапку матча без ожидания фонового опроса.
## BUILD 2026.07.20.12 — конструктор vMix JSON
Из проекта Golf перенесён переносимый модуль настроек vMix и адаптирован к хоккейным данным.
Откройте **Шестерёнка → vMix JSON**. В разделе доступны:
- отдельные JSON-пресеты для верхнего счёта, информации о матче, составов, судей, удалений, событий и полного матча;
- включение и перестановка колонок, изменение имени выходного поля и источника данных;
- вычисляемые колонки и формулы из библиотеки vMix;
- дополнительные объединяемые источники (`joins`);
- просмотр доступных полей выбранного хоккейного источника;
- предварительный просмотр результата для постоянного персонального канала vMix;
- импорт настроек из JSON или ZIP и экспорт текущих пресетов.
Адрес пользовательского JSON формируется для постоянного канала аккаунта и языка:
```text
/vmix/hockey/channel/{channel}/{language}/custom/{key}.json
```
Поддерживаемые источники: `info`, `scoreboard`, `home_lineup`, `away_lineup`,
`officials`, `penalties`, `events`, `full_match`.
Чтобы получить рабочую ссылку и список полей, сначала откройте матч. Канал создаётся
один раз для WFL-аккаунта и затем сохраняет тот же ключ при входе с другого браузера,
перезагрузке страницы и выборе нового матча. Настройки vMix хранятся в
`settings/vmix_json.json` отдельно от подключения Stat2TV. При импорте
гольф-проектов старые endpoint-адреса автоматически заменяются хоккейными, а
неподдерживаемые источники переводятся на `scoreboard` без удаления колонок.
## BUILD 2026.07.20.13 — постоянные персональные каналы vMix
- Ссылки vMix больше не зависят от временной операторской сессии.
- Для каждого WFL-аккаунта создаётся один постоянный случайный ключ канала.
- При выборе нового матча обновляется привязка канала, но URL в проекте vMix не меняется.
- Пользователь может переключать только канал своего аккаунта; чужой канал нельзя изменить через API.
- Логин не публикуется в URL и не используется как секрет.
- Для отдельных студий рекомендуется создать отдельные WFL-аккаунты: один аккаунт = один постоянный канал.
- Старые адреса `/vmix/hockey/session/...` оставлены как совместимые алиасы, чтобы существующие проекты не перестали читать данные.
Новый рекомендуемый формат:
```text
/vmix/hockey/channel/{channel}/{language}/custom/{key}.json
```
## vMix Agent Bridge (build 2026.08.11.4)
Новая схема подключения не требует логина внутри agent и не скачивает `.vmix` проект. Готовый Windows x64 agent находится в `agent/agent.exe`.
- agent регистрирует постоянный Device ID через `/ws/hockey-agent`;
- вошедший WFL-пользователь видит устройства в панели **vMix Agent** и прикрепляет своё;
- на аккаунт можно сохранить несколько устройств, но только одно является активным эфирным;
- при выборе следующего матча активный agent получает новый `assignment_id` + `match_id` без перезапуска vMix;
- после reconnect pairing и текущий матч восстанавливаются с сервера;
- команды vMix защищены проверкой текущих `assignment_id` и `match_id`;
- build `2026.08.11.4` добавляет первый реальный канал команд: тестовый `SetText` из web с ожиданием `command.ack` от agent и ответа локального vMix.
Подробности запуска: `agent/README.md`.
## Mapping Editor / Agent 1.3.0 — build 2026.08.12.1
- Agent 1.3.0 автоматически инвентаризирует текущий vMix: Inputs, key/number/type и GT-поля.
- Сервер сохраняет fingerprint и последнюю структуру проекта в PostgreSQL.
- Admin получил раздел `Настройки → Mapping`: создание профиля из активного Agent, редактирование связей, обновление структуры и удаление профиля.
- Оператор не может менять mapping; в панели vMix Agent он только видит активный профиль и его версию.
- Mapping привязан к fingerprint графического проекта, а не к матчу или устройству.
- При изменении mapping сервер немедленно отправляет `mapping.assigned` всем Agent с той же структурой vMix.
## Tournament drawer / schedule fallback — build 2026.08.12.2
- Исправлена grid-разметка вкладки «Все турниры»: summary больше не сжимается длинным списком, список скроллится только внутри drawer.
- Автоматический fallback расписания теперь после tournament-scoped файлов проверяет полный набор Stat2TV endpoint-форм, включая варианты с `tournament` и `date` query-параметрами.
- Источник `online.khl.ru` намеренно не скрапится: официальный сайт блокирует автоматические запросы и запрещает автоматизированное извлечение без разрешения.
## Build 2026.08.17.1 — Visual Mapping Editor
Mapping теперь настраивается визуально: admin выбирает vMix Input, затем конкретное GT-поле и связывает его с человеческим источником данных текущего матча. В редакторе одновременно показываются понятное название источника, его живое значение и технический data_key. Для связанного текстового/графического поля доступен безопасный тест через выбранный online Agent.
## Build 2026.08.17.2 — Context Variables + SQL Data Sources
Mapping Editor больше не зависит от захардкоженного списка data_key. В PostgreSQL добавлены:
- `hockey_mapping_context_variables` — определения системных и пользовательских идентификаторов;
- `hockey_mapping_context_values` — значения с изоляцией по account/session/match;
- `hockey_mapping_sql_sources` — admin-managed read-only SQL SELECT источники.
В `Настройки → Mapping` доступны вкладки `Связи vMix`, `Переменные`, `SQL источники`. Колонки SQL автоматически становятся ключами `source.column`, а текущие значения выбранного матча сразу видны в Visual Mapping Editor. SQL выполняется в read-only транзакции с коротким statement timeout на PostgreSQL.
### Build 2026.08.17.3
Разделы `Переменные` и `SQL источники` вынесены прямо в верхнее меню Настроек рядом с Mapping. Загрузка Mapping API стала отказоустойчивой: ошибка одного endpoint не скрывает остальные разделы.
### Build 2026.08.17.5
- SQL Data Source с несколькими строками теперь доступен в Mapping как полноценная таблица.
- Можно выбрать конкретную строку и конкретный столбец без изменения SQL-запроса.
- Ячейки получают внутренний адрес `source.row.N.column`; старый `source.column` сохранён и означает первую строку.
- Каталог Mapping читает до 250 строк каждого включённого SQL-источника в read-only режиме.
- В табличном picker есть поиск строки по любому значению.
- vMix Inputs сортируются по номеру Input, затем по названию.
- Добавлен быстрый поиск Input по номеру, названию, key и типу.
### Build 2026.08.17.6
- Mapping: для SQL-источника добавлен явный селектор `Источник → строка → столбец` с живым значением выбранной ячейки.
- Выбранную SQL-ячейку можно напрямую связать с текущим Text/Source полем vMix; технический ключ формируется автоматически.
- Кнопка `Тест` переименована в `Тест поля`, чтобы было понятно, что она отправляет только одну связь.
- Добавлена кнопка `Применить Input`, отправляющая все настроенные поля текущего Input, включая SQL-ячейки, одним batch-запросом.
- Кнопка общего применения переименована в `Применить весь Mapping`.
### Build 2026.08.17.7
- Исправлен SQL Preview в Mapping: кнопка «Проверить SQL» больше не заменяет несохранённый запрос дефолтным SELECT.
- Черновик формы SQL (код, название, категория, описание, SQL, enabled, sort order) сохраняется при Preview и при ошибке выполнения.
### Build 2026.08.17.11 — game date fallback from match details
- Если расписание выбранного матча не содержит дату, `game_date` заполняется из детальной карточки Stat2TV/KHL.
- Поддерживается локализованный формат вида `16 августа 2026, Вс 13:00:00`; в PostgreSQL он сохраняется как настоящий `DATE` (`2026-08-16`).
- Время `13:00` также извлекается из этой же строки, если отдельное поле времени отсутствует.
- Пустой date/time из последующего refresh расписания больше не стирает значение, уже восстановленное из карточки матча.
- Если в расписании дата есть, она остаётся приоритетной и detail fallback её не перезаписывает.
## Build 2026.08.17.12 — game_date recovery
- Localized KHL/Stat2TV dates such as `16 августа 2026, Вс` are normalized and stored in `hockey_games.game_date` as a real DATE (`2026-08-16`).
- Schedule upsert now recovers date/time from `start_datetime_raw` if parsed date/time are missing.
- Detail-card save performs a final recovery from the persisted raw datetime before commit.
- Startup backfill repairs existing rows where `game_date IS NULL` but `start_datetime_raw` contains a usable date.
- Unicode NBSP/thin spaces are normalized before date parsing.
## Build 2026.08.17.13 — SQL Auto Refresh → vMix
- SQL Data Source can now enable **Автообновление в vMix** and configure a refresh interval from 1 to 3600 seconds.
- Auto refresh runs server-side, so the Mapping admin page does not need to stay open.
- Only Mapping fields linked to the due SQL source are evaluated/sent.
- vMix commands are deduplicated: unchanged values are not sent again.
- Recommended: clocks = 1 s; live statistics = 25 s; standings/non-live data = 1060 s or manual.
- PostgreSQL time formats such as `TO_CHAR(NOW(), 'HH24:MI:SS')` no longer produce false context parameters (`:MI`, `:SS`). PostgreSQL casts such as `value::text` are also ignored by the context-parameter parser.
- SQL help now includes current-time and timezone examples.
## Build 2026.08.17.14
- SQL Source preview no longer hides rows after the first 8.
- Preview renders all rows returned by the server (up to 250) inside a scrollable table with a sticky header.
## Build 2026.08.17.15 — series Mapping
- SQL table picker in Mapping now has a real 230430 px result grid and scroll; rows are no longer visually squeezed below the controls.
- Linked SQL table cells expose `Автосвязать столбец`: one seed such as `Name1.Text ← roster.row.1.fio` expands to sequential GT fields and SQL rows.
- Added `Размножить строку`: configure all columns of one roster row once (for example number + fio), then clone that row pattern across the remaining SQL rows.
- Sequence detection is generic: it detects the strongest numeric token in GT field names rather than requiring a hard-coded `PlayerN` naming convention.
- A confirmation preview shows generated links before they are written into the unsaved Mapping profile.
## Build 2026.08.17.16 — Mapping field filters + fast vMix batch
- vMix Input fields in Mapping are split into three selectors: `Text` (`.Text`), `Image` (`.Source`) and `Color` (`.Color`).
- Added `Скрывать связанные` toggle for large GT titles.
- Mapping field kind now preserves `color` as a separate UI type while runtime uses the existing vMix text-value command path.
- New Agent 1.4.0 supports `vmix.batch`: the server sends the whole resolved Mapping in one WebSocket frame and receives one batch ACK.
- Agent executes independent local vMix HTTP commands with a small worker pool and a reusable keep-alive HTTP client.
- Server automatically falls back to legacy one-command-at-a-time transport for Agent < 1.4.0.
- Empty Mapping values now keep `Value=` in the vMix request, so generated empty roster rows can clear old title text.
- Match switch, language switch, full Mapping apply and `Применить Input` use batch transport when Agent 1.4.0 is connected.
## Нормализованная статистика — build 30
Добавлено отдельное SQL-хранение матчевой статистики команд, сезонной статистики игроков/команд, строк standings и powerplay/rank. Исходный RAW Stat2TV сохраняется. Подробности: `NORMALIZED_STATISTICS_DB.md`.
Проверка: `GET /api/hockey/database/statistics-status?tournament_id=<ID>`.