{"openapi":"3.1.0","info":{"title":"matchcore1","version":"0.1.0"},"paths":{"/api/auth/signup":{"post":{"tags":["auth"],"summary":"Signup Handler","operationId":"signup_handler_api_auth_signup_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/signin":{"post":{"tags":["auth"],"summary":"Signin Handler","operationId":"signin_handler_api_auth_signin_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserLogin"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/confirm-email":{"get":{"tags":["auth"],"summary":"Confirm Email Handler","operationId":"confirm_email_handler_api_auth_confirm_email_get","parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/resend-confirmation":{"post":{"tags":["auth"],"summary":"Resend Confirmation Handler","operationId":"resend_confirmation_handler_api_auth_resend_confirmation_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/me":{"get":{"tags":["auth"],"summary":"Получить профиль текущего пользователя","operationId":"get_profile_api_auth_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRead"}}}}},"security":[{"HTTPBearer":[]}]},"put":{"tags":["auth"],"summary":"Обновить профиль (username, дата рождения, фото)","operationId":"update_profile_api_auth_me_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserUpdate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/auth/me/avatar":{"post":{"tags":["auth"],"summary":"Загрузить аватар через чанковый upload","description":"Применяет завершённую сессию чанковой загрузки как аватар профиля.\n\n**Шаги:**\n1. Инициализировать загрузку: `POST /api/v1/upload/init` (MIME: image/jpeg, image/png, image/gif, image/webp)\n2. Загрузить чанки: `POST /api/v1/upload/chunk`\n3. Применить аватар: `POST /api/auth/me/avatar` с `upload_id`\n\nМаксимальный размер файла: **5 МБ**.","operationId":"set_avatar_from_upload_api_auth_me_avatar_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/auth/me/avatar/direct":{"post":{"tags":["auth"],"summary":"Прямая загрузка аватара (без чанков, до 5 МБ)","description":"Загружает изображение аватара напрямую за один запрос.\n\n**Разрешённые форматы:** JPEG, PNG, GIF, WebP\n\n**Максимальный размер:** 5 МБ\n\nДля файлов больше 5 МБ используйте чанковую загрузку: `POST /api/auth/me/avatar`.","operationId":"upload_avatar_direct_api_auth_me_avatar_direct_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_avatar_direct_api_auth_me_avatar_direct_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/auth/change-password":{"post":{"tags":["auth"],"summary":"Сменить пароль (инвалидирует все сессии)","operationId":"change_password_api_auth_change_password_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePasswordRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePasswordResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]},{"HTTPBearer":[]}]}},"/api/auth/logout":{"post":{"tags":["auth"],"summary":"Выйти с текущего устройства","description":"Инвалидирует токен только текущего устройства. Необходимо передать **X-Device-ID** в заголовке или cookie `device_id`.","operationId":"logout_api_auth_logout_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LogoutResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/auth/logout-all":{"post":{"tags":["auth"],"summary":"Выйти со всех устройств","description":"Инвалидирует все активные токены пользователя.","operationId":"logout_all_api_auth_logout_all_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LogoutResponse"}}}}},"security":[{"HTTPBearer":[]},{"HTTPBearer":[]}]}},"/api/auth/account":{"delete":{"tags":["auth"],"summary":"Удалить аккаунт","operationId":"delete_account_handler_api_auth_account_delete","responses":{"204":{"description":"Successful Response"}},"security":[{"HTTPBearer":[]}]}},"/api/auth/tournaments":{"get":{"tags":["auth"],"summary":"Турниры профиля пользователя","description":"Получить список турниров текущего авторизованного пользователя по типу вкладки.\n\n    **Типы вкладок (параметр `type`):**\n    - `upcoming` — предстоящие: пользователь зарегистрирован + турнир ещё идёт\n      (статусы: REGISTRATION_OPEN, REGISTRATION_CLOSED, ONGOING)\n    - `past` — прошедшие: пользователь участвовал + турнир завершён (COMPLETED)\n    - `created` — созданные: все турниры, где пользователь является создателем (любой статус)\n\n    **Пагинация:**\n    - `page` — номер страницы (начиная с 1)\n    - `limit` — количество турниров на странице (1–50, по умолчанию 10)\n\n    **Сортировка:** по `event_date` ASC (ближайшие первыми) во всех трёх типах.\n\n    **Примеры:**\n    - `GET /api/v1/me/tournaments?type=upcoming` — предстоящие, первая страница\n    - `GET /api/v1/me/tournaments?type=past&page=2&limit=10` — прошедшие, страница 2\n    - `GET /api/v1/me/tournaments?type=created&page=1` — созданные турниры\n\n    **Требует авторизации:** `Authorization: Bearer {token}`","operationId":"get_user_tournaments_api_auth_tournaments_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"type","in":"query","required":true,"schema":{"type":"string","description":"Тип вкладки: upcoming | past | created","title":"Type"},"description":"Тип вкладки: upcoming | past | created"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Номер страницы (начиная с 1)","default":1,"title":"Page"},"description":"Номер страницы (начиная с 1)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Турниров на странице (1–50)","default":10,"title":"Limit"},"description":"Турниров на странице (1–50)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserTournamentsListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/restore-account":{"post":{"tags":["auth"],"summary":"Запросить восстановление удалённого аккаунта","description":"Отправляет письмо на оригинальный email с одноразовым токеном.\n\nВосстановление доступно в течение **30 дней** после удаления.\n\nОтвет всегда `{status: 'queued'}` независимо от наличия аккаунта.","operationId":"restore_account_handler_api_auth_restore_account_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RestoreAccountRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Restore Account Handler Api Auth Restore Account Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/confirm-restore":{"post":{"tags":["auth"],"summary":"Подтвердить восстановление аккаунта","description":"Принимает одноразовый токен из письма и восстанавливает аккаунт.","operationId":"confirm_restore_handler_api_auth_confirm_restore_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmRestoreRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/change-email/request":{"post":{"tags":["auth"],"summary":"Запросить смену email","description":"Проверяет пароль, проверяет занятость нового email, отправляет письмо подтверждения на **новый** адрес.\n\nОтвет: `{status: 'queued'}`.","operationId":"change_email_request_handler_api_auth_change_email_request_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangeEmailRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Change Email Request Handler Api Auth Change Email Request Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/auth/change-email/confirm":{"post":{"tags":["auth"],"summary":"Подтвердить смену email","description":"Принимает одноразовый токен из письма.\n\nПосле подтверждения все активные сессии инвалидируются — пользователь должен войти снова.","operationId":"change_email_confirm_handler_api_auth_change_email_confirm_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangeEmailConfirmRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/change-email/cancel":{"delete":{"tags":["auth"],"summary":"Отменить ожидающую смену email","operationId":"change_email_cancel_handler_api_auth_change_email_cancel_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Change Email Cancel Handler Api Auth Change Email Cancel Delete"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/auth/sessions":{"get":{"tags":["auth"],"summary":"Список активных сессий устройств","description":"Возвращает все активные сессии пользователя. `is_current=true` — текущее устройство.","operationId":"list_sessions_api_auth_sessions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserSessionsResponse"}}}}},"security":[{"HTTPBearer":[]},{"HTTPBearer":[]}]},"delete":{"tags":["auth"],"summary":"Завершить все сессии (алиас logout-all)","description":"Отзывает все активные сессии пользователя. Идентично `POST /auth/logout-all`.","operationId":"revoke_all_sessions_api_auth_sessions_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LogoutResponse"}}}}},"security":[{"HTTPBearer":[]},{"HTTPBearer":[]}]}},"/api/auth/sessions/{device_id}":{"delete":{"tags":["auth"],"summary":"Отозвать сессию конкретного устройства","description":"Завершает сессию выбранного устройства. Пользователь может отозвать любую из своих сессий, в том числе текущую.","operationId":"revoke_session_api_auth_sessions__device_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"device_id","in":"path","required":true,"schema":{"type":"string","title":"Device Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LogoutResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/users/{user_id}/status":{"patch":{"tags":["admin"],"summary":"Изменить статус пользователя (только STAFF)","operationId":"update_user_status_api_admin_users__user_id__status_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserStatusUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/users/{user_id}/status-history":{"get":{"tags":["admin"],"summary":"История изменений статуса пользователя (только STAFF)","operationId":"get_user_status_history_api_admin_users__user_id__status_history_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"integer","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UserStatusHistoryRead"},"title":"Response Get User Status History Api Admin Users  User Id  Status History Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/home/popular-games":{"get":{"tags":["home"],"summary":"Карусель 1: Популярные игры","description":"Топ игр по количеству турниров у которых **event_date попадает в ближайшие 7 дней**.\n\n    - Возвращает раздельно спортивные и киберспортивные игры\n    - Каждая карточка содержит `url_path` для перехода на страницу дисциплины\n    - При отсутствии данных — fallback: случайные активные игры\n    - Кэш: 15 минут (Redis)","operationId":"get_popular_games_api_v1_home_popular_games_get","parameters":[{"name":"sport_limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Макс спортивных игр","default":10,"title":"Sport Limit"},"description":"Макс спортивных игр"},{"name":"esport_limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Макс киберспортивных игр","default":10,"title":"Esport Limit"},"description":"Макс киберспортивных игр"},{"name":"use_cache","in":"query","required":false,"schema":{"type":"boolean","description":"Использовать Redis кэш","default":true,"title":"Use Cache"},"description":"Использовать Redis кэш"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PopularGamesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/home/open-registration":{"get":{"tags":["home"],"summary":"Карусель 2: Открытая регистрация","description":"Турниры со статусом **REGISTRATION_OPEN**, отсортированные по уровню (выше = популярнее)\n    и по дате события (ближайшие первыми).\n\n    - Максимум **2 турнира с одной игры**\n    - Максимум 20 турниров всего\n    - Каждая карточка содержит `url_path` для перехода на страницу турнира\n    - Кэш: 5 минут (Redis)","operationId":"get_open_registration_api_v1_home_open_registration_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":1,"description":"Макс турниров","default":20,"title":"Limit"},"description":"Макс турниров"},{"name":"use_cache","in":"query","required":false,"schema":{"type":"boolean","description":"Использовать Redis кэш","default":true,"title":"Use Cache"},"description":"Использовать Redis кэш"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenRegistrationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/home/new-tournaments":{"get":{"tags":["home"],"summary":"Карусель 3: Новые турниры","description":"Самые свежие турниры, отсортированные по **дате создания** (новые первыми).\n\n    - Исключаются: DRAFT, CANCELLED, неактивные\n    - Минималистичная карточка без изображения и без информации об игре\n    - Каждая карточка содержит `url_path` для перехода на страницу турнира\n    - Кэш: 10 минут (Redis)","operationId":"get_new_tournaments_api_v1_home_new_tournaments_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":1,"description":"Кол-во новых турниров","default":20,"title":"Limit"},"description":"Кол-во новых турниров"},{"name":"use_cache","in":"query","required":false,"schema":{"type":"boolean","description":"Использовать Redis кэш","default":true,"title":"Use Cache"},"description":"Использовать Redis кэш"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewTournamentsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/home/invalidate-cache":{"post":{"tags":["home"],"summary":"Инвалидировать кэш домашней страницы","description":"Очистить весь кэш каруселей (для разработки/администрирования)","operationId":"invalidate_home_cache_api_v1_home_invalidate_cache_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/games":{"get":{"tags":["games"],"summary":"Получить список игр","description":"Получить список активных игр с пагинацией, фильтрацией по типу и полнотекстовым поиском.\n\n    **Параметры:**\n    - **page**: Номер страницы (по умолчанию 1)\n    - **page_size**: Элементов на странице (10-100, по умолчанию 20)\n    - **game_type**: Типы игр через запятую (SPORT, ESPORTS или оба; по умолчанию оба)\n    - **sort_by**: Сортировка (tournaments - по кол-ву, name - по названию, recent - по дате)\n    - **search**: Поиск по названию и описанию (опционально)\n\n    **Примеры:**\n    - `GET /api/v1/games?page=1` - первая страница всех игр\n    - `GET /api/v1/games?game_type=SPORT` - только спортивные игры\n    - `GET /api/v1/games?game_type=ESPORTS` - только киберспортивные игры\n    - `GET /api/v1/games?search=dota&page=1` - поиск по названию/описанию\n    - `GET /api/v1/games?sort_by=name` - сортировка по названию\n\n    **Сортировка по умолчанию:** по количеству турниров (DESC)","operationId":"list_games_api_v1_games_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Номер страницы","default":1,"title":"Page"},"description":"Номер страницы"},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":10,"description":"Элементов на странице","default":20,"title":"Page Size"},"description":"Элементов на странице"},{"name":"game_type","in":"query","required":false,"schema":{"type":"string","description":"Типы игр через запятую: SPORT,ESPORTS","title":"Game Type"},"description":"Типы игр через запятую: SPORT,ESPORTS"},{"name":"search","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":255,"description":"Встроенный LIKE поиск","title":"Search"},"description":"Встроенный LIKE поиск"},{"name":"sort_by","in":"query","required":false,"schema":{"type":"string","description":"Сортировка: tournaments, name, recent","default":"tournaments","title":"Sort By"},"description":"Сортировка: tournaments, name, recent"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GameListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tournaments":{"post":{"tags":["tournaments"],"summary":"Создать черновик турнира","description":"Создаёт новый турнир со статусом **DRAFT**.\n\n    После создания фронтенд перенаправляет пользователя на `/tournaments/{slug}`.\n\n    **Требуется аутентификация.**","operationId":"create_tournament_api_v1_tournaments_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTournamentRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTournamentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/tournaments/game/{game_slug}":{"get":{"tags":["tournaments"],"summary":"Список турниров по дисциплине","description":"Список активных турниров для дисциплины с пагинацией, фильтрацией и поиском.\n\n    **filter_stage** — семантический фильтр по этапу:\n    - `upcoming` — предстоящие (PUBLISHED, REGISTRATION_OPEN, REGISTRATION_CLOSED)\n    - `current` — текущие (ONGOING)\n    - `completed` — завершённые (COMPLETED)\n\n    **sort_by** — сортировка:\n    - `date` — по дате события (ASC)\n    - `level` — по уровню подписки (DESC) + дата (ASC)\n    - по умолчанию умная сортировка: текущие → предстоящие → завершённые\n\n    **Публичный эндпоинт, без аутентификации.**","operationId":"list_tournaments_api_v1_tournaments_game__game_slug__get","parameters":[{"name":"game_slug","in":"path","required":true,"schema":{"type":"string","title":"Game Slug"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Номер страницы","default":1,"title":"Page"},"description":"Номер страницы"},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":10,"description":"Элементов на странице","default":20,"title":"Page Size"},"description":"Элементов на странице"},{"name":"sort_by","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Сортировка: date, level или None (дефолт)","title":"Sort By"},"description":"Сортировка: date, level или None (дефолт)"},{"name":"filter_stage","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Фильтр по этапу: upcoming, current, completed","title":"Filter Stage"},"description":"Фильтр по этапу: upcoming, current, completed"},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string","minLength":1,"maxLength":255},{"type":"null"}],"description":"Поиск по названию/описанию","title":"Search"},"description":"Поиск по названию/описанию"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TournamentListResponse"}}}},"500":{"description":"Внутренняя ошибка сервера"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tournaments/{slug}":{"get":{"tags":["tournaments"],"summary":"Информация о турнире","description":"Полная информация о турнире по slug.\n\n    **Публичный эндпоинт.**\n    DRAFT видны только владельцу — остальные получают 404.","operationId":"get_tournament_detail_api_v1_tournaments__slug__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TournamentDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["tournaments"],"summary":"Обновить настройки турнира (Settings)","description":"Обновить поля турнира со страницы **настроек**.\n\n    Можно менять: `title`, `description`, `event_date`, `player_limit`,\n    `cover_url`, `background_image`, `tag`, `addition`, `contact`,\n    `translations`, `registration_closed_at`, `ended_at`.\n\n    Поле `game_id` **не изменяется**.\n    Чтобы снять ограничение участников — передать `\"remove_player_limit\": true`.\n\n    **Доступно: owner, администраторы турнира, staff платформы.**","operationId":"update_tournament_settings_api_v1_tournaments__slug__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTournamentRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TournamentDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["tournaments"],"summary":"Удалить турнир (мягкое удаление)","description":"Мягкое удаление: `status` → `DELETED`, `is_active` → `false`.\n    Турнир полностью исчезает из API. Действие **необратимо**.\n\n    Изменение записывается в журнал истории статусов.\n\n    **Только для владельца турнира.**","operationId":"delete_tournament_api_v1_tournaments__slug__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tournaments/{slug}/registrations":{"get":{"tags":["tournaments"],"summary":"Список зарегистрировавшихся","description":"Все зарегистрировавшиеся участники турнира.\n\n    **Публичный эндпоинт** — виден всем, включая неавторизованных.\n    Для владельца, администраторов турнира и платформенных администраторов\n    дополнительно возвращается поле `is_banned` для каждого участника.\n    Пагинация не используется.","operationId":"get_tournament_registrations_api_v1_tournaments__slug__registrations_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TournamentRegistrationsListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tournaments/{slug}/export":{"get":{"tags":["tournaments"],"summary":"Выгрузка регистраций (xlsx/csv)","description":"Выгрузить список участников в файл (xlsx или csv).\n\n    **Только для владельца и платформенных администраторов (is_staff).**","operationId":"export_tournament_registrations_api_v1_tournaments__slug__export_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","description":"Формат: xlsx или csv","default":"xlsx","title":"Format"},"description":"Формат: xlsx или csv"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tournaments/{slug}/status":{"patch":{"tags":["tournaments"],"summary":"Изменить статус турнира","description":"Ручное изменение статуса турнира. Допустимые переходы:\n\n    | Из | В | Действие |\n    |---|---|---|\n    | `DRAFT` | `PUBLISHED` | Опубликовать черновик |\n    | `PUBLISHED` | `CANCELLED` | Отменить турнир |\n    | `CANCELLED` | `PUBLISHED` | Восстановить турнир |\n\n    Переходы `REGISTRATION_OPEN`, `ONGOING`, `COMPLETED` — **автоматические** по времени.\n\n    **Только для владельца турнира.**","operationId":"change_tournament_status_api_v1_tournaments__slug__status_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangeStatusRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TournamentDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tournaments/{slug}/administrators":{"get":{"tags":["tournaments"],"summary":"Список администраторов турнира","description":"Публичный список администраторов турнира.","operationId":"get_tournament_administrators_api_v1_tournaments__slug__administrators_get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TournamentAdminsListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["tournaments"],"summary":"Добавить администратора","description":"Назначить пользователя администратором турнира.\n\n**Только для owner турнира и platform staff (is_staff).**\nАдминистраторы турнира НЕ могут добавлять других администраторов.\n\nНельзя назначить владельца турнира администратором.","operationId":"add_tournament_administrator_api_v1_tournaments__slug__administrators_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddAdminRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TournamentAdminRef"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tournaments/{slug}/administrators/{admin_id}":{"delete":{"tags":["tournaments"],"summary":"Удалить администратора","description":"Снять права администратора турнира с пользователя.\n\n**Только для owner турнира и platform staff (is_staff).**\nАдминистраторы турнира НЕ могут удалять других администраторов.","operationId":"remove_tournament_administrator_api_v1_tournaments__slug__administrators__admin_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"admin_id","in":"path","required":true,"schema":{"type":"integer","title":"Admin Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tournaments/{slug}/administrators/history":{"get":{"tags":["tournaments"],"summary":"История назначений/отзывов администраторов","description":"Полная история. **Только для owner турнира и platform staff.**","operationId":"get_admin_history_api_v1_tournaments__slug__administrators_history_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TournamentAdminHistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tournaments/{slug}/bans":{"get":{"tags":["tournaments"],"summary":"Текущие баны турнира","description":"Список активных банов. **Только для owner, admin турнира и platform staff.**","operationId":"get_active_bans_api_v1_tournaments__slug__bans_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TournamentBansListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tournaments/{slug}/bans/history":{"get":{"tags":["tournaments"],"summary":"История банов/разбанов турнира","description":"Полная история банов. **Только для owner турнира и platform staff.**","operationId":"get_ban_history_api_v1_tournaments__slug__bans_history_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TournamentBanHistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tournaments/{slug}/registrations/{registration_id}":{"patch":{"tags":["tournaments"],"summary":"Обновить регистрацию участника","description":"Обновить данные регистрации участника (ответы на форму, check-in).\n\n**Изменяемые поля:** `answers`, `checked_in`, `checked_in_at`.\n\n**Нельзя менять:** `id`, `user_id`, `tournament_id`, `status`, `submitted_at`, `created_at`.\n\n**Только для owner, администратора турнира и platform admin.**","operationId":"update_registration_api_v1_tournaments__slug__registrations__registration_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"registration_id","in":"path","required":true,"schema":{"type":"integer","title":"Registration Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRegistrationRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tournaments/{slug}/registrations/{registration_id}/cancel":{"post":{"tags":["tournaments"],"summary":"Отменить регистрацию участника","description":"Отменить регистрацию участника на турнире без блокировки.\n\n- Статус регистрации → `CANCELLED`.\n- Участник не блокируется и может повторно зарегистрироваться.\n\n**Только для owner, администратора турнира и platform admin.**","operationId":"cancel_registration_api_v1_tournaments__slug__registrations__registration_id__cancel_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"registration_id","in":"path","required":true,"schema":{"type":"integer","title":"Registration Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tournaments/{slug}/registrations/{registration_id}/ban":{"post":{"tags":["tournaments"],"summary":"Заблокировать участника","description":"Заблокировать участника на турнире.\n\n- Добавляет пользователя в список `banned_players`.\n- Отменяет его активную регистрацию (статус → CANCELLED).\n- Заблокированный пользователь не сможет повторно зарегистрироваться.\n\n**Только для owner, администратора турнира и platform admin.**","operationId":"ban_player_api_v1_tournaments__slug__registrations__registration_id__ban_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"registration_id","in":"path","required":true,"schema":{"type":"integer","title":"Registration Id"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/BanPlayerRequest"},{"type":"null"}],"title":"Body"}}}},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tournaments/{slug}/registrations/{registration_id}/unban":{"post":{"tags":["tournaments"],"summary":"Разблокировать участника","description":"Снять блокировку с участника на турнире.\n\n- Удаляет пользователя из списка `banned_players`.\n- Пользователь сможет снова зарегистрироваться.\n\n**Только для owner, администратора турнира и platform admin.**","operationId":"unban_player_api_v1_tournaments__slug__registrations__registration_id__unban_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"registration_id","in":"path","required":true,"schema":{"type":"integer","title":"Registration Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tournaments/{slug}/registrations/{registration_id}/approve":{"post":{"tags":["tournaments"],"summary":"Подтвердить заявку на турнир","description":"Переводит заявку из `SUBMITTED` или `WAITLIST` в `APPROVED`.\n\n**Только для owner, администратора турнира и platform admin.**","operationId":"approve_registration_api_v1_tournaments__slug__registrations__registration_id__approve_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"registration_id","in":"path","required":true,"schema":{"type":"integer","title":"Registration Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tournaments/{slug}/registrations/{registration_id}/reject":{"post":{"tags":["tournaments"],"summary":"Отклонить заявку на турнир","description":"Переводит заявку в `REJECTED`. Можно указать причину.\n\n**Только для owner, администратора турнира и platform admin.**","operationId":"reject_registration_api_v1_tournaments__slug__registrations__registration_id__reject_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"registration_id","in":"path","required":true,"schema":{"type":"integer","title":"Registration Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RejectRegistrationRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tournaments/{tournament_id}/registration/start":{"get":{"tags":["registration-flow"],"summary":"Начать регистрацию на турнир","description":"Инициализирует регистрацию авторизованного пользователя на турнир.\n    Возвращает первый раздел формы и session_id.","operationId":"start_registration_api_v1_tournaments__tournament_id__registration_start_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"tournament_id","in":"path","required":true,"schema":{"type":"integer","title":"Tournament Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationStartResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tournaments/{tournament_id}/registration/sections/{section_id}/submit":{"post":{"tags":["registration-flow"],"summary":"Отправить ответы раздела","description":"Сохраняет ответы пользователя на вопросы раздела.\n    Определяет следующий раздел (или завершает регистрацию).\n    При конфликте версии формы возвращает 409.","operationId":"submit_section_api_v1_tournaments__tournament_id__registration_sections__section_id__submit_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"tournament_id","in":"path","required":true,"schema":{"type":"integer","title":"Tournament Id"}},{"name":"section_id","in":"path","required":true,"schema":{"type":"integer","title":"Section Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SectionSubmitRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SectionSubmitResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tournaments/{tournament_id}/registration/go-back":{"post":{"tags":["registration-flow"],"summary":"Вернуться к предыдущему разделу","operationId":"go_back_api_v1_tournaments__tournament_id__registration_go_back_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"tournament_id","in":"path","required":true,"schema":{"type":"integer","title":"Tournament Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoBackRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoBackResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/registrations/{registration_id}":{"delete":{"tags":["registration-flow"],"summary":"Отменить собственную заявку на турнир","description":"Игрок отменяет свою регистрацию.\n\nСтатус переходит в `CANCELLED`. Если заявка была `APPROVED`, первый в листе ожидания автоматически получает `APPROVED`.","operationId":"cancel_own_registration_api_v1_me_registrations__registration_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"registration_id","in":"path","required":true,"schema":{"type":"integer","title":"Registration Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tournaments/{tournament_id}/registration-form":{"get":{"tags":["registration-forms"],"summary":"Получить форму регистрации турнира","operationId":"get_tournament_form_api_v1_tournaments__tournament_id__registration_form_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"tournament_id","in":"path","required":true,"schema":{"type":"integer","title":"Tournament Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationFormResponse"}}}},"403":{"description":"Недостаточно прав"},"404":{"description":"Ресурс не найден"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["registration-forms"],"summary":"Создать новую форму регистрации для турнира","operationId":"create_tournament_form_api_v1_tournaments__tournament_id__registration_form_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"tournament_id","in":"path","required":true,"schema":{"type":"integer","title":"Tournament Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationFormCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationFormResponse"}}}},"403":{"description":"Недостаточно прав"},"404":{"description":"Ресурс не найден"},"409":{"description":"Ресурс уже существует"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["registration-forms"],"summary":"Обновить форму регистрации турнира","operationId":"update_tournament_form_api_v1_tournaments__tournament_id__registration_form_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"tournament_id","in":"path","required":true,"schema":{"type":"integer","title":"Tournament Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationFormUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationFormResponse"}}}},"403":{"description":"Недостаточно прав"},"404":{"description":"Ресурс не найден"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["registration-forms"],"summary":"Удалить форму регистрации турнира","operationId":"delete_tournament_form_api_v1_tournaments__tournament_id__registration_form_delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"tournament_id","in":"path","required":true,"schema":{"type":"integer","title":"Tournament Id"}}],"responses":{"204":{"description":"Successful Response"},"403":{"description":"Недостаточно прав"},"404":{"description":"Ресурс не найден"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tournaments/{tournament_id}/registration-form/from-template/{template_id}":{"post":{"tags":["registration-forms"],"summary":"Создать форму турнира из шаблона","operationId":"create_form_from_template_api_v1_tournaments__tournament_id__registration_form_from_template__template_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"tournament_id","in":"path","required":true,"schema":{"type":"integer","title":"Tournament Id"}},{"name":"template_id","in":"path","required":true,"schema":{"type":"integer","title":"Template Id"}}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationFormResponse"}}}},"403":{"description":"Недостаточно прав"},"404":{"description":"Ресурс не найден"},"409":{"description":"Ресурс уже существует"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tournaments/{tournament_id}/registration-form/rename":{"put":{"tags":["registration-forms"],"summary":"Переименовать форму регистрации турнира","operationId":"rename_tournament_form_api_v1_tournaments__tournament_id__registration_form_rename_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"tournament_id","in":"path","required":true,"schema":{"type":"integer","title":"Tournament Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationFormRename"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationFormResponse"}}}},"403":{"description":"Недостаточно прав"},"404":{"description":"Ресурс не найден"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tournaments/{tournament_id}/registration-form/apply":{"post":{"tags":["registration-forms"],"summary":"Применить форму из библиотеки к турниру","description":"Применяет форму (шаблон или форму другого турнира) к данному турниру.\n    Если у турнира уже есть форма без завершённых регистраций — она будет заменена.\n    Если есть завершённые регистрации — 409 Conflict.","operationId":"apply_form_to_tournament_api_v1_tournaments__tournament_id__registration_form_apply_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"tournament_id","in":"path","required":true,"schema":{"type":"integer","title":"Tournament Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplyFormRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationFormResponse"}}}},"403":{"description":"Недостаточно прав"},"404":{"description":"Ресурс не найден"},"409":{"description":"Ресурс уже существует"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/registration-forms/library":{"get":{"tags":["registration-forms"],"summary":"Библиотека форм: шаблоны и формы турниров пользователя","operationId":"get_library_api_v1_registration_forms_library_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"filter","in":"query","required":false,"schema":{"type":"string","pattern":"^(all|templates|my_forms)$","default":"all","title":"Filter"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LibraryResponse"}}}},"403":{"description":"Недостаточно прав"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/registration-forms/{form_id}/save-as-template":{"post":{"tags":["registration-forms"],"summary":"Сохранить форму как шаблон в библиотеку","operationId":"save_as_template_api_v1_registration_forms__form_id__save_as_template_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"form_id","in":"path","required":true,"schema":{"type":"integer","title":"Form Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveAsTemplateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationFormResponse"}}}},"403":{"description":"Недостаточно прав"},"404":{"description":"Ресурс не найден"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/registration-forms/templates":{"get":{"tags":["registration-forms"],"summary":"Список своих шаблонов форм","operationId":"list_my_templates_api_v1_registration_forms_templates_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/RegistrationFormSummary"},"type":"array","title":"Response List My Templates Api V1 Registration Forms Templates Get"}}}},"403":{"description":"Недостаточно прав"}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["registration-forms"],"summary":"Создать новый шаблон формы","operationId":"create_template_api_v1_registration_forms_templates_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationFormCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationFormResponse"}}}},"403":{"description":"Недостаточно прав"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/registration-forms/templates/from-tournament/{tournament_id}":{"post":{"tags":["registration-forms"],"summary":"Сохранить форму турнира как шаблон","operationId":"save_form_as_template_api_v1_registration_forms_templates_from_tournament__tournament_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"tournament_id","in":"path","required":true,"schema":{"type":"integer","title":"Tournament Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationFormRename"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationFormResponse"}}}},"403":{"description":"Недостаточно прав"},"404":{"description":"Ресурс не найден"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/registration-forms/templates/{template_id}":{"get":{"tags":["registration-forms"],"summary":"Получить шаблон формы","operationId":"get_template_api_v1_registration_forms_templates__template_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"integer","title":"Template Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationFormResponse"}}}},"403":{"description":"Недостаточно прав"},"404":{"description":"Ресурс не найден"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["registration-forms"],"summary":"Обновить шаблон формы","operationId":"update_template_api_v1_registration_forms_templates__template_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"integer","title":"Template Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationFormUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationFormResponse"}}}},"403":{"description":"Недостаточно прав"},"404":{"description":"Ресурс не найден"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["registration-forms"],"summary":"Удалить шаблон формы","description":"Удаляет шаблон формы.\n\n**Важно (11.4):** удаляется только сам шаблон. Копии, ранее применённые\nк турнирам через `apply_form_to_tournament`, остаются и продолжают работать\nнезависимо (у них tournament_id IS NOT NULL).","operationId":"delete_template_api_v1_registration_forms_templates__template_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"integer","title":"Template Id"}}],"responses":{"204":{"description":"Successful Response"},"403":{"description":"Недостаточно прав"},"404":{"description":"Ресурс не найден"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/registration-forms/templates/{template_id}/rename":{"put":{"tags":["registration-forms"],"summary":"Переименовать шаблон формы","operationId":"rename_template_api_v1_registration_forms_templates__template_id__rename_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"integer","title":"Template Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationFormRename"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationFormResponse"}}}},"403":{"description":"Недостаточно прав"},"404":{"description":"Ресурс не найден"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/upload/init":{"post":{"tags":["file-upload"],"summary":"Инициализировать загрузку файла","description":"Создаёт сессию чанковой загрузки. Проверяет тип файла и размер.\n\n    **Разрешённые типы:** JPEG, PNG, GIF, WebP, PDF, DOCX, DOC\n\n    **Максимальный размер:** 7.5 МБ","operationId":"init_upload_api_v1_upload_init_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileUploadInitRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileUploadInitResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/upload/chunk":{"post":{"tags":["file-upload"],"summary":"Загрузить чанк (часть файла)","description":"Принимает один чанк файла. После загрузки всех чанков файл автоматически собирается.\n\n    **Параметры формы:**\n    - `upload_id` — ID сессии загрузки (из /init)\n    - `chunk_index` — порядковый номер чанка (0-based)\n    - `chunk` — бинарные данные чанка","operationId":"upload_chunk_api_v1_upload_chunk_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_chunk_api_v1_upload_chunk_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChunkUploadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/upload/{upload_id}/status":{"get":{"tags":["file-upload"],"summary":"Статус загрузки файла","operationId":"get_upload_status_api_v1_upload__upload_id__status_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"upload_id","in":"path","required":true,"schema":{"type":"string","title":"Upload Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChunkUploadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"AddAdminRequest":{"properties":{"username":{"type":"string","maxLength":32,"minLength":1,"title":"Username","description":"Username пользователя"}},"type":"object","required":["username"],"title":"AddAdminRequest","description":"Запрос на добавление администратора","example":{"username":"pro_player"}},"AnswerPayload":{"properties":{"question_id":{"type":"integer","title":"Question Id"},"answer_text":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Answer Text"},"answer_number":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Answer Number"},"answer_single":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Answer Single"},"answer_multiple":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Answer Multiple"},"file_upload_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Upload Id"}},"type":"object","required":["question_id"],"title":"AnswerPayload","description":"Ответ на один вопрос."},"ApplyFormRequest":{"properties":{"form_id":{"type":"integer","title":"Form Id"}},"type":"object","required":["form_id"],"title":"ApplyFormRequest","description":"Применить форму из библиотеки к турниру."},"BanPlayerRequest":{"properties":{"reason":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Reason","description":"Причина блокировки"}},"type":"object","title":"BanPlayerRequest","description":"Тело запроса для бана участника (reason — необязательно)","example":{"reason":"Нарушение правил турнира"}},"Body_upload_avatar_direct_api_auth_me_avatar_direct_post":{"properties":{"file":{"type":"string","format":"binary","title":"File","description":"Файл изображения аватара"}},"type":"object","required":["file"],"title":"Body_upload_avatar_direct_api_auth_me_avatar_direct_post"},"Body_upload_chunk_api_v1_upload_chunk_post":{"properties":{"upload_id":{"type":"string","title":"Upload Id"},"chunk_index":{"type":"integer","title":"Chunk Index"},"chunk":{"type":"string","format":"binary","title":"Chunk"}},"type":"object","required":["upload_id","chunk_index","chunk"],"title":"Body_upload_chunk_api_v1_upload_chunk_post"},"ChangeEmailConfirmRequest":{"properties":{"token":{"type":"string","title":"Token"}},"type":"object","required":["token"],"title":"ChangeEmailConfirmRequest","description":"Подтверждение смены email по одноразовому токену."},"ChangeEmailRequest":{"properties":{"new_email":{"type":"string","format":"email","title":"New Email"},"password":{"type":"string","maxLength":128,"minLength":8,"title":"Password"}},"type":"object","required":["new_email","password"],"title":"ChangeEmailRequest","description":"Запрос на смену email: проверяем пароль и создаём токен подтверждения."},"ChangePasswordRequest":{"properties":{"current_password":{"type":"string","maxLength":128,"minLength":8,"title":"Current Password"},"new_password":{"type":"string","maxLength":128,"minLength":8,"title":"New Password"},"new_password_confirm":{"type":"string","maxLength":128,"minLength":8,"title":"New Password Confirm"}},"type":"object","required":["current_password","new_password","new_password_confirm"],"title":"ChangePasswordRequest"},"ChangePasswordResponse":{"properties":{"detail":{"type":"string","title":"Detail","default":"Password changed successfully"}},"type":"object","title":"ChangePasswordResponse"},"ChangeStatusRequest":{"properties":{"status":{"type":"string","title":"Status","description":"Новый статус: PUBLISHED, CANCELLED"}},"type":"object","required":["status"],"title":"ChangeStatusRequest","description":"Запрос для изменения статуса турнира","example":{"status":"PUBLISHED"}},"ChunkUploadResponse":{"properties":{"upload_id":{"type":"string","title":"Upload Id"},"received_chunks":{"type":"integer","title":"Received Chunks"},"total_chunks":{"type":"integer","title":"Total Chunks"},"is_completed":{"type":"boolean","title":"Is Completed"}},"type":"object","required":["upload_id","received_chunks","total_chunks","is_completed"],"title":"ChunkUploadResponse"},"ConfirmRestoreRequest":{"properties":{"token":{"type":"string","title":"Token"}},"type":"object","required":["token"],"title":"ConfirmRestoreRequest","description":"Подтверждение восстановления аккаунта по одноразовому токену."},"CreateTournamentRequest":{"properties":{"title":{"type":"string","maxLength":255,"minLength":3,"title":"Title","description":"Название турнира"},"game_id":{"type":"integer","exclusiveMinimum":0.0,"title":"Game Id","description":"ID дисциплины (игры)"},"participation_type":{"type":"string","title":"Participation Type","description":"Формат участия: PLAYERS, TEAMS, PLAYERS_AND_TEAMS"},"event_date":{"type":"string","format":"date-time","title":"Event Date","description":"Дата и время начала турнира (ISO 8601)"},"ended_at":{"type":"string","format":"date-time","title":"Ended At","description":"Дата и время окончания турнира (ISO 8601)"},"team_size":{"anyOf":[{"type":"integer","maximum":1000.0,"minimum":2.0},{"type":"null"}],"title":"Team Size","description":"Кол-во игроков в команде (только для TEAMS / PLAYERS_AND_TEAMS)"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags","description":"Список тегов турнира"}},"type":"object","required":["title","game_id","participation_type","event_date","ended_at"],"title":"CreateTournamentRequest","description":"Запрос для создания турнира (черновик)","example":{"ended_at":"2026-06-17T18:00:00+00:00","event_date":"2026-06-15T18:00:00+00:00","game_id":1,"participation_type":"PLAYERS","tags":["1v1","open","summer"],"title":"Desert Strike 1v1 Championship"}},"CreateTournamentResponse":{"properties":{"id":{"type":"integer","title":"Id","description":"ID создаваемого турнира"},"slug":{"type":"string","title":"Slug","description":"URL-friendly slug турнира"},"title":{"type":"string","title":"Title","description":"Название турнира"},"event_date":{"type":"string","format":"date-time","title":"Event Date","description":"Дата начала"},"ended_at":{"type":"string","format":"date-time","title":"Ended At","description":"Дата окончания"},"stage":{"type":"string","title":"Stage","description":"Этап турнира (всегда DRAFT при создании)"},"participation_type":{"type":"string","title":"Participation Type","description":"Формат участия"},"team_size":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Team Size","description":"Игроков в команде"},"player_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Player Limit","description":"Максимальное количество участников (null = неограниченно)"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags","description":"Теги турнира"},"game_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Game Id","description":"ID дисциплины"},"owner_id":{"type":"integer","title":"Owner Id","description":"ID владельца турнира"}},"type":"object","required":["id","slug","title","event_date","ended_at","stage","participation_type","game_id","owner_id"],"title":"CreateTournamentResponse","description":"Ответ при создании турнира"},"FileUploadInitRequest":{"properties":{"filename":{"type":"string","maxLength":500,"title":"Filename"},"file_size":{"type":"integer","exclusiveMinimum":0.0,"title":"File Size"},"mime_type":{"type":"string","title":"Mime Type"}},"type":"object","required":["filename","file_size","mime_type"],"title":"FileUploadInitRequest"},"FileUploadInitResponse":{"properties":{"upload_id":{"type":"string","title":"Upload Id"},"chunk_size":{"type":"integer","title":"Chunk Size"}},"type":"object","required":["upload_id","chunk_size"],"title":"FileUploadInitResponse"},"FormQuestionCreate":{"properties":{"title":{"type":"string","maxLength":255,"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"question_type":{"type":"string","title":"Question Type"},"required":{"type":"boolean","title":"Required","default":false},"order":{"type":"integer","minimum":1.0,"title":"Order","default":1},"is_routing_question":{"type":"boolean","title":"Is Routing Question","default":false},"go_to_section_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Go To Section Id"},"options":{"items":{"$ref":"#/components/schemas/QuestionOptionCreate"},"type":"array","title":"Options"}},"type":"object","required":["title","question_type"],"title":"FormQuestionCreate"},"FormQuestionResponse":{"properties":{"title":{"type":"string","maxLength":255,"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"question_type":{"type":"string","title":"Question Type"},"required":{"type":"boolean","title":"Required","default":false},"order":{"type":"integer","minimum":1.0,"title":"Order","default":1},"is_routing_question":{"type":"boolean","title":"Is Routing Question","default":false},"go_to_section_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Go To Section Id"},"id":{"type":"integer","title":"Id"},"options":{"items":{"$ref":"#/components/schemas/QuestionOptionResponse"},"type":"array","title":"Options","default":[]}},"type":"object","required":["title","question_type","id"],"title":"FormQuestionResponse"},"FormSectionCreate":{"properties":{"title":{"type":"string","maxLength":255,"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"order":{"type":"integer","minimum":1.0,"title":"Order","default":1},"default_next_section_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Default Next Section Id"},"ends_registration":{"type":"boolean","title":"Ends Registration","default":false},"questions":{"items":{"$ref":"#/components/schemas/FormQuestionCreate"},"type":"array","title":"Questions"}},"type":"object","required":["title"],"title":"FormSectionCreate"},"FormSectionResponse":{"properties":{"title":{"type":"string","maxLength":255,"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"order":{"type":"integer","minimum":1.0,"title":"Order","default":1},"default_next_section_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Default Next Section Id"},"ends_registration":{"type":"boolean","title":"Ends Registration","default":false},"id":{"type":"integer","title":"Id"},"questions":{"items":{"$ref":"#/components/schemas/FormQuestionResponse"},"type":"array","title":"Questions","default":[]}},"type":"object","required":["title","id"],"title":"FormSectionResponse"},"GameDetailRef":{"properties":{"id":{"type":"integer","title":"Id"},"title":{"type":"string","title":"Title"},"slug":{"type":"string","title":"Slug"},"cover_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cover Url"},"background_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Background Image"}},"type":"object","required":["id","title","slug"],"title":"GameDetailRef","description":"Игра на странице детали турнира"},"GameListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/GameResponse"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total","description":"Общее количество элементов"},"page":{"type":"integer","title":"Page","description":"Текущая страница"},"page_size":{"type":"integer","title":"Page Size","description":"Элементов на странице"},"total_pages":{"type":"integer","title":"Total Pages","description":"Всего страниц"},"has_next":{"type":"boolean","title":"Has Next","description":"Есть ли следующая страница"},"has_previous":{"type":"boolean","title":"Has Previous","description":"Есть ли предыдущая страница"}},"type":"object","required":["items","total","page","page_size","total_pages","has_next","has_previous"],"title":"GameListResponse","description":"Ответ со списком игр и информацией о пагинации"},"GameRef":{"properties":{"id":{"type":"integer","title":"Id"},"title":{"type":"string","title":"Title"},"slug":{"type":"string","title":"Slug"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"cover_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cover Url"},"background_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Background Image"}},"type":"object","required":["id","title","slug"],"title":"GameRef","description":"Игра в контексте турнира"},"GameRefCard":{"properties":{"id":{"type":"integer","title":"Id"},"title":{"type":"string","title":"Title"},"slug":{"type":"string","title":"Slug"},"game_type":{"type":"string","title":"Game Type"}},"type":"object","required":["id","title","slug","game_type"],"title":"GameRefCard","description":"Краткая информация об игре внутри карточки турнира.\n\nНет cover_url / background_image — не нужны внутри карточки турнира."},"GameResponse":{"properties":{"id":{"type":"integer","title":"Id"},"title":{"type":"string","title":"Title"},"slug":{"type":"string","title":"Slug"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"cover_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cover Url"},"background_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Background Image"},"game_type":{"type":"string","title":"Game Type"},"is_active":{"type":"boolean","title":"Is Active"}},"type":"object","required":["id","title","slug","game_type","is_active"],"title":"GameResponse","description":"Игра в списке"},"GoBackRequest":{"properties":{"session_id":{"type":"string","title":"Session Id"}},"type":"object","required":["session_id"],"title":"GoBackRequest"},"GoBackResponse":{"properties":{"section":{"$ref":"#/components/schemas/FormSectionResponse"},"current_section_number":{"type":"integer","title":"Current Section Number"},"total_sections":{"type":"integer","title":"Total Sections"},"previous_answers":{"items":{"$ref":"#/components/schemas/AnswerPayload"},"type":"array","title":"Previous Answers","default":[]}},"type":"object","required":["section","current_section_number","total_sections"],"title":"GoBackResponse"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"LibraryFormItem":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"version":{"type":"integer","title":"Version"},"is_template":{"type":"boolean","title":"Is Template"},"tournament_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tournament Id"},"tournament_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tournament Name"},"created_at":{"title":"Created At"},"updated_at":{"title":"Updated At"},"responses_count":{"type":"integer","title":"Responses Count","default":0}},"type":"object","required":["id","name","version","is_template","created_at","updated_at"],"title":"LibraryFormItem","description":"Элемент библиотеки форм (шаблоны + формы турниров пользователя)."},"LibraryResponse":{"properties":{"forms":{"items":{"$ref":"#/components/schemas/LibraryFormItem"},"type":"array","title":"Forms"},"total":{"type":"integer","title":"Total"},"limit":{"type":"integer","title":"Limit"},"offset":{"type":"integer","title":"Offset"}},"type":"object","required":["forms","total","limit","offset"],"title":"LibraryResponse"},"LogoutResponse":{"properties":{"detail":{"type":"string","title":"Detail"}},"type":"object","required":["detail"],"title":"LogoutResponse"},"NewTournamentCard":{"properties":{"id":{"type":"integer","title":"Id"},"title":{"type":"string","title":"Title"},"slug":{"type":"string","title":"Slug"},"event_date":{"type":"string","format":"date-time","title":"Event Date"},"stage":{"type":"string","title":"Stage"},"level":{"type":"integer","title":"Level"},"player_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Player Limit"},"free_slots":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Free Slots"},"cover_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cover Url"},"url_path":{"type":"string","title":"Url Path"}},"type":"object","required":["id","title","slug","event_date","stage","level","url_path"],"title":"NewTournamentCard","description":"Карточка турнира для карусели новых турниров.\n\nНет owner            — не отображается в карточке.\nНет game             — нет привязки к дисциплине; нет JOIN к games.\nНет description      — нет места в карточке карусели.\nurl_path             — готовый путь для перехода на страницу турнира."},"NewTournamentsResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/NewTournamentCard"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"cached_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Cached At"},"cache_ttl_seconds":{"type":"integer","title":"Cache Ttl Seconds","default":0}},"type":"object","required":["items","total"],"title":"NewTournamentsResponse"},"OpenRegistrationCard":{"properties":{"id":{"type":"integer","title":"Id"},"title":{"type":"string","title":"Title"},"slug":{"type":"string","title":"Slug"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"event_date":{"type":"string","format":"date-time","title":"Event Date"},"stage":{"type":"string","title":"Stage"},"level":{"type":"integer","title":"Level"},"player_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Player Limit"},"free_slots":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Free Slots"},"background_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Background Image"},"game":{"anyOf":[{"$ref":"#/components/schemas/GameRefCard"},{"type":"null"}]},"url_path":{"type":"string","title":"Url Path"}},"type":"object","required":["id","title","slug","event_date","stage","level","url_path"],"title":"OpenRegistrationCard","description":"Карточка турнира для карусели открытой регистрации.\n\nНет cover_url    — карточка использует background_image как фон.\nНет owner        — имя организатора не отображается в карточке.\nurl_path         — готовый путь для перехода на страницу турнира."},"OpenRegistrationResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/OpenRegistrationCard"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"cached_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Cached At"},"cache_ttl_seconds":{"type":"integer","title":"Cache Ttl Seconds","default":0}},"type":"object","required":["items","total"],"title":"OpenRegistrationResponse"},"PendingEmailChange":{"properties":{"new_email":{"type":"string","title":"New Email"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"}},"type":"object","required":["new_email","expires_at"],"title":"PendingEmailChange","description":"Информация об ожидающей подтверждения смене email."},"PopularGameCard":{"properties":{"id":{"type":"integer","title":"Id"},"title":{"type":"string","title":"Title"},"slug":{"type":"string","title":"Slug"},"cover_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cover Url"},"game_type":{"type":"string","title":"Game Type"},"tournament_count":{"type":"integer","title":"Tournament Count"},"url_path":{"type":"string","title":"Url Path"}},"type":"object","required":["id","title","slug","game_type","tournament_count","url_path"],"title":"PopularGameCard","description":"Карточка игры для карусели популярных игр.\n\nНет description  — не отображается в карточке карусели.\nНет is_active    — показываем только активные, поле не нужно фронту.\nurl_path         — готовый путь для перехода на страницу дисциплины."},"PopularGamesResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/PopularGameCard"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"sport_count":{"type":"integer","title":"Sport Count"},"esport_count":{"type":"integer","title":"Esport Count"},"cached_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Cached At"},"cache_ttl_seconds":{"type":"integer","title":"Cache Ttl Seconds","default":0}},"type":"object","required":["items","total","sport_count","esport_count"],"title":"PopularGamesResponse"},"QuestionOptionCreate":{"properties":{"label":{"type":"string","maxLength":255,"title":"Label"},"value":{"type":"string","maxLength":255,"title":"Value"},"next_section_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Next Section Id"},"order":{"type":"integer","minimum":1.0,"title":"Order","default":1}},"type":"object","required":["label","value"],"title":"QuestionOptionCreate"},"QuestionOptionResponse":{"properties":{"label":{"type":"string","maxLength":255,"title":"Label"},"value":{"type":"string","maxLength":255,"title":"Value"},"next_section_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Next Section Id"},"order":{"type":"integer","minimum":1.0,"title":"Order","default":1},"id":{"type":"integer","title":"Id"}},"type":"object","required":["label","value","id"],"title":"QuestionOptionResponse"},"RegistrationDetailResponse":{"properties":{"id":{"type":"integer","title":"Id"},"user":{"$ref":"#/components/schemas/UserRegistrationRef"},"status":{"type":"string","title":"Status"},"answers":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Answers"},"checked_in":{"type":"boolean","title":"Checked In"},"checked_in_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Checked In At"},"registered_at":{"type":"string","format":"date-time","title":"Registered At"}},"type":"object","required":["id","user","status","checked_in","registered_at"],"title":"RegistrationDetailResponse","description":"Обновлённая регистрация участника"},"RegistrationFormCreate":{"properties":{"name":{"type":"string","maxLength":255,"title":"Name"},"sections":{"items":{"$ref":"#/components/schemas/FormSectionCreate"},"type":"array","title":"Sections"}},"type":"object","required":["name"],"title":"RegistrationFormCreate"},"RegistrationFormRename":{"properties":{"name":{"type":"string","maxLength":255,"title":"Name"}},"type":"object","required":["name"],"title":"RegistrationFormRename"},"RegistrationFormResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"version":{"type":"integer","title":"Version"},"is_template":{"type":"boolean","title":"Is Template"},"tournament_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tournament Id"},"created_by_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Created By Id"},"created_at":{"title":"Created At"},"updated_at":{"title":"Updated At"},"sections":{"items":{"$ref":"#/components/schemas/FormSectionResponse"},"type":"array","title":"Sections","default":[]}},"type":"object","required":["id","name","version","is_template","created_at","updated_at"],"title":"RegistrationFormResponse"},"RegistrationFormSummary":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"version":{"type":"integer","title":"Version"},"is_template":{"type":"boolean","title":"Is Template"},"tournament_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tournament Id"},"created_by_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Created By Id"},"created_at":{"title":"Created At"},"updated_at":{"title":"Updated At"}},"type":"object","required":["id","name","version","is_template","created_at","updated_at"],"title":"RegistrationFormSummary","description":"Краткая информация о форме (для списков)."},"RegistrationFormUpdate":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Name"},"sections":{"anyOf":[{"items":{"$ref":"#/components/schemas/FormSectionCreate"},"type":"array"},{"type":"null"}],"title":"Sections"}},"type":"object","title":"RegistrationFormUpdate","description":"Полное обновление структуры формы (заменяет разделы целиком)."},"RegistrationListItem":{"properties":{"id":{"type":"integer","title":"Id","description":"ID регистрации"},"user":{"$ref":"#/components/schemas/UserRegistrationRef"},"status":{"type":"string","title":"Status","description":"Статус регистрации: PENDING, CONFIRMED, REJECTED, CANCELLED"},"checked_in":{"type":"boolean","title":"Checked In","description":"Был ли пользователь на check-in"},"checked_in_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Checked In At","description":"Время check-in"},"registered_at":{"type":"string","format":"date-time","title":"Registered At","description":"Время регистрации"},"is_banned":{"type":"boolean","title":"Is Banned","description":"Заблокирован ли участник на турнире","default":false}},"type":"object","required":["id","user","status","checked_in","checked_in_at","registered_at"],"title":"RegistrationListItem","description":"Элемент списка зарегистрировавшихся"},"RegistrationStartResponse":{"properties":{"session_id":{"type":"string","title":"Session Id"},"form_version":{"type":"integer","title":"Form Version"},"section":{"$ref":"#/components/schemas/FormSectionResponse"},"total_sections":{"type":"integer","title":"Total Sections"},"current_section_number":{"type":"integer","title":"Current Section Number"}},"type":"object","required":["session_id","form_version","section","total_sections","current_section_number"],"title":"RegistrationStartResponse"},"RejectRegistrationRequest":{"properties":{"comment":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Comment","description":"Причина отклонения (необязательно)"}},"type":"object","title":"RejectRegistrationRequest","description":"Запрос на отклонение заявки администратором."},"RestoreAccountRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","maxLength":128,"minLength":8,"title":"Password"}},"type":"object","required":["email","password"],"title":"RestoreAccountRequest","description":"Запрос на восстановление удалённого аккаунта."},"SaveAsTemplateRequest":{"properties":{"template_name":{"type":"string","maxLength":255,"title":"Template Name"}},"type":"object","required":["template_name"],"title":"SaveAsTemplateRequest"},"SectionSubmitRequest":{"properties":{"session_id":{"type":"string","title":"Session Id"},"form_version":{"type":"integer","title":"Form Version"},"answers":{"items":{"$ref":"#/components/schemas/AnswerPayload"},"type":"array","title":"Answers"}},"type":"object","required":["session_id","form_version"],"title":"SectionSubmitRequest"},"SectionSubmitResponse":{"properties":{"registration_completed":{"type":"boolean","title":"Registration Completed","default":false},"next_section":{"anyOf":[{"$ref":"#/components/schemas/FormSectionResponse"},{"type":"null"}]},"current_section_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Current Section Number"},"total_sections":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Sections"}},"type":"object","title":"SectionSubmitResponse","description":"Ответ сервера после сохранения раздела."},"TokenResponse":{"properties":{"access_token":{"type":"string","title":"Access Token"},"token_type":{"type":"string","title":"Token Type","default":"bearer"},"device_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Device Id"}},"type":"object","required":["access_token"],"title":"TokenResponse"},"TournamentAdminHistoryItem":{"properties":{"user_id":{"type":"integer","title":"User Id"},"granted_at":{"type":"string","format":"date-time","title":"Granted At"},"granted_by_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Granted By Id"},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Revoked At"},"revoked_by_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Revoked By Id"}},"type":"object","required":["user_id","granted_at"],"title":"TournamentAdminHistoryItem","description":"Запись истории назначения/отзыва администратора"},"TournamentAdminHistoryResponse":{"properties":{"total":{"type":"integer","title":"Total"},"items":{"items":{"$ref":"#/components/schemas/TournamentAdminHistoryItem"},"type":"array","title":"Items"}},"type":"object","required":["total","items"],"title":"TournamentAdminHistoryResponse","description":"История назначений/отзывов администраторов"},"TournamentAdminRef":{"properties":{"id":{"type":"integer","title":"Id"},"username":{"type":"string","title":"Username"},"profile_url":{"type":"string","title":"Profile Url"},"granted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Granted At"},"granted_by_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Granted By Id"}},"type":"object","required":["id","username","profile_url"],"title":"TournamentAdminRef","description":"Активный администратор турнира"},"TournamentAdminsListResponse":{"properties":{"total":{"type":"integer","title":"Total"},"items":{"items":{"$ref":"#/components/schemas/TournamentAdminRef"},"type":"array","title":"Items"}},"type":"object","required":["total","items"],"title":"TournamentAdminsListResponse","description":"Список администраторов турнира"},"TournamentBanHistoryItem":{"properties":{"user_id":{"type":"integer","title":"User Id"},"banned_at":{"type":"string","format":"date-time","title":"Banned At"},"banned_by_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Banned By Id"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"},"unbanned_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Unbanned At"},"unbanned_by_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Unbanned By Id"}},"type":"object","required":["user_id","banned_at"],"title":"TournamentBanHistoryItem","description":"Запись истории бана/разбана"},"TournamentBanHistoryResponse":{"properties":{"total":{"type":"integer","title":"Total"},"items":{"items":{"$ref":"#/components/schemas/TournamentBanHistoryItem"},"type":"array","title":"Items"}},"type":"object","required":["total","items"],"title":"TournamentBanHistoryResponse","description":"История банов/разбанов турнира"},"TournamentBanRef":{"properties":{"user_id":{"type":"integer","title":"User Id"},"banned_at":{"type":"string","format":"date-time","title":"Banned At"},"banned_by_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Banned By Id"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","required":["user_id","banned_at"],"title":"TournamentBanRef","description":"Активный бан участника турнира"},"TournamentBansListResponse":{"properties":{"total":{"type":"integer","title":"Total"},"items":{"items":{"$ref":"#/components/schemas/TournamentBanRef"},"type":"array","title":"Items"}},"type":"object","required":["total","items"],"title":"TournamentBansListResponse","description":"Текущие (активные) баны турнира"},"TournamentCardResponse":{"properties":{"id":{"type":"integer","title":"Id"},"title":{"type":"string","title":"Title"},"slug":{"type":"string","title":"Slug"},"event_date":{"type":"string","format":"date-time","title":"Event Date"},"stage":{"type":"string","title":"Stage"},"player_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Player Limit"},"free_slots":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Free Slots"},"url_path":{"type":"string","title":"Url Path"}},"type":"object","required":["id","title","slug","event_date","stage","url_path"],"title":"TournamentCardResponse","description":"Карточка турнира в списке профиля пользователя"},"TournamentDetailResponse":{"properties":{"id":{"type":"integer","title":"Id"},"title":{"type":"string","title":"Title"},"slug":{"type":"string","title":"Slug"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"event_date":{"type":"string","format":"date-time","title":"Event Date"},"ended_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Ended At"},"stage":{"type":"string","title":"Stage"},"level":{"type":"integer","title":"Level"},"player_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Player Limit"},"free_slots":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Free Slots"},"participation_type":{"type":"string","title":"Participation Type"},"team_size":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Team Size"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"},"cover_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cover Url"},"background_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Background Image"},"addition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Addition"},"contact":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Contact"},"translations":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Translations"},"owner_id":{"type":"integer","title":"Owner Id"},"game":{"anyOf":[{"$ref":"#/components/schemas/GameDetailRef"},{"type":"null"}]},"registration_closed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Registration Closed At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","title","slug","event_date","stage","level","participation_type","owner_id","created_at","updated_at"],"title":"TournamentDetailResponse","description":"Полная информация о турнире"},"TournamentListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/TournamentResponse"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total","description":"Общее количество элементов"},"page":{"type":"integer","title":"Page","description":"Текущая страница"},"page_size":{"type":"integer","title":"Page Size","description":"Элементов на странице"},"total_pages":{"type":"integer","title":"Total Pages","description":"Всего страниц"},"has_next":{"type":"boolean","title":"Has Next","description":"Есть ли следующая страница"},"has_previous":{"type":"boolean","title":"Has Previous","description":"Есть ли предыдущая страница"}},"type":"object","required":["items","total","page","page_size","total_pages","has_next","has_previous"],"title":"TournamentListResponse","description":"Ответ со списком турниров и информацией о пагинации"},"TournamentRegistrationsListResponse":{"properties":{"total":{"type":"integer","title":"Total","description":"Общее количество регистраций"},"items":{"items":{"$ref":"#/components/schemas/RegistrationListItem"},"type":"array","title":"Items"}},"type":"object","required":["total","items"],"title":"TournamentRegistrationsListResponse","description":"Список всех зарегистрировавшихся на турнир"},"TournamentResponse":{"properties":{"id":{"type":"integer","title":"Id"},"title":{"type":"string","title":"Title"},"slug":{"type":"string","title":"Slug"},"event_date":{"type":"string","format":"date-time","title":"Event Date"},"ended_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Ended At"},"stage":{"type":"string","title":"Stage"},"level":{"type":"integer","title":"Level"},"player_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Player Limit"},"free_slots":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Free Slots"},"participation_type":{"type":"string","title":"Participation Type"},"team_size":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Team Size"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"},"cover_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cover Url"},"background_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Background Image"},"game":{"anyOf":[{"$ref":"#/components/schemas/GameRef"},{"type":"null"}]}},"type":"object","required":["id","title","slug","event_date","stage","level","participation_type"],"title":"TournamentResponse","description":"Турнир в списке"},"UpdateRegistrationRequest":{"properties":{"answers":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Answers","description":"Ответы на вопросы формы (заменяет полностью)"},"checked_in":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Checked In","description":"Отметить/снять check-in"},"checked_in_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Checked In At","description":"Время check-in"}},"type":"object","title":"UpdateRegistrationRequest","description":"Запрос на обновление регистрации участника (owner/admin турнира).\n\nНельзя менять: id, user_id, tournament_id, status, submitted_at, created_at.\nМожно менять: answers (JSON с ответами формы), checked_in, checked_in_at.","example":{"answers":{"q1":"updated answer","q2":"option1"},"checked_in":true}},"UpdateTournamentRequest":{"properties":{"title":{"anyOf":[{"type":"string","maxLength":255,"minLength":3},{"type":"null"}],"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"event_date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Event Date"},"ended_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Ended At"},"player_limit":{"anyOf":[{"type":"integer","maximum":10000.0,"minimum":1.0},{"type":"null"}],"title":"Player Limit"},"participation_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Participation Type","description":"PLAYERS, TEAMS, PLAYERS_AND_TEAMS"},"team_size":{"anyOf":[{"type":"integer","maximum":1000.0,"minimum":2.0},{"type":"null"}],"title":"Team Size"},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags","description":"Список тегов (заменяет текущий список)"},"cover_url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Cover Url"},"background_image":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Background Image"},"addition":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Addition"},"contact":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Contact"},"translations":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Translations"},"registration_closed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Registration Closed At"},"remove_player_limit":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Remove Player Limit","description":"true = убрать ограничение (player_limit=null)"}},"type":"object","title":"UpdateTournamentRequest","description":"Запрос для обновления турнира (Settings)","example":{"player_limit":256,"registration_closed_at":"2026-05-30T18:00:00Z","tags":["pro","invitational"],"title":"Updated Championship"}},"UserCreate":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"username":{"type":"string","maxLength":32,"minLength":3,"pattern":"^[A-Za-z0-9_]+$","title":"Username"},"password":{"type":"string","maxLength":128,"minLength":8,"title":"Password"}},"type":"object","required":["email","username","password"],"title":"UserCreate","example":{"email":"alice@example.com","password":"SecurePass123","username":"alice_01"}},"UserLogin":{"properties":{"email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Email"},"username":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Username"},"password":{"type":"string","maxLength":128,"minLength":8,"title":"Password"}},"type":"object","required":["password"],"title":"UserLogin","example":{"email":"alice@example.com","password":"SecurePass123"}},"UserRead":{"properties":{"id":{"type":"integer","title":"Id"},"username":{"type":"string","title":"Username"},"email":{"type":"string","format":"email","title":"Email"},"status":{"type":"string","title":"Status"},"subscription_level":{"type":"integer","title":"Subscription Level"},"photo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Photo Url"},"date_birth":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Date Birth"},"is_email_confirmed":{"type":"boolean","title":"Is Email Confirmed"},"email_confirmed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Email Confirmed At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"pending_email_change":{"anyOf":[{"$ref":"#/components/schemas/PendingEmailChange"},{"type":"null"}]}},"type":"object","required":["id","username","email","status","subscription_level","photo_url","date_birth","is_email_confirmed","email_confirmed_at","created_at","updated_at"],"title":"UserRead"},"UserRegistrationRef":{"properties":{"id":{"type":"integer","title":"Id"},"username":{"type":"string","title":"Username"},"profile_url":{"type":"string","title":"Profile Url","description":"Путь к профилю: /profile/{username}"}},"type":"object","required":["id","username","profile_url"],"title":"UserRegistrationRef","description":"Пользователь на странице регистраций турнира"},"UserSessionRead":{"properties":{"device_id":{"type":"string","title":"Device Id"},"user_agent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Agent"},"ip_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ip Address"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"last_seen_at":{"type":"string","format":"date-time","title":"Last Seen At"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"is_current":{"type":"boolean","title":"Is Current","default":false}},"type":"object","required":["device_id","created_at","last_seen_at","expires_at"],"title":"UserSessionRead","description":"Запись активной сессии (для GET /auth/sessions)."},"UserSessionsResponse":{"properties":{"sessions":{"items":{"$ref":"#/components/schemas/UserSessionRead"},"type":"array","title":"Sessions"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["sessions","total"],"title":"UserSessionsResponse"},"UserStatusEnum":{"type":"string","enum":["INACTIVE","ACTIVE","STAFF","BANNED","DELETED"],"title":"UserStatusEnum","description":"Статусы пользователя (взаимоисключающие)."},"UserStatusHistoryRead":{"properties":{"id":{"type":"integer","title":"Id"},"user_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"User Id"},"old_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Old Status"},"new_status":{"type":"string","title":"New Status"},"changed_by":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Changed By"},"changed_at":{"type":"string","format":"date-time","title":"Changed At"}},"type":"object","required":["id","user_id","old_status","new_status","changed_by","changed_at"],"title":"UserStatusHistoryRead"},"UserStatusUpdateRequest":{"properties":{"new_status":{"$ref":"#/components/schemas/UserStatusEnum"}},"type":"object","required":["new_status"],"title":"UserStatusUpdateRequest","description":"Запрос на изменение статуса пользователя (только для STAFF).","example":{"new_status":"BANNED"}},"UserTournamentsListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/TournamentCardResponse"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total","description":"Общее количество турниров в этой категории"},"page":{"type":"integer","title":"Page","description":"Текущая страница"},"page_size":{"type":"integer","title":"Page Size","description":"Турниров на странице"},"total_pages":{"type":"integer","title":"Total Pages","description":"Всего страниц"},"has_next":{"type":"boolean","title":"Has Next","description":"Есть ли следующая страница"},"has_previous":{"type":"boolean","title":"Has Previous","description":"Есть ли предыдущая страница"}},"type":"object","required":["items","total","page","page_size","total_pages","has_next","has_previous"],"title":"UserTournamentsListResponse","description":"Ответ со списком турниров профиля пользователя и информацией о пагинации"},"UserUpdate":{"properties":{"username":{"anyOf":[{"type":"string","maxLength":32,"minLength":3,"pattern":"^[A-Za-z0-9_]+$"},{"type":"null"}],"title":"Username"},"date_birth":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Date Birth"}},"type":"object","title":"UserUpdate","description":"Поля профиля, которые пользователь может менять сам.\n\nphoto_url изменяется только через аватар-аплоад:\n  POST /api/auth/me/avatar/direct  (прямая загрузка)\n  POST /api/v1/upload/* + POST /api/auth/me/avatar  (чанковый аплоад)"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer"}}}}