Skip to content

Latest commit

 

History

History
1559 lines (1156 loc) · 43.9 KB

File metadata and controls

1559 lines (1156 loc) · 43.9 KB

Руководство по API

Базовый URL: http://localhost:8080/api/v1

Содержание


Формат ответов

Все успешные ответы оборачиваются в envelope:

{
  "data": { ... }
}

Ответы с ошибками:

{
  "error": {
    "code": "NOT_FOUND",
    "message": "Ресурс не найден"
  }
}

Аутентификация

Все защищённые эндпоинты требуют заголовок Authorization: Bearer <token>.

Токен доступа (access token) получается при регистрации или входе. Срок действия ограничен. Для обновления используйте эндпоинт /auth/refresh с refresh-токеном.


Лимиты размера тела запроса

Тип запроса Лимит
JSON-эндпоинты 1 МБ
Загрузка файлов (программы) 10 МБ

При превышении лимита возвращается ошибка 400 Bad Request.


Уровни доступа

В документации используются следующие обозначения:

Обозначение Описание
🌐 Публичный Доступен без авторизации
🔑 Требует авторизации Необходим валидный JWT-токен
👑 Только администратор Необходим JWT-токен с ролью admin

Некоторые эндпоинты используют опциональную авторизацию (OptionalAuth): они доступны всем, но авторизованные администраторы получают расширенную информацию (например, полные сообщения об ошибках в матчах).


Авторизация (Auth)

Базовый путь: /api/v1/auth

POST /auth/register 🌐 Публичный

Регистрация нового пользователя.

POST /auth/register
Content-Type: application/json

{
  "username": "player1",
  "email": "player1@example.com",
  "password": "SecurePass123!"
}

Ответ: 201 Created

{
  "user": {"id": "uuid", "username": "player1", "role": "user"},
  "access_token": "eyJ...",
  "refresh_token": "eyJ..."
}

POST /auth/login 🌐 Публичный

Вход в систему.

POST /auth/login
Content-Type: application/json

{"email": "player1@example.com", "password": "SecurePass123!"}

Ответ: 200 OK с токенами (формат аналогичен регистрации).

POST /auth/refresh 🌐 Публичный

Обновление пары токенов.

POST /auth/refresh
Content-Type: application/json

{"refresh_token": "eyJ..."}

Ответ: 200 OK с новыми токенами.

POST /auth/logout 🔑 Требует авторизации

Выход из системы. Добавляет токены в чёрный список.

POST /auth/logout
Authorization: Bearer <token>
Content-Type: application/json

{"refresh_token": "eyJ..."}

Refresh-токен в теле запроса опционален. Ответ: 204 No Content.

GET /auth/me 🔑 Требует авторизации

Получение информации о текущем пользователе.

GET /auth/me
Authorization: Bearer <token>

Ответ: 200 OK

{
  "id": "uuid",
  "username": "player1",
  "email": "player1@example.com",
  "role": "user",
  "created_at": "2026-01-01T00:00:00Z"
}

PUT /auth/profile 🔑 Требует авторизации

Обновление профиля текущего пользователя. Позволяет сменить email и/или пароль.

PUT /auth/profile
Authorization: Bearer <token>
Content-Type: application/json

{
  "email": "newemail@example.com",
  "password": "NewSecurePass123!",
  "current_password": "OldPassword123!"
}

Все поля опциональны. При смене пароля поле current_password обязательно.

Ответ: 200 OK -- обновлённый объект пользователя.


Игры (Games)

Базовый путь: /api/v1/games

GET /games 🌐 Публичный

Список всех доступных игр.

GET /games?name=prisoners&limit=50&offset=0

Параметры запроса:

  • name -- фильтр по имени (частичное совпадение)
  • limit -- размер страницы (по умолчанию: 50)
  • offset -- смещение

Ответ: 200 OK

[
  {
    "id": "uuid",
    "slug": "prisoners_dilemma",
    "name": "Дилемма заключённого",
    "rules": "# Правила\n\n...",
    "score_multiplier": 1.0,
    "created_at": "2026-01-01T00:00:00Z"
  }
]

GET /games/{id} 🌐 Публичный

Получение информации об игре по ID.

GET /games/{id}

GET /games/name/{name} 🌐 Публичный

Получение игры по имени. Полезно для поиска игры без знания UUID.

