This commit is contained in:
2026-10-11 16:00:18 +07:00
parent 504b49f7cc
commit 030ca56900
77 changed files with 793 additions and 638 deletions
+26 -6
View File
@@ -1,4 +1,4 @@
# Пакет игры, версия 1 — ED-029, этап 4
# Пакет игры, версия 2 — ED-031
Пакет — самостоятельный ZIP для одной игры до старта. Сборка получает готовый
снимок данных и файлы; чтение не обращается к сети, БД или хранилищу приложения.
@@ -8,7 +8,7 @@
| Запись | Содержание |
| --- | --- |
| `manifest.json` | `version=1`, случайный `package_id` (32 hex-символа), `created_at` в UTC, `source_server`, исходный `game_id`, массив `files` |
| `manifest.json` | `version=2`, случайный `package_id` (32 hex-символа), `created_at` в UTC, `source_server`, исходный `game_id`, массив `files` |
| `game.json` | Объект `Data`: `game`, `scenario`, `teams`, `tickets`, `playlists`, необязательный `screen_plan`, `map` |
| `files/<sha256>.<extension>` | Медиа с именем по SHA-256 содержимого; одинаковые байты хранятся один раз |
@@ -347,7 +347,7 @@ RustFS и создать `<marker>.continue` в течение минуты. Buc
Интерфейс передачи остаётся этапом 7; полный билетный и игровой прогон — этапом 8.
До готовности возврата результатов используются только тестовые игры.
## Пакет результатов, версия 1 (ED-029, этап 9)
## Пакет результатов, версия 2 (ED-031)
Это отдельный контракт: ZIP содержит ровно `manifest.json` и `results.json`,
без сценария и файлов. Серверное применение реализовано этапом 10; API/UI описаны в этапе 11.
@@ -370,7 +370,7 @@ gameID, output)` доступен только в `venue`, для существ
| Поле | Значение |
| --- | --- |
| `version` | `1` |
| `version` | `2` |
| `package_id`, `created_at` | ID именно пакета результатов, время подготовки |
| `source_server`, `game_id` | Онлайн-источник и исходный ID игры |
| `source_package_id`, `source_sha256` | ID и SHA-256 всего исходного ZIP игры из реестра импорта |
@@ -395,7 +395,8 @@ SHA-256 защищает от повреждения; это не подпись
| `applications` | Локальные `id`, `team_id`, исходные `name`/`image`/`file_type`, `status` (`need`/`done`), `created_at` |
| `answers` | `team_id`, `question_code`, `answer`, nullable `score`, `created_at`, `updated_at` |
`source_id` совпадает с `id` для исходной записи и равен `0` для новой локальной.
`source_id` совпадает с `id` для исходной записи. У новой локальной команды
это пустая строка, у нового билета — `0`. ID команд и ссылки на них — UUID-строки.
Все ссылки прогресса используют итоговый локальный `team_id`. Этап 10 уточняет
выделение ID: новые команды сохраняют venue-ID и пароль для напечатанных QR;
занятый чужой командой ID отклоняет весь возврат. Новым билетам, ходам и уликам
@@ -473,7 +474,8 @@ venue-пароль. Новые билеты получают онлайн-ID и
ID или хеша с чужой записью отклоняет весь пакет. Ходы и улики получают свежие
онлайн-ID в порядке пакета, включая исправленный снимок. Реестр хранит
соответствия каждого возврата; соответствия новых билетов сохраняются между
исправлениями. Последовательности продвигаются монотонным `nextval`, без `setval`
исправлениями. Команды сохраняют UUID v7 без последовательности.
Последовательности билетов, ходов и материалов продвигаются монотонным `nextval`, без `setval`
и глобальных блокировок обычных операций.
Материалы переводятся из portable-троек исходного ZIP в исходные онлайн-ссылки
@@ -557,3 +559,21 @@ prod-игры блок «Возврат результатов с площадк
страницу prod, исправленный балл, перезапись онлайн-ответа, исходные ссылки и
билеты, сохранение оформления, снятие офлайн-отметки, повтор после перезапуска.
ZIP остаётся неподписанным; нагрузка, Wi-Fi и фактический ZIP 1 ГиБ не проверяются.
## Переход на UUID v7 (ED-031)
Все способы создания команды генерируют UUID v7 в Go. API передаёт ID строкой,
PostgreSQL хранит `uuid`. Несколько независимых площадок создают команды без
общего счётчика; перенос игры и возврат результатов сохраняют UUID и ссылки.
Перед обновлением завершите игры на площадках и верните результаты, остановите
запись во всех окружениях и сохраните резервные копии БД. Обновите backend и
frontend согласованно во всех окружениях и примените миграции. Миграция заменяет
числовые ID существующих команд на UUID v7, сохраняя пароли, игровые данные,
связи и карту. Старые числовые ссылки и QR нужно сформировать заново.
Пакеты игры и результатов версии 1 больше не принимаются. Миграция очищает
старые реестры экспорта, импорта и возврата; игровые данные и материалы остаются.
Старые ZIP-объекты в хранилище остаются, но недоступны через очищенный реестр.
После обновления создайте новые экспорты версии 2. Откат требует восстановления
резервной копии БД и предыдущей версии приложения; обратного преобразования ID нет.