фикс 14

This commit is contained in:
2026-04-23 18:34:37 +03:00
parent 25bd34d94f
commit 2c7222260d
4 changed files with 686 additions and 145 deletions

831
README.md
View File

@@ -1,230 +1,771 @@
# ⚽ Match Management & vMix Integration System
# ⚽ VMIX Football Broadcast System
Полноценная система управления футбольными матчами с live-обновлением,
парсингом данных и интеграцией с vMix.
<p align="center">
<img src="https://img.shields.io/badge/Python-3.10%2B-3776AB?logo=python&logoColor=white" alt="Python">
<img src="https://img.shields.io/badge/FastAPI-0.115+-009688?logo=fastapi&logoColor=white" alt="FastAPI">
<img src="https://img.shields.io/badge/PostgreSQL-15+-4169E1?logo=postgresql&logoColor=white" alt="PostgreSQL">
<img src="https://img.shields.io/badge/WebSocket-Realtime-7C3AED" alt="WebSocket">
<img src="https://img.shields.io/badge/vMix-Integration-FF6A00" alt="vMix">
<img src="https://img.shields.io/badge/status-active-success" alt="Status">
</p>
------------------------------------------------------------------------
> Система управления футбольными трансляциями с интеграцией в **vMix**, админ-панелью, live-обновлением матчей, генерацией данных для графики и WebSocket-взаимодействием с операторскими клиентами.
# 📌 Описание
---
Проект состоит из нескольких ключевых частей:
## 📌 Что это за проект
- FastAPI сервер (админка + API)
- Scheduler (live-обновления матчей)
- Парсеры (игры, расписание, таблица)
- PostgreSQL база данных
- WebSocket сервер для vMix
Проект предназначен для подготовки и сопровождения футбольных трансляций. Он объединяет в одном приложении:
------------------------------------------------------------------------
- администрирование матчей, команд, игроков, тренеров, судей и стадионов;
- работу с составами и формациями на матч;
- генерацию данных для эфирной графики в vMix;
- создание и выгрузку `.vmix`-проекта;
- приём и отправку команд в vMix-клиенты через WebSocket;
- фоновое отслеживание матчей и обновление live-данных;
- синхронизацию расписания, игроков, команд и турнирной таблицы.
# 🧱 Архитектура системы
По текущей структуре проект ориентирован на внутреннюю production/операторскую эксплуатацию, а не на публичный API-сервис.
┌──────────────┐
│ Scheduler │
│ │
│ matches_loop │
│ standings │
└──────┬───────┘
┌──────────────┼──────────────┐
│ │ │
▼ ▼ ▼
live_match_worker parser_game parser_standings
Database
FastAPI
vMix
---
------------------------------------------------------------------------
## ✨ Основные возможности
# 🗄 Структура базы данных
### Админка и матч-центр
- авторизация администратора;
- список матчей и выбор матча для сессии;
- рабочее пространство матча;
- редактирование составов;
- редактирование формаций;
- управление судьями;
- управление событиями матча.
## Таблица: matches
### База футбольных сущностей
- игроки;
- команды;
- тренеры;
- судьи;
- стадионы;
- турнирная таблица;
- составы на матч;
- матчевые сессии для операторов.
Поле Тип Описание
------------- ----------- ----------------------
id int ID матча
external_id text ID матча на сайте
match_date timestamp дата и время
status text статус матча
home_score int счет хозяев
away_score int счет гостей
updated_at timestamp последнее обновление
### Интеграция с vMix
- генерация `.vmix`-проекта;
- формирование имени файла проекта;
- генерация JSON-данных для графики;
- публикация команд в подключённые vMix-клиенты;
- получение динамических значений из vMix API.
------------------------------------------------------------------------
### Live-логика
- планировщик, который отслеживает матчи дня;
- запуск watcher-потоков перед матчем;
- опрос live-данных каждые 60 секунд;
- обновление статуса матча и счёта;
- обновление турнирной таблицы.
## Таблица: standings
### Парсинг и синхронизация
- парсинг матчей;
- парсинг игроков;
- парсинг расписания;
- парсинг таблицы;
- синхронизация сущностей в БД через сервисный слой.
Поле Тип Описание
---------- ----- ----------
team_id int команда
position int позиция
points int очки
played int сыграно
---
------------------------------------------------------------------------
## 🏗 Архитектура
## Таблица: match_lineup_players
Проект построен вокруг классической схемы:
- составы команд
- старт + запас
```text
Parsers -> Services -> Repositories -> PostgreSQL
|
+-> vMix JSON / .vmix generation
+-> FastAPI admin UI
+-> WebSocket command bus
+-> Scheduler / live workers
```
------------------------------------------------------------------------
### Слои проекта
## Таблица: match_events
#### `parsers/`
Получают данные из внешних источников. Используются для матчей, игроков, расписания, команд и таблиц.
- события матча (голы, карточки и т.д.)
#### `services/`
Содержат прикладную бизнес-логику: синхронизацию данных, авторизацию, подготовку JSON для vMix.
------------------------------------------------------------------------
#### `repositories/`
Отвечают за доступ к PostgreSQL. Здесь собраны CRUD-операции и специализированные запросы.
# 🔄 Основные процессы
#### `templates/` + `static/`
HTML-шаблоны Jinja2, CSS, JS и статические файлы интерфейса.
## 1. Scheduler
#### `vmix/`
Логика генерации vMix-проекта и служебные функции, связанные с эфирной интеграцией.
Работает как отдельный процесс:
#### `scheduler.py`
Фоновый мониторинг матчей и обновление live-состояния.
### Каждую минуту:
#### `agent.py`
Отдельный клиент для связи между vMix и сервером через WebSocket.
- ищет матчи на сегодня
- запускает worker за 1 минуту до начала
---
### Worker:
## 📁 Структура проекта
- раз в минуту:
- парсит сайт
- обновляет счет и статус
- останавливается при finished
```text
vmix/
├── app.py # Основной FastAPI сервер
├── agent.py # WebSocket/vMix агент
├── db.py # Подключение к PostgreSQL
├── scheduler.py # Фоновый live scheduler
├── main.py # Demo/seed сценарий
├── deploy.sh # Скрипт деплоя
├── requirements.txt # Python зависимости
├── wfl.sql # Основная схема БД
├── parsers/
│ ├── parser_game.py # Парсинг/обновление данных матча
│ ├── parser_players.py # Парсинг игроков
│ ├── parser_schedule.py # Парсинг расписания
│ ├── parser_standings.py # Парсинг таблицы
│ └── parser_teams.py # Парсинг команд
├── repositories/
│ ├── audit_log_repository.py
│ ├── auth_repository.py
│ ├── coach_repository.py
│ ├── match_clock_repository.py
│ ├── match_coach_repository.py
│ ├── match_event_repository.py
│ ├── match_formation_repository.py
│ ├── match_lineup_repository.py
│ ├── match_referee_repository.py
│ ├── match_repository.py
│ ├── match_session_repository.py
│ ├── match_view_repository.py
│ ├── player_repository.py
│ ├── referee_repository.py
│ ├── stadium_repository.py
│ ├── standings_repository.py
│ ├── team_coach_repository.py
│ ├── team_repository.py
│ └── team_squad_repository.py
├── services/
│ ├── auth_service.py
│ ├── game_service.py
│ ├── players_service.py
│ ├── schedule_service.py
│ ├── standings_service.py
│ ├── teams_service.py
│ └── vmix_json_service.py
├── sql/
│ └── 001_auth.sql # Таблицы админ-пользователей и сессий
├── static/
│ ├── script.js
│ ├── styles.css
│ ├── smith.ico
│ └── images/
│ └── vmix_icon.png
├── templates/
│ ├── login.html
│ ├── matches.html
│ ├── match_workspace.html
│ ├── download_vmix.html
│ ├── admin_db_index.html
│ ├── admin_db_players.html
│ ├── admin_db_player_edit.html
│ ├── admin_db_referees.html
│ ├── admin_db_referee_edit.html
│ ├── admin_db_coaches.html
│ ├── admin_db_coach_edit.html
│ ├── admin_db_stadiums.html
│ ├── admin_db_stadium_edit.html
│ ├── admin_db_teams.html
│ └── admin_db_team_edit.html
└── vmix/
├── __init__.py
└── vmix_service.py # Генерация .vmix файла
```
------------------------------------------------------------------------
---
## 2. Обновление турнирной таблицы
## 🧰 Технологии
- вызывается `parser_standings`
- обновляет standings в БД
- запускается раз в минуту
| Категория | Технологии |
|---|---|
| Backend | FastAPI |
| Валидация | Pydantic |
| Шаблоны | Jinja2 |
| База данных | PostgreSQL + psycopg2 |
| Парсинг | requests + BeautifulSoup4 |
| Realtime | WebSocket |
| Интеграция с эфиром | vMix API + XML |
| Конфигурация | python-dotenv |
| Дополнительно | numpy |
------------------------------------------------------------------------
### Зависимости из `requirements.txt`
## 3. FastAPI
```txt
fastapi>=0.115,<1.0
uvicorn[standard]>=0.30,<1.0
pydantic>=2.0,<3.0
jinja2>=3.1,<4.0
python-multipart>=0.0.9,<1.0
requests>=2.31,<3.0
websockets>=12,<16
beautifulsoup4>=4.12,<5.0
psycopg2-binary>=2.9,<3.0
python-dotenv>=1.0,<2.0
numpy>=1.26,<3.0
```
Обеспечивает:
Также в файле указан дополнительный приватный индекс и пакет `nasio`, поэтому для полноценной установки в целевой среде может понадобиться доступ к внутреннему package registry.
- админку
- API для vMix
- WebSocket соединения
---
------------------------------------------------------------------------
## 🚀 Быстрый старт
# 📡 API Endpoints
## 1. Клонирование репозитория
## Основные
```bash
git clone <YOUR_REPOSITORY_URL>
cd vmix
```
## 2. Установка зависимостей
```bash
pip install -r requirements.txt
```
## 3. Настройка переменных окружения
Создай файл `.env` в корне проекта:
```env
DB_HOST=localhost
DB_PORT=5432
DB_NAME=wfl_db
DB_USER=postgres
DB_PASSWORD=your_password
```
`db.py` загружает эти параметры через `python-dotenv` и использует их для подключения к PostgreSQL.
## 4. Инициализация базы данных
Сначала разверни основную схему:
```bash
psql -U postgres -d wfl_db -f wfl.sql
```
Затем создай таблицы авторизации:
```bash
psql -U postgres -d wfl_db -f sql/001_auth.sql
```
## 5. Создание администратора
```bash
python scripts/create_admin.py
```
Скрипт запросит:
- `Username`
- `Password`
После этого создаст запись в таблице `admin_users`.
## 6. Запуск приложения
```bash
uvicorn app:app --host 0.0.0.0 --port 8000 --reload
```
После запуска приложение будет доступно по адресу:
```text
http://localhost:8000
```
---
## 🔐 Авторизация
В проекте используется сессионная авторизация для админки.
### Что есть в коде
- таблица `admin_users`;
- таблица `auth_sessions`;
- проверка пароля в `services/auth_service.py`;
- cookie/session-based доступ к админским маршрутам;
- logout с отзывом сессии.
### SQL-таблицы авторизации
Файл `sql/001_auth.sql` создаёт:
- `admin_users`
- `auth_sessions`
- индексы по токену, пользователю и активности
### Скрипт создания пользователя
`python scripts/create_admin.py`
---
## 🖥 Интерфейс и рабочие зоны
### Основные страницы
- `/login` — вход администратора;
- `/` — редирект/входная точка;
- `/admin/matches` — список матчей для администратора;
- `/admin/session/{session_token}` — рабочее пространство матча;
- `/admin/session/{session_token}/download-vmix-page` — страница выгрузки проекта;
- `/admin/db` — индекс админского раздела БД.
### Разделы админ-БД
- игроки;
- судьи;
- тренеры;
- стадионы;
- команды.
Для каждой сущности есть минимум список и форма редактирования.
---
## 📡 HTTP и WebSocket API
Ниже — маршруты, которые реально определены в `app.py`.
### Аутентификация
| Метод | Маршрут | Назначение |
|---|---|---|
| GET | `/login` | страница входа |
| POST | `/login` | авторизация |
| POST | `/logout` | выход |
### Матчи и сессии
| Метод | Маршрут | Назначение |
|---|---|---|
| GET | `/admin/matches` | список матчей |
| GET | `/admin/matches/{match_id}/select` | выбор матча и создание/открытие сессии |
| GET | `/admin/session/{session_token}` | рабочее пространство матча |
| POST | `/admin/session/{session_token}/load-match-data` | загрузка/обновление данных матча |
| POST | `/admin/session/{session_token}/close` | закрытие сессии |
| GET | `/admin/session/{session_token}/download-vmix-page` | HTML-страница выгрузки vMix |
| GET | `/admin/session/{session_token}/download-vmix` | скачивание `.vmix` |
### Формации и составы
| Метод | Маршрут | Назначение |
|---|---|---|
| POST | `/admin/session/{session_token}/formations/apply` | применить preset формации к игрокам |
| POST | `/admin/session/{session_token}/formations/save` | сохранить формации |
| GET | `/admin/session/{session_token}/squad-editor-data` | получить данные редактора состава |
| POST | `/admin/session/{session_token}/squad-editor-save` | сохранить состав |
| POST | `/admin/session/{session_token}/referees/save` | сохранить судей на матч |
### События матча
| Метод | Маршрут | Назначение |
|---|---|---|
| GET | `/admin/session/{session_token}/events` | список событий |
| POST | `/admin/session/{session_token}/event` | создать событие |
| PUT | `/admin/session/{session_token}/event/{event_id}` | обновить событие |
| DELETE | `/admin/session/{session_token}/event/{event_id}` | удалить событие |
| DELETE | `/admin/session/{session_token}/events` | очистить все события |
### Справочники БД
| Метод | Маршрут | Назначение |
|---|---|---|
| GET | `/admin/db` | главная админ-БД |
| GET/POST | `/admin/db/players` / `/admin/db/players/{player_id}/edit` | список/редактирование игроков |
| GET/POST | `/admin/db/referees` / `/admin/db/referees/{referee_id}/edit` | список/редактирование судей |
| GET/POST | `/admin/db/coaches` / `/admin/db/coaches/{coach_id}/edit` | список/редактирование тренеров |
| GET/POST | `/admin/db/stadiums` / `/admin/db/stadiums/{stadium_id}/edit` | список/редактирование стадионов |
| GET/POST | `/admin/db/teams` / `/admin/db/teams/{team_id}/edit` | список/редактирование команд |
### vMix JSON endpoints
| Метод | Маршрут | Назначение |
|---|---|---|
| GET | `/vmix/session/{session_token}/home-lineup` | стартовый состав хозяев |
| GET | `/vmix/session/{session_token}/away-lineup` | стартовый состав гостей |
| GET | `/vmix/session/{session_token}/home-bench` | запасные хозяев |
| GET | `/vmix/session/{session_token}/away-bench` | запасные гостей |
| GET | `/vmix/session/{session_token}/info` | информация о матче |
| GET | `/vmix/session/{session_token}/standings` | турнирная таблица |
| GET | `/vmix/session/{session_token}/schedule` | расписание/тур |
| GET | `/vmix/session/{session_token}/home-formations` | формация хозяев |
| GET | `/vmix/session/{session_token}/away-formations` | формация гостей |
| GET | `/vmix/session/{session_token}/scoreboard` | данные для счётчика |
| GET | `/vmix/session/{session_token}/match-events` | данные по событиям матча |
### Команды для vMix-клиентов
| Метод | Маршрут | Назначение |
|---|---|---|
| POST | `/api/vmix/publish-command` | отправить команду в vMix-клиент(ы) |
| GET | `/api/vmix/clients` | список подключённых клиентов |
| WS | `/ws/vmix-client` | WebSocket-канал клиентов |
---
## 🎬 Интеграция с vMix
### Что делает сервер
Сервер:
- создаёт матчевые сессии;
- готовит JSON для графики;
- собирает и отдаёт `.vmix`-проект;
- отправляет команды в подключённые клиентские агенты.
### Что делает агент `agent.py`
Агент — это отдельное приложение, которое запускается рядом с vMix и выполняет роль моста между сервером и локальным vMix API.
#### В коде агента есть:
- `VMIX_API = "http://127.0.0.1:8088/api"`
- `WS_BASE = "wss://wfl.tvstart.ru/ws/vmix-client"`
- чтение XML-ответа vMix;
- извлечение `dynamic/value1`, `dynamic/value2` и других значений;
- регистрация клиента в WebSocket;
- reconnect-логика.
### Как это работает в общем
1. Оператор открывает матч в админке.
2. Создаётся матчевая сессия с `session_token`.
3. Сервер отдаёт JSON и/или `.vmix`-файл.
4. Локальный агент подключается по WebSocket.
5. Сервер отправляет команды конкретному клиенту, группе или оператору.
6. Агент применяет команды в локальном vMix через HTTP API.
---
## 🧾 Генерация JSON для графики
Логика сосредоточена в `services/vmix_json_service.py`.
### По коду видно, что сервис формирует:
- стартовые составы;
- запасных;
- информацию о матче;
- турнирную таблицу;
- расписание тура;
- формации команд;
- scoreboard-информацию;
- события матча;
- данные для показа авторов голов.
### Особенности реализации
- строятся полные имена игроков;
- добавляются суффиксы капитана и вратаря;
- формируются пути к фотографиям игроков;
- используются логотипы команд и специальные варианты логотипов для некоторых клубов;
- матчевая информация собирается SQL-запросами по сессии.
---
## 📦 Генерация `.vmix` проекта
Файл `vmix/vmix_service.py` используется для:
- сборки бинарного содержимого vMix-проекта;
- генерации имени файла;
- выдачи файла пользователю через FastAPI.
В `app.py` для этого используются:
- `build_vmix_project_bytes`
- `build_vmix_filename`
Это означает, что оператор может открыть страницу сессии и скачать готовый `.vmix`-проект под конкретный матч.
---
## ⏱ Scheduler и live-мониторинг
`scheduler.py` — это фоновый процесс, который поднимается на старте приложения:
```python
@app.on_event("startup")
def start_scheduler():
import threading
thread = threading.Thread(target=run_scheduler, daemon=True)
thread.start()
```
### Ключевые интервалы
```python
MATCH_START_LEAD_MINUTES = 1
LIVE_MATCH_POLL_SECONDS = 60
MATCHES_LOOP_SECONDS = 60
STANDINGS_LOOP_SECONDS = 60
WORKER_ERROR_RETRY_SECONDS = 30
WORKER_MAX_ERRORS_IN_ROW = 20
```
### Что делает scheduler
- получает матчи на сегодня из БД;
- определяет, какие матчи уже пора мониторить;
- запускает отдельные worker-потоки;
- обновляет status/home_score/away_score в таблице матчей;
- вызывает обновление турнирной таблицы;
- ведёт реестр активных worker'ов.
### Источник live-данных
По текущему коду live-страница матча запрашивается с:
```text
https://wfl.rfs.ru/match/{match_id}
```
HTML разбирается через BeautifulSoup.
### Важное замечание
В `fetch_match_live_data()` есть незавершённая часть: функция частично реализована и в конце всё ещё содержит `NotImplementedError`. То есть scheduler уже встроен, но live-парсинг требует аккуратной доработки, чтобы считать его полностью production-ready.
---
## 🗄 Репозитории и доменные сущности
По составу `repositories/` проект работает со следующими сущностями:
### Пользователи и аудит
- `auth_repository.py`
- `audit_log_repository.py`
### Матчи
- `match_repository.py`
- `match_session_repository.py`
- `match_view_repository.py`
- `match_clock_repository.py`
- `match_event_repository.py`
- GET /admin/matches
- GET /admin/session/{session_token}
### Составы и формации
- `match_lineup_repository.py`
- `match_formation_repository.py`
- `team_squad_repository.py`
------------------------------------------------------------------------
### Официальные лица и стадионы
- `referee_repository.py`
- `match_referee_repository.py`
- `coach_repository.py`
- `match_coach_repository.py`
- `team_coach_repository.py`
- `stadium_repository.py`
### vMix
### Команды, игроки, таблица
- `team_repository.py`
- `player_repository.py`
- `standings_repository.py`
- GET /vmix/session/{session_token}/info
- GET /vmix/session/{session_token}/standings
- GET /vmix/session/{session_token}/schedule
- GET /vmix/session/{session_token}/scoreboard
Это хороший признак разделённой архитектуры: доступ к данным отделён от HTTP-слоя и от прикладной логики.
------------------------------------------------------------------------
---
### WebSocket
## 🔄 Сервисы синхронизации
/ws/vmix-client
В `services/` есть отдельные сервисы:
Функции: - регистрация клиентов - heartbeat - отправка команд
- `teams_service.py`
- `schedule_service.py`
- `players_service.py`
- `standings_service.py`
- `game_service.py`
- `auth_service.py`
- `vmix_json_service.py`
------------------------------------------------------------------------
### Demo-режим
`main.py` показывает, как можно программно наполнить систему тестовыми данными:
# ⚙️ Запуск проекта
- создаются 2 команды;
- создаётся матч;
- добавляются игроки;
- заполняется турнирная таблица.
## 1. Установка
Запуск:
pip install -r requirements.txt
```bash
python main.py
```
------------------------------------------------------------------------
Это удобно для первичной проверки БД и шаблонного сценария разработки.
## 2. Настройка БД
---
Отредактировать:
## 🧪 Полезные команды
db.py
### Проверка подключения к БД
------------------------------------------------------------------------
```bash
python db.py
```
## 3. Запуск
### Создание администратора
### API
```bash
python scripts/create_admin.py
```
uvicorn app:app --reload
### Demo-наполнение
### Scheduler
```bash
python main.py
```
python scheduler.py
### Запуск сервера
------------------------------------------------------------------------
```bash
uvicorn app:app --reload
```
# ❗ ВАЖНО
---
Scheduler должен запускаться отдельно.
## 🖼 Скриншоты
НЕЛЬЗЯ:
Ниже заготовки под реальные скриншоты интерфейса. Когда будут реальные изображения, просто положи их в репозиторий и обнови пути.
run_scheduler()
```md
![Login](docs/screens/login.png)
![Matches](docs/screens/matches.png)
![Workspace](docs/screens/workspace.png)
![Database](docs/screens/database.png)
```
внутри FastAPI.
---
------------------------------------------------------------------------
## ⚠️ Ограничения и важные замечания
# 🔧 Что нужно реализовать
### 1. Документация OpenAPI отключена
В `app.py` явно выключены:
- `/docs`
- `/redoc`
- `/openapi.json`
## fetch_match_live_data()
Это нормально для внутреннего production-режима, но неудобно для внешних интеграций.
def fetch_match_live_data(match_row):
return {
"status": "live",
"home_score": 1,
"away_score": 0
}
### 2. Live scheduler требует доработки
`fetch_match_live_data()` ещё не завершена до конца и сейчас выглядит как заготовка с частичной логикой.
------------------------------------------------------------------------
### 3. Есть Windows-специфичные элементы
В JSON-сервисе и агенте встречаются Windows-пути и логика работы с иконкой консоли. Это значит, что часть инфраструктуры ориентирована на Windows-машину оператора.
# 🚀 Рекомендации
### 4. Есть внешняя зависимость от приватного Python registry
В `requirements.txt` указан `--extra-index-url`, поэтому разворачивание в другой среде может потребовать доступов.
- запускать scheduler отдельно
- использовать 1 worker для API
- добавить логирование
- обрабатывать ошибки парсинга
### 5. Есть жёстко заданные интеграционные значения
Например:
- `http://127.0.0.1:8088/api`
- `wss://wfl.tvstart.ru/ws/vmix-client`
------------------------------------------------------------------------
Для production лучше вынести их в `.env`.
# 📌 Dev режим
---
uvicorn app:app --reload
python scheduler.py
## 🔮 Что можно улучшить
------------------------------------------------------------------------
### Инфраструктура
- добавить Dockerfile и `docker-compose.yml`;
- вынести конфигурацию целиком в `.env`;
- добавить healthcheck и monitoring;
- настроить CI/CD.
# 🧠 Production
### Backend
- включить структурированное логирование;
- покрыть ключевые места тестами;
- заменить часть threading-логики на более управляемый background orchestration;
- валидацию live-парсеров сделать устойчивее.
- API отдельно
- Scheduler отдельно
- supervisor / systemd
### Безопасность
- ограничить rate limit для логина;
- добавить CSRF-защиту, если нужна;
- вынести секреты и URL в окружение;
- расширить аудит действий администратора.
------------------------------------------------------------------------
### API и DX
- вернуть внутреннюю OpenAPI-документацию под флагом окружения;
- добавить Postman/Insomnia collection;
- оформить контракт JSON-ответов для графики.
# 📬 Контакты
### UI/UX
- добавить больше навигации в админке;
- улучшить визуальный статус live-сессий;
- добавить быстрые действия в матч-центре.
Для доработок и улучшений --- пиши 👍
---
## 🛠 Пример локального сценария запуска
```bash
# 1. установить зависимости
pip install -r requirements.txt
# 2. создать .env
cp .env.example .env # если появится шаблон
# 3. поднять БД и применить SQL
psql -U postgres -d wfl_db -f wfl.sql
psql -U postgres -d wfl_db -f sql/001_auth.sql
# 4. создать администратора
python scripts/create_admin.py
# 5. при необходимости заполнить демо-данными
python main.py
# 6. запустить сервер
uvicorn app:app --host 0.0.0.0 --port 8000 --reload
```
---
## 🤝 Вклад в проект
Если проект будет развиваться дальше, рекомендуется принять минимальные правила contribution:
1. отдельная ветка на каждую фичу;
2. PR с описанием изменений;
3. проверка SQL-миграций перед merge;
4. ручная проверка vMix-сценария и матчевого workflow.
---
## 📄 Лицензия
В текущем архиве лицензия отдельно не обнаружена.
Если проект внутренний — можно оставить private/internal use only.
Если репозиторий будет публичным — добавь подходящую лицензию, например MIT, Apache-2.0 или другую нужную команде.
---
## 👨‍💻 Итог
Этот проект — это не просто CRUD-приложение, а полноценный операторский инструмент для футбольной трансляции:
- FastAPI-сервер с HTML-интерфейсом;
- PostgreSQL как основной источник данных;
- сессионная админ-авторизация;
- матчевые рабочие сессии;
- составы, формации, события и судьи;
- JSON и `.vmix` для эфирной графики;
- WebSocket-мост для операторских клиентов;
- scheduler для live-матчей и обновления данных.
Если нужно, следующим сообщением я могу так же сделать ещё и:
- `README_EN.md` на английском;
- `docs/API.md` с описанием всех маршрутов;
- `docker-compose.yml` для локального запуска;
- `.env.example`;
- более «маркетинговую» GitHub-версию с centered hero, anchors и navigation block.