GET /games/name/prisoners_dilemma

Ответ: 200 OK -- объект игры (формат аналогичен списку).

POST /games 👑 Только администратор

Создание новой игры.

POST /games
Authorization: Bearer <token>
Content-Type: application/json

{
  "slug": "new_game",
  "name": "Новая игра",
  "rules": "# Правила\n\nMarkdown описание...",
  "score_multiplier": 1.5
}

Ответ: 201 Created -- созданный объект игры.

PUT /games/{id} 👑 Только администратор

Обновление игры.

PUT /games/{id}
Authorization: Bearer <token>
Content-Type: application/json

{
  "name": "Обновлённое название",
  "rules": "# Новые правила\n\n...",
  "score_multiplier": 2.0
}

DELETE /games/{id} 👑 Только администратор

Удаление игры.

DELETE /games/{id}
Authorization: Bearer <token>

Ответ: 204 No Content.


Турниры (Tournaments)

Базовый путь: /api/v1/tournaments

Публичные эндпоинты

GET /tournaments 🌐 Публичный

Список турниров с фильтрацией и пагинацией.

GET /tournaments?status=active&game_type=prisoners_dilemma&limit=10&offset=0

Параметры запроса:

  • status -- фильтр по статусу: pending, active, completed, cancelled
  • game_type -- фильтр по типу игры
  • limit -- размер страницы (по умолчанию: 50)
  • offset -- смещение

GET /tournaments/{id} 🌐 Публичный

Получение информации о турнире.

GET /tournaments/{id}

Ответ: 200 OK

{
  "id": "uuid",
  "name": "Турнир",
  "description": "...",
  "status": "active",
  "max_team_size": 3,
  "games": [
    {
      "game_id": "uuid",
      "game_name": "Дилемма заключённого",
      "is_active": true,
      "round_status": "running",
      "round_number": 2
    }
  ],
  "teams_count": 15,
  "created_at": "2026-01-01T00:00:00Z"
}

GET /tournaments/{id}/leaderboard 🌐 Публичный

Таблица лидеров турнира.

GET /tournaments/{id}/leaderboard?limit=100

Ответ: 200 OK

[
  {
    "rank": 1,
    "team_id": "uuid",
    "team_name": "TopTeam",
    "rating": 1650,
    "wins": 10,
    "losses": 2,
    "draws": 1
  }
]

GET /tournaments/{id}/cross-game-leaderboard 🌐 Публичный

Кросс-игровой рейтинг турнира. Объединяет результаты по всем играм.

GET /tournaments/{id}/cross-game-leaderboard

Ответ: 200 OK

[
  {
    "rank": 1,
    "team_id": "uuid",
    "team_name": "TopTeam",
    "program_name": "MyBot v3",
    "game_ratings": {
      "game-uuid-1": 1650,
      "game-uuid-2": 1580
    },
    "total_rating": 3230,
    "total_wins": 18,
    "total_losses": 4,
    "total_games": 22
  }
]

GET /tournaments/{id}/matches 🌐 Публичный

Список матчей турнира с пагинацией.

GET /tournaments/{id}/matches?limit=50&offset=0

GET /tournaments/{id}/matches/rounds 🌐 Публичный

Матчи турнира, сгруппированные по раундам. Удобно для отображения прогресса по раундам.

GET /tournaments/{id}/matches/rounds

Ответ: 200 OK -- массив объектов MatchRound, каждый содержит номер раунда и список матчей.

GET /tournaments/{id}/games 🌐 Публичный

Список игр, подключённых к турниру.

GET /tournaments/{id}/games

Ответ: 200 OK -- массив объектов игр.

GET /tournaments/{id}/teams 🌐 Публичный

Список команд, участвующих в турнире.

GET /tournaments/{id}/teams

Ответ: 200 OK -- массив объектов команд.

GET /tournaments/{id}/games/{gameId}/leaderboard 🌐 Публичный

Таблица лидеров для конкретной игры в турнире.

GET /tournaments/{id}/games/{gameId}/leaderboard?limit=100

Ответ: 200 OK -- формат аналогичен общей таблице лидеров.

GET /tournaments/{id}/games/{gameId}/matches 🌐 Публичный

Матчи для конкретной игры в турнире.

GET /tournaments/{id}/games/{gameId}/matches?status=completed&limit=50&offset=0

