generated from VLADIMIR/template
add
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
# Подтверждение участия
|
||||
|
||||
Для всех форматов игр за 24 часа до `start_at` сервер отправляет письмо капитану.
|
||||
Проверка запускается при старте сервера, затем раз в минуту. Отправка последовательная:
|
||||
большая рассылка занимает дополнительное время. Команды без email видны организатору,
|
||||
но письмо им отправить невозможно.
|
||||
|
||||
## Правила
|
||||
|
||||
- `pending` — ожидает ответа; команда сохраняет право участвовать.
|
||||
- `confirmed` — подтверждено капитаном или автоматически при регистрации менее чем за сутки.
|
||||
- `cancelled` — отменено; команда остаётся в истории организатора, но исключается из игры,
|
||||
ответов организатору, результатов, карты и PDF с QR-кодами.
|
||||
- Ровно за 24 часа автоматического подтверждения нет.
|
||||
- Ответ окончательный: повтор того же ответа успешен, противоположный отклоняется.
|
||||
- После планового начала или выхода игры из `draft` новые ответы не принимаются.
|
||||
- Перенос игры и повторный сбор подтверждений не поддерживаются.
|
||||
|
||||
Правило поздней регистрации вычисляется в сервисе перед созданием команды для формы и ручного добавления.
|
||||
Существующие команды миграция не изменяет: они остаются в статусе `pending`.
|
||||
Даты без часового пояса в существующих `games.start_at` и `teams.created_at` считаются UTC.
|
||||
|
||||
## Запуск
|
||||
|
||||
1. Применить миграцию `20260915120000_add_team_participation.sql` через обычный `goose up`.
|
||||
2. Обновить сервер и фронтенд вместе: фронтенд должен обслуживать `/participation`.
|
||||
3. Проверить существующие SMTP-настройки, `APP_BASE_URL`, `PARTICIPATION_SECRET`.
|
||||
`GAME_TIMEZONE` задаёт часовой пояс письма, по умолчанию `Asia/Barnaul`.
|
||||
|
||||
Рассылка запускается автоматически. Если `APP_BASE_URL`, `PARTICIPATION_SECRET` или часовой пояс
|
||||
некорректны, сервер пишет причину отключения рассылки в журнал.
|
||||
Не менять `PARTICIPATION_SECRET` между попытками отправки: HMAC-токен привязан к команде и этому секрету.
|
||||
В БД хранится только SHA-256 токена. Уже отправленные ссылки проверяются по сохранённому хешу.
|
||||
Токен передаётся в URL-фрагменте и теле API-запроса, не в query string.
|
||||
Не включать тела запросов `/api/participation/*` в access-логи.
|
||||
|
||||
Неудачные попытки повторяются через пять минут автоматически, максимум восемь раз на команду.
|
||||
После восьмой неудачи новые попытки не запускаются; ошибка остаётся видна организатору.
|
||||
Пятиминутная аренда задания защищает от одновременной обработки серверами и восстанавливается
|
||||
после падения. Одна попытка ограничена минутой. Ошибки сохранения результата записываются в журнал.
|
||||
SMTP не обеспечивает ровно одну доставку: если письмо принято, а результат не сохранён,
|
||||
возможен дубль с той же ссылкой. `participation_sent_at` означает принятие письма SMTP,
|
||||
а не прочтение письма или гарантированное попадание во входящие.
|
||||
|
||||
## Проверка
|
||||
|
||||
```sh
|
||||
go test ./...
|
||||
TEST_DATABASE_URL='host=localhost port=5432 user=test dbname=test sslmode=disable' \
|
||||
go test ./internal/repos/teams_repo ./internal/services/game_service -count=1
|
||||
```
|
||||
|
||||
Интеграционные тесты создают и удаляют собственные схемы. SMTP заменён тестовой реализацией;
|
||||
реальным капитанам тесты ничего не отправляют.
|
||||
Reference in New Issue
Block a user