Формат ошибок и загрузка файлов
Два сквозных механизма, которые встречаются в каждом разделе.
Формат ошибок
Заголовок раздела «Формат ошибок»Все ошибки API приходят одной формой:
{ "error": { "code": "SNAKE_CASE", "message": "..." } }Коды стабильны, и на них завязаны фронты — по коду они выбирают текст и
поведение, а не по message. Менять код — ломающее изменение, даже если
сообщение осталось прежним.
Что бывает сейчас:
| Область | Коды |
|---|---|
| Общее | VALIDATION_ERROR, UNAUTHORIZED, FORBIDDEN, NOT_FOUND |
| Вход | INVALID_OTP, OTP_RATE_LIMITED, INVALID_REFRESH_TOKEN, USER_BANNED |
| Запись | REGISTRATION_CLOSED, REGISTRATION_BANNED, ALREADY_REGISTERED, INVALID_STATUS |
| Live | NOT_ENOUGH_PLAYERS, TOURNAMENT_ALREADY_STARTED, TOURNAMENT_NOT_RUNNING, TOURNAMENT_NOT_FINISHED, ALREADY_ELIMINATED, NOTHING_TO_UNDO, SEAT_TAKEN, INVALID_LEVEL, INVALID_LEVELS |
| Результаты | RESULTS_ALREADY_CONFIRMED |
Загрузка картинок
Заголовок раздела «Загрузка картинок»POST /uploads, multipart, поле file. Кладёт файл в S3-совместимое хранилище
и возвращает { url, key }.
Presigned URL не используются — файл идёт через сервер. Это осознанный выбор: так проверка прав и ограничений остаётся в одном месте.
Доступ даёт UploadAccessGuard. Загрузить может:
- платформенный админ с правом
content.manageилиtournaments.manage; - либо любой
owner/tdкакого-нибудь клуба.
Ограничения — белый список MIME-типов и лимит размера, оба в storage.ts.
Что рядом
Заголовок раздела «Что рядом»- Аутентификация и роли — откуда берутся права.
- Ландшафт и границы — где лежит контракт целиком.