Параметры запроса:

  • status -- фильтр: pending, running, completed, failed
  • limit -- размер страницы (по умолчанию: 50)
  • offset -- смещение

GET /tournaments/{id}/games/status 🌐 Публичный

Игры турнира с расширенной информацией о статусе раундов.

GET /tournaments/{id}/games/status

Ответ: 200 OK

[
  {
    "tournament_id": "uuid",
    "game_id": "uuid",
    "game_name": "prisoners_dilemma",
    "game_display_name": "Дилемма заключённого",
    "is_active": true,
    "round_completed": false,
    "round_completed_at": null,
    "current_round": 2
  }
]

GET /tournaments/{id}/active-game 🌐 Публичный

Текущая активная игра турнира. Возвращает null, если активной игры нет.

GET /tournaments/{id}/active-game

Ответ: 200 OK -- объект TournamentGameWithDetails или null.

Эндпоинты с авторизацией

POST /tournaments/{id}/join 🔑 Требует авторизации

Присоединение к турниру с указанием программы.

POST /tournaments/{id}/join
Authorization: Bearer <token>
Content-Type: application/json

{
  "program_id": "uuid"
}

Ответ: 200 OK

{"status": "joined"}

GET /tournaments/{id}/my-team 🔑 Требует авторизации

Получение команды текущего пользователя в турнире. Возвращает null, если пользователь не состоит в команде в данном турнире.

GET /tournaments/{id}/my-team
Authorization: Bearer <token>

Ответ: 200 OK -- объект команды или null.

POST /tournaments/{id}/games 🔑 Требует авторизации

Добавление игры в турнир. Доступно администраторам и создателю турнира.

POST /tournaments/{id}/games
Authorization: Bearer <token>
Content-Type: application/json

{
  "game_id": "uuid"
}

Ответ: 204 No Content.

Административные эндпоинты

POST /tournaments 👑 Только администратор

Создание нового турнира.

POST /tournaments
Authorization: Bearer <token>
Content-Type: application/json

{
  "name": "Еженедельный чемпионат",
  "description": "Описание турнира (Markdown)",
  "max_team_size": 3,
  "max_participants": 100,
  "is_perpetual": false
}

Ответ: 201 Created -- созданный объект турнира.

POST /tournaments/{id}/start 👑 Только администратор

Запуск турнира. Переводит статус в active.

POST /tournaments/{id}/start
Authorization: Bearer <token>

Ответ: 200 OK

{"status": "started"}

POST /tournaments/{id}/complete 👑 Только администратор

Завершение турнира. Переводит статус в completed.

POST /tournaments/{id}/complete
Authorization: Bearer <token>

Ответ: 200 OK

{"status": "completed"}

DELETE /tournaments/{id} 👑 Только администратор

Удаление турнира.

DELETE /tournaments/{id}
Authorization: Bearer <token>

Ответ: 204 No Content.

POST /tournaments/{id}/matches 👑 Только администратор

Создание одиночного матча между двумя программами.

POST /tournaments/{id}/matches
Authorization: Bearer <token>
Content-Type: application/json

{
  "program1_id": "uuid",
  "program2_id": "uuid",
  "priority": "medium"
}

Значения priority: low, medium, high. По умолчанию: medium.

Ответ: 201 Created -- объект созданного матча.

DELETE /tournaments/{id}/games/{gameId} 👑 Только администратор

Удаление игры из турнира.

DELETE /tournaments/{id}/games/{gameId}
Authorization: Bearer <token>

Ответ: 204 No Content.

GET /tournaments/{id}/games/{gameId}/programs 👑 Только администратор

Список программ, загруженных для конкретной игры в турнире.

GET /tournaments/{id}/games/{gameId}/programs
Authorization: Bearer <token>

Ответ: 200 OK -- массив объектов программ.

POST /tournaments/{id}/games/{gameId}/complete-round 👑 Только администратор

Пометить раунд игры как завершённый. Блокирует загрузку новых программ для этой игры.

POST /tournaments/{id}/games/{gameId}/complete-round
Authorization: Bearer <token>

Ответ: 204 No Content.

POST /tournaments/{id}/games/{gameId}/reset-round 👑 Только администратор

Полный сброс раунда игры: удаление матчей, сброс рейтингов и статистики участников.

POST /tournaments/{id}/games/{gameId}/reset-round
Authorization: Bearer <token>

Ответ: 200 OK

{
  "matches_deleted": 45,
  "participants_reset": 10,
  "rating_history_reset": 90
}

POST /tournaments/{id}/games/{gameId}/auto-round 👑 Только администратор

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

POST /tournaments/{id}/games/{gameId}/auto-round
Authorization: Bearer <token>
Content-Type: application/json

{
  "enabled": true,
  "interval_seconds": 120
}

Поле interval_seconds должно быть в диапазоне от 10 до 3600. Обязательно при enabled: true.

Ответ: 200 OK

{
  "enabled": true,
  "interval_seconds": 120
}

GET /tournaments/{id}/games/{gameId}/auto-round 👑 Только администратор

Получение текущего статуса авто-раунда для игры.

GET /tournaments/{id}/games/{gameId}/auto-round
Authorization: Bearer <token>

Ответ: 200 OK

{
  "enabled": true,
  "interval_seconds": 120,
  "last_run_at": "2026-03-17T12:00:00Z"
}

POST /tournaments/{id}/active-game 👑 Только администратор

Установка активной игры в турнире. Только одна игра может быть активной одновременно.

POST /tournaments/{id}/active-game
Authorization: Bearer <token>
Content-Type: application/json

{
  "game_id": "uuid"
}

Ответ: 204 No Content.

POST /tournaments/{id}/games/deactivate-all 👑 Только администратор

Деактивация всех игр в турнире. Снимает флаг активности со всех игр.

POST /tournaments/{id}/games/deactivate-all
Authorization: Bearer <token>

Ответ: 204 No Content.

POST /tournaments/{id}/run-matches 👑 Только администратор

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

POST /tournaments/{id}/run-matches
Authorization: Bearer <token>

Ответ: 200 OK

{
  "status": "started",
  "enqueued": 45
}

POST /tournaments/{id}/run-game-matches 👑 Только администратор

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

POST /tournaments/{id}/run-game-matches
Authorization: Bearer <token>
Content-Type: application/json

{
  "game_type": "prisoners_dilemma"
}

Ответ: 200 OK

{
  "status": "started",
  "game_type": "prisoners_dilemma",
  "enqueued": 15
}

POST /tournaments/{id}/retry-matches 👑 Только администратор

Повторный запуск всех неудачных (failed) матчей турнира.

POST /tournaments/{id}/retry-matches
Authorization: Bearer <token>

Ответ: 200 OK

{
  "status": "retried",
  "enqueued": 3
}

POST /tournaments/{id}/programs/clear-errors 👑 Только администратор

Очистка сообщений об ошибках для всех программ в турнире. Полезно после массового исправления проблем.

POST /tournaments/{id}/programs/clear-errors
Authorization: Bearer <token>

Ответ: 200 OK

{
  "cleared": 5,
  "message": "Очищено 5 ошибок"
}

Команды (Teams)

Базовый путь: /api/v1/teams

Все эндпоинты команд требуют авторизации.

POST /teams 🔑 Требует авторизации

Создание новой команды в турнире. Текущий пользователь становится лидером.

POST /teams
Authorization: Bearer <token>
Content-Type: application/json

{
  "tournament_id": "uuid",
  "name": "Моя команда"
}

Ответ: 201 Created

{
  "id": "uuid",
  "name": "Моя команда",
  "invite_code": "ABC123",
  "leader_id": "uuid",
  "members": [
    {"id": "uuid", "username": "player1"}
  ]
}

POST /teams/join 🔑 Требует авторизации

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

POST /teams/join
Authorization: Bearer <token>
Content-Type: application/json

{
  "code": "ABC123"
}

Ответ: 200 OK -- объект команды.

GET /teams/{id} 🔑 Требует авторизации

Получение информации о команде с участниками.

GET /teams/{id}
Authorization: Bearer <token>

PUT /teams/{id} 🔑 Требует авторизации

Обновление названия команды. Доступно только лидеру команды.

PUT /teams/{id}
Authorization: Bearer <token>
Content-Type: application/json

{
  "name": "Новое название"
}

Ответ: 200 OK -- обновлённый объект команды.

GET /teams/{id}/members 🔑 Требует авторизации

Получение списка участников команды.

GET /teams/{id}/members
Authorization: Bearer <token>

Ответ: 200 OK -- массив объектов участников.

POST /teams/{id}/leave 🔑 Требует авторизации

Покинуть команду.

POST /teams/{id}/leave
Authorization: Bearer <token>

Ответ: 204 No Content.

DELETE /teams/{id}/members/{userId} 🔑 Требует авторизации

Исключение участника из команды. Доступно только лидеру.

DELETE /teams/{id}/members/{userId}
Authorization: Bearer <token>

Ответ: 204 No Content.

GET /teams/{id}/invite 🔑 Требует авторизации

Получение кода и ссылки приглашения в команду. Доступно только лидеру.

GET /teams/{id}/invite
Authorization: Bearer <token>

Ответ: 200 OK

{
  "code": "ABC123",
  "link": "http://localhost:8080/join?code=ABC123"
}

DELETE /teams/{id} 👑 Только администратор

Удаление команды.

DELETE /teams/{id}
Authorization: Bearer <token>

Ответ: 204 No Content.


Программы (Programs)

Базовый путь: /api/v1/programs

Все эндпоинты программ требуют авторизации. Максимальный размер загружаемого файла: 10 МБ.

POST /programs 🔑 Требует авторизации

Загрузка новой программы. Поддерживает два формата: multipart/form-data (файл) и application/json (путь).

Загрузка файла (рекомендуемый способ):

POST /programs
Authorization: Bearer <token>
Content-Type: multipart/form-data

file: <binary>
team_id: "uuid"
tournament_id: "uuid"
game_id: "uuid"
name: "My Strategy v2"

Поле name опционально -- если не указано, используется имя файла.

Сервер автоматически:

  • Определяет язык по расширению файла (python, cpp, c, go, rust, java, javascript, ruby, php, lua)
  • Проверяет синтаксис кода
  • Компилирует программу (для компилируемых языков)
  • Добавляет shebang для интерпретируемых языков (если отсутствует)
  • Регистрирует программу как участника турнира
  • Назначает атомарную версию

Ответ: 201 Created

{
  "id": "uuid",
  "name": "My Strategy v2",
  "language": "python",
  "version": 3,
  "error_message": null,
  "created_at": "2026-01-01T00:00:00Z"
}

Если обнаружена ошибка синтаксиса или компиляции, поле error_message содержит описание проблемы, но программа все равно сохраняется.

Важно: Загрузка программ может быть заблокирована, если:

  • Турнир ещё не начался (статус не active)
  • Раунд игры уже завершён (в ручном режиме)
  • Выполняются матчи другой игры (в ручном режиме)

В режиме авто-раунда эти ограничения снимаются.

JSON-запрос (обратная совместимость):

POST /programs
Authorization: Bearer <token>
Content-Type: application/json

{
  "name": "My Strategy",
  "game_type": "prisoners_dilemma",
  "code_path": "strategy.py",
  "language": "python"
}

GET /programs 🔑 Требует авторизации

Список программ текущего пользователя.

GET /programs?tournament_id=uuid&game_id=uuid
Authorization: Bearer <token>

GET /programs/versions 🔑 Требует авторизации

Список всех версий программ для команды и игры. Позволяет отслеживать историю загрузок.

GET /programs/versions?team_id=uuid&game_id=uuid
Authorization: Bearer <token>

Параметры запроса (обязательные):

  • team_id -- идентификатор команды
  • game_id -- идентификатор игры

Ответ: 200 OK -- массив объектов программ, отсортированных по версии.

GET /programs/{id} 🔑 Требует авторизации

Получение информации о программе. Владелец видит свои программы, администратор -- все.

GET /programs/{id}
Authorization: Bearer <token>

GET /programs/{id}/download 🔑 Требует авторизации

Скачивание исходного файла программы. Владелец может скачивать свои программы, администратор -- любые.

GET /programs/{id}/download
Authorization: Bearer <token>

Ответ: бинарный файл с заголовком Content-Disposition: attachment.

PUT /programs/{id} 🔑 Требует авторизации

Обновление метаданных программы (имя, путь к коду, язык). Доступно только владельцу.

PUT /programs/{id}
Authorization: Bearer <token>
Content-Type: application/json

{
  "name": "Updated Strategy",
  "code_path": "new_strategy.py",
  "language": "python"
}

Ответ: 200 OK -- обновлённый объект программы.

DELETE /programs/{id} 🔑 Требует авторизации

Удаление программы. Доступно только владельцу. Удаляет также файл с диска.

DELETE /programs/{id}
Authorization: Bearer <token>

Ответ: 204 No Content.


Матчи (Matches)

Базовый путь: /api/v1/matches

Публичные эндпоинты (с опциональной авторизацией)

Эндпоинты списка и получения матчей используют OptionalAuth: они доступны без авторизации, но авторизованные пользователи получают дополнительную информацию:

  • Администраторы видят полные сообщения об ошибках для всех матчей
  • Владельцы программы видят полные ошибки, если их программа упала
  • Остальные видят обезличенное сообщение: "Программа оппонента завершилась с ошибкой"

GET /matches 🌐 Публичный (OptionalAuth)

Список матчей с фильтрацией.

GET /matches?tournament_id=uuid&program_id=uuid&status=completed&game_type=prisoners_dilemma&limit=50&offset=0

Параметры запроса:

  • tournament_id -- фильтр по турниру
  • program_id -- фильтр по программе
  • status -- фильтр: pending, running, completed, failed
  • game_type -- фильтр по типу игры
  • limit -- размер страницы (по умолчанию: 50)
  • offset -- смещение

GET /matches/{id} 🌐 Публичный (OptionalAuth)

Получение информации о матче.

GET /matches/{id}

Ответ: 200 OK

{
  "id": "uuid",
  "tournament_id": "uuid",
  "game_id": "uuid",
  "program1": {
    "id": "uuid",
    "name": "Bot1",
    "team_name": "Team1"
  },
  "program2": {
    "id": "uuid",
    "name": "Bot2",
    "team_name": "Team2"
  },
  "winner_id": "uuid",
  "status": "completed",
  "score1": 1500,
  "score2": 1200,
  "round_number": 2,
  "error_message": null,
  "created_at": "2026-01-01T00:00:00Z",
  "completed_at": "2026-01-01T00:01:00Z"
}

GET /matches/statistics 🌐 Публичный (OptionalAuth)

Статистика матчей. Можно фильтровать по турниру.

GET /matches/statistics?tournament_id=uuid

Параметры запроса:

  • tournament_id -- фильтр по турниру (опционально; без фильтра -- глобальная статистика)

Ответ: 200 OK -- объект со статистикой (количество матчей по статусам, среднее время и т.д.).

Административные эндпоинты

GET /matches/queue/stats 👑 Только администратор

Статистика очереди матчей (Redis). Показывает количество матчей в каждой очереди приоритетов.

GET /matches/queue/stats
Authorization: Bearer <token>

Ответ: 200 OK -- объект со статистикой очереди.

POST /matches/queue/clear 👑 Только администратор

Полная очистка всех очередей матчей.

POST /matches/queue/clear
Authorization: Bearer <token>

Ответ: 200 OK

{"message": "All queues cleared successfully"}

POST /matches/queue/purge 👑 Только администратор

Удаление из очереди матчей, которых нет в базе данных. Полезно для очистки "зависших" записей.

POST /matches/queue/purge
Authorization: Bearer <token>

Ответ: 200 OK

{
  "message": "Invalid matches purged successfully",
  "purged_count": 3
}

WebSocket

Базовый путь: /api/v1/ws

Все WebSocket-эндпоинты требуют авторизации. Токен передаётся через параметр запроса или subprotocol.

GET /ws/tournaments/{id} 🔑 Требует авторизации

Подключение к real-time обновлениям турнира.

WS /ws/tournaments/{id}?token=<jwt>

Альтернативный способ передачи токена -- через WebSocket subprotocol:

Sec-WebSocket-Protocol: access_token.<jwt>

Типы сообщений

Обновление лидерборда:

{
  "type": "leaderboard_update",
  "payload": {
    "game_id": "uuid",
    "entries": [
      {"rank": 1, "team_name": "Team1", "rating": 1650}
    ]
  }
}

Обновление матча:

{
  "type": "match_update",
  "payload": {
    "match_id": "uuid",
    "status": "completed",
    "winner_id": "uuid",
    "score1": 1500,
    "score2": 1200
  }
}

Обновление раунда:

{
  "type": "round_update",
  "payload": {
    "game_id": "uuid",
    "round_status": "running",
    "round_number": 3
  }
}

Турнир завершён:

{
  "type": "tournament_completed",
  "payload": {
    "tournament_id": "uuid"
  }
}

GET /ws/stats 🔑 Требует авторизации

Получение статистики WebSocket-подключений (количество активных клиентов, подключения по турнирам и т.д.).

GET /ws/stats
Authorization: Bearer <token>

Ответ: 200 OK -- объект со статистикой подключений.


Система (System)

Базовый путь: /api/v1/system

Все эндпоинты доступны только администраторам.

GET /system/metrics 👑 Только администратор

Подробные метрики сервера: CPU, память, диск, Go runtime.

GET /system/metrics
Authorization: Bearer <token>

Ответ: 200 OK

{
  "cpu": {
    "usage_percent": 23.5,
    "cores": 8,
    "model_name": "Apple M1 Pro",
    "per_core": [15.2, 30.1, 22.0, ...]
  },
  "memory": {
    "total": 17179869184,
    "used": 8589934592,
    "free": 8589934592,
    "used_percent": 50.0
  },
  "disk": {
    "total": 500107862016,
    "used": 250053931008,
    "free": 250053931008,
    "used_percent": 50.0,
    "path": "/"
  },
  "host": {
    "hostname": "server-01",
    "platform": "darwin",
    "platform_version": "14.0",
    "os": "darwin",
    "arch": "arm64",
    "uptime": 86400
  },
  "go": {
    "version": "go1.24.0",
    "goroutines": 42,
    "heap_alloc": 10485760,
    "heap_sys": 20971520,
    "num_gc": 15,
    "gomaxprocs": 8
  },
  "temperature": [
    {"sensor_key": "CPU", "temperature": 55.0}
  ]
}

GET /system/health 👑 Только администратор

Проверка здоровья системы с диагностикой ресурсов.

GET /system/health
Authorization: Bearer <token>

Ответ: 200 OK

{
  "status": "healthy",
  "timestamp": "2026-03-17T12:00:00Z",
  "hostname": "server-01",
  "pid": 12345
}

Поле status может принимать значения: healthy, warning (при использовании памяти > 90%).


Ответы с ошибками

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Неверные данные",
    "details": {"field": "email", "reason": "неверный формат"}
  }
}
Код HTTP статус Описание
NOT_FOUND 404 Ресурс не найден
UNAUTHORIZED 401 Отсутствует/неверный токен
FORBIDDEN 403 Недостаточно прав
VALIDATION_ERROR 400 Неверные данные
CONFLICT 409 Конфликт ресурсов (напр. дубликат)
RATE_LIMITED 429 Слишком много запросов
INTERNAL_ERROR 500 Ошибка сервера

Лимиты запросов

  • Настраиваемый лимит запросов в минуту (через конфигурацию)
  • Ответ 429 Too Many Requests при превышении
  • Заголовок X-RateLimit-Remaining показывает оставшуюся квоту
  • Заголовок X-RateLimit-Reset показывает время сброса

Пагинация

API поддерживает пагинацию на основе limit и offset:

GET /tournaments?limit=20&offset=40
  • limit -- количество записей на странице (значение по умолчанию зависит от эндпоинта, обычно 50)
  • offset -- смещение от начала списка

Для некоторых эндпоинтов также поддерживается курсорная пагинация:

{
  "data": [...],
  "next_cursor": "eyJ...",
  "has_more": true
}

Передайте параметр cursor для получения следующей страницы.


Системные эндпоинты

Эндпоинты вне /api/v1, доступные без авторизации.

Health check

GET /health

Ответ: 200 OK с телом OK.

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

Метрики Prometheus

GET /metrics

Метрики в формате Prometheus для интеграции с системой мониторинга.

Статические файлы

GET /*

Все неопознанные маршруты обслуживают встроенный React SPA (single-page application) с fallback на index.html.


Сводная таблица эндпоинтов

Метод Путь Доступ Описание
Auth
POST /auth/register 🌐 Регистрация
POST /auth/login 🌐 Вход
POST /auth/refresh 🌐 Обновление токенов
POST /auth/logout 🔑 Выход
GET /auth/me 🔑 Текущий пользователь
PUT /auth/profile 🔑 Обновление профиля
Games
GET /games 🌐 Список игр
GET /games/{id} 🌐 Игра по ID
GET /games/name/{name} 🌐 Игра по имени
POST /games 👑 Создать игру
PUT /games/{id} 👑 Обновить игру
DELETE /games/{id} 👑 Удалить игру
Tournaments -- публичные
GET /tournaments 🌐 Список турниров
GET /tournaments/{id} 🌐 Турнир по ID
GET /tournaments/{id}/leaderboard 🌐 Лидерборд
GET /tournaments/{id}/cross-game-leaderboard 🌐 Кросс-игровой рейтинг
GET /tournaments/{id}/matches 🌐 Матчи турнира
GET /tournaments/{id}/matches/rounds 🌐 Матчи по раундам
GET /tournaments/{id}/games 🌐 Игры турнира
GET /tournaments/{id}/teams 🌐 Команды турнира
GET /tournaments/{id}/games/{gameId}/leaderboard 🌐 Лидерборд по игре
GET /tournaments/{id}/games/{gameId}/matches 🌐 Матчи по игре
GET /tournaments/{id}/games/status 🌐 Статус игр
GET /tournaments/{id}/active-game 🌐 Активная игра
Tournaments -- авторизация
POST /tournaments/{id}/join 🔑 Присоединиться
GET /tournaments/{id}/my-team 🔑 Моя команда
POST /tournaments/{id}/games 🔑 Добавить игру
Tournaments -- администрирование
POST /tournaments 👑 Создать турнир
POST /tournaments/{id}/start 👑 Запустить турнир
POST /tournaments/{id}/complete 👑 Завершить турнир
DELETE /tournaments/{id} 👑 Удалить турнир
POST /tournaments/{id}/matches 👑 Создать матч
DELETE /tournaments/{id}/games/{gameId} 👑 Удалить игру из турнира
GET /tournaments/{id}/games/{gameId}/programs 👑 Программы для игры
POST /tournaments/{id}/games/{gameId}/complete-round 👑 Завершить раунд
POST /tournaments/{id}/games/{gameId}/reset-round 👑 Сбросить раунд
POST /tournaments/{id}/games/{gameId}/auto-round 👑 Настроить авто-раунд
GET /tournaments/{id}/games/{gameId}/auto-round 👑 Статус авто-раунда
POST /tournaments/{id}/active-game 👑 Установить активную игру
POST /tournaments/{id}/games/deactivate-all 👑 Деактивировать все игры
POST /tournaments/{id}/run-matches 👑 Запустить все матчи
POST /tournaments/{id}/run-game-matches 👑 Запустить матчи по игре
POST /tournaments/{id}/retry-matches 👑 Перезапустить неудачные
POST /tournaments/{id}/programs/clear-errors 👑 Очистить ошибки программ
Teams
POST /teams 🔑 Создать команду
POST /teams/join 🔑 Вступить по коду
GET /teams/{id} 🔑 Получить команду
PUT /teams/{id} 🔑 Обновить название
GET /teams/{id}/members 🔑 Участники команды
POST /teams/{id}/leave 🔑 Покинуть команду
DELETE /teams/{id}/members/{userId} 🔑 Исключить участника
GET /teams/{id}/invite 🔑 Ссылка приглашения
DELETE /teams/{id} 👑 Удалить команду
Programs
POST /programs 🔑 Загрузить программу
GET /programs 🔑 Список программ
GET /programs/versions 🔑 Версии программ
GET /programs/{id} 🔑 Получить программу
GET /programs/{id}/download 🔑 Скачать программу
PUT /programs/{id} 🔑 Обновить программу
DELETE /programs/{id} 🔑 Удалить программу
Matches
GET /matches 🌐 Список матчей
GET /matches/{id} 🌐 Получить матч
GET /matches/statistics 🌐 Статистика матчей
GET /matches/queue/stats 👑 Статистика очереди
POST /matches/queue/clear 👑 Очистить очередь
POST /matches/queue/purge 👑 Удалить невалидные
WebSocket
GET /ws/tournaments/{id} 🔑 Real-time турнира
GET /ws/stats 🔑 Статистика WS
System
GET /system/metrics 👑 Метрики сервера
GET /system/health 👑 Здоровье системы

Версия документации: 4.0 Последнее обновление: Март 2026