# Проверки площадки для разработчика Для работы площадки эти файлы не нужны. Обычный запуск: `make venue`. - `deploy.py` — запускает проверки единого HTTPS-деплоя из `https.py` без Docker: первый запуск, повторная сборка Docker-образа, принудительный перезапуск, отсутствие артефактов, сертификаты и сохранность настроек. - `smoke.py` — проверяет работающую площадку через API. Без `--verify` создаёт тестовые данные; с `--verify` проверяет ранее созданные данные. Всегда использует HTTPS и прежние домены с проверкой доверия TLS; требует локального DNS. - `https.py` — проверяет сертификаты и HTTPS-запуск с подставными командами. `--docker` дополнительно запускает два временных Nginx-контейнера в отдельной сети, проверяет TLS, маршруты, перенаправления и перезапуск, затем удаляет свои контейнеры и сеть. Использует локальный `nginx:alpine` и временный тестовый CA; работающие окружения, production и системное хранилище доверия не меняет. - `dns.py --docker` — проверяет оба локальных домена по UDP/TCP и отсутствие внешних IPv6-ответов в отдельной внутренней Docker-сети без WAN до и после перезапуска CoreDNS. `--server ` проверяет работающий DNS. Команды из корня проекта: ```sh python3 tests/venue/deploy.py python3 tests/venue/smoke.py --verify python3 tests/venue/https.py python3 tests/venue/https.py --docker python3 tests/venue/dns.py --docker python3 tests/venue/dns.py --server 192.168.10.155 ``` ## Полный flow ED-029, этап 8 ```sh python3 tests/venue/flow.py python3 tests/venue/flow.py --browser python3 tests/venue/flow.py --results python3 tests/venue/flow.py --apply python3 tests/venue/flow.py --apply --browser ``` `flow.py` собирает актуальный Go/Vue-код во временном каталоге, поднимает одноразовые prod/venue-серверы с отдельными PostgreSQL и RustFS в Docker-сети `--internal`, затем удаляет только свои контейнеры, тома и сеть. Работающие окружения, файлы `prod`/`venue`, их настройки и Cudy не меняются. Требуются установленные Go, Node/npm, frontend-зависимости и доступ к Docker; образы `postgres:15`, `rustfs/rustfs:latest` и `alpine:3.22` должны быть доступны локально (скрипт использует `--pull=never`). SMTP источника направлен в локальный sink, который закрывает соединение; успешная отправка писем не проверяется. Проверяются оба формата (`offline` и `online`): экспорт и импорт настоящего ZIP, исходные ссылки команд/билетов, статусы участия, QR/PDF, приём билетов и его конкурентность, новые локальные команды/билеты, ходы и материалы, запрет ходов до старта/на паузе/после завершения, перезапуск всех venue-сервисов, ответы, оценивание, результаты и повторный импорт без потери прогресса. Дополнительно запускаются PostgreSQL-регрессии gameplay/lifecycle, tickets, MCP и app. Выдача токенов писем имитируется только в тестовой БД; решения капитанов выполняются через штатный API. Возврат результатов на источник не выполняется. `--browser` требует Firefox с Marionette и запускает отдельный чистый стенд. Реальные интерфейсы проходят экспорт, скачивание, загрузку ZIP, проверку билета, ходы, выдачу материала, оценивание и завершение на 1440 px (`online`) и 390 px (`offline`). Проверяются клавиатурный focus, отказ на ход с сохранением ввода, блокировка повторной отправки и кнопки на паузе при уже введённом коде. Локальный HTTP-прокси переключает один публичный адрес между двумя реальными backend, имитируя смену DNS; Игровые API-ответы не подменяются; ошибки, пустой список и состояния Wi-Fi панели мониторинга дополнительно проверяются управляемыми ответами GetDevices. Тестовые ссылки, ZIP, профиль Firefox и сборки остаются во временном каталоге до конца прогона. `--results` дополнительно проверяет этап 9: серверный сервис собирает ZIP результатов обеих завершённых игр из реальной тестовой БД. Проверяются привязка к исходному ZIP, прогресс/материалы/баллы, новый снимок после оценивания, конкурентное оценивание, сохранность предыдущего пакета, повтор после перезапуска и отсутствие изменений исходных игр. Локальные ссылки RustFS в пакеты не попадают. ZIP находятся только во временном каталоге с правами 0600; новые API/UI для возврата и применение онлайн не выполняются. ### Ручная контрольная точка этапа 8 Автоматический прогон не заменяет проверку телефонов и камеры. После отдельного обновления реальной площадки актуальными артефактами, только на тестовой игре: 1. На источнике подготовить пакет с заранее выданными билетами и QR команд; скачать и импортировать его на venue через интерфейс. 2. Отключить WAN и мобильные данные. На Android/iPhone открыть прежние ссылки билета и команды через Wi-Fi площадки, проверить доверенный HTTPS. 3. Проверить билет у организатора и принять его; повтор должен показывать использованный билет. Проверить QR камерой там, где браузер поддерживает сканирование; при отсутствии поддержки проверить ручную вставку ссылки. 4. Начать игру, выполнить ход, выдать материал, поставить на паузу с введённым следующим кодом: ход должен блокироваться. Продолжить и выполнить этот ход. 5. Проверить правила формата: в `offline` материалы выдаёт организатор и нет цифровых ответов; в `online` игрок сохраняет ответ. Завершить игру, выставить баллы и открыть результаты; игрок должен увидеть сообщение о завершении. 6. Повторить импорт исходного ZIP: билеты и локальный прогресс должны сохраниться. Сообщить результат этой контрольной точки для приёмки этапа 8. Нагрузка на 100 клиентов, покрытие Wi-Fi, ZIP на 1 ГиБ и возврат результатов относятся к отдельным проверкам/этапам. До готовности возврата использовать только тестовые игры. `--apply` включает проверки этапа 9 и дополнительно проверяет этап 10: настоящий ZIP площадки применяется серверным сервисом к изолированному prod, с проверкой исходного ZIP в private RustFS. Проверяются перезапись онлайн-правок данными ZIP, сохранение онлайн-оформления, исправленный балл, повтор старого ZIP после нового и после перезапуска prod, прежние QR/билеты и ссылки новых venue-команд/билетов, исчезновение `game.export`. Новых endpoint-ов нет: service-only Go harness вызывается из стенда. Все ZIP и ресурсы остаются в приватном временном каталоге и удаляются после прогона. Этап 11: `--browser` также проходит возврат обоих форматов через реальные интерфейсы: свежий ZIP кнопкой venue, загрузка на странице prod, предупреждение о перезаписи, блокировка повторного запроса, результаты, старые ссылки/билеты, сохранение названия/описания, исчезновение офлайн-отметки, исправленная оценка, перезапись онлайн-ответа и повтор старого пакета после перезапуска. Прокси стенда проверяет лимит ZIP 1 ГиБ и использует таймаут 30 минут; небольшая задержка ответа применяется только для проверки блокировки кнопки. До пользовательских flow запускаются PostgreSQL/race-регрессии возврата и реального HTTP-применения. Работающие серверы не меняются; фактическая загрузка ZIP 1 ГиБ не проверяется. ### Учёт устройств (этап 12) `python3 tests/venue/flow.py --browser` проверяет реальный публичный heartbeat, права чтения, prod/venue, UUID и сочетания полей, неверные credentials, отменённое участие, смену/очистку контекста, фильтр игры и отсутствие секретов. Firefox проверяет игрока, организатора и экран в отдельных вкладках одного профиля, привязку экрана, SPA-навигацию, новые подключения при перезагрузке, остановку heartbeat, восстановление сети и повторную регистрацию через интервал после перезапуска backend. Прогон изолирован от работающих серверов. Границы 60 секунд/15 минут, лимит 1024, конкурентное чтение/обновление и безопасное ограничение User-Agent проверяются тестами сервиса с управляемыми часами (`go test -race ./internal/services/device_presence_service ./internal/app`). Фронтенд self-check: `node src/utils/__tests__/deviceID.test.ts`, `node src/stores/__tests__/devicePresence.test.ts` и `node src/composables/__tests__/devicePresence.test.ts`: временный UUID, отозванные lifecycle-контексты, отсутствие параллельных heartbeat, остановка после `enabled=false`, повтор ошибок по интервалу и независимость публичных credentials от JWT. Нагрузочный и аппаратный прогоны не включены. ### Панель состояния (этап 13) `python3 tests/venue/flow.py --browser` дополнительно проверяет Firefox: сводку и серверное время, встроенную ошибку с сохранением снимка, повтор, пустой список, остановку запросов после переключения вкладки; отдельного разработчика в venue/prod, безопасный состав GetGame/GetGames, скрытые создание и результаты, нормализацию `tab=answers` в `state`, единственную вкладку и обычный браузерный heartbeat. Проверки нескольких вкладок и смены контекста этапа 12 остаются частью прогона. Потеря API и пустой ответ воспроизводятся перехватом только GetDevices в браузере; остальные API реальные. `node src/composables/__tests__/gameState.test.ts` (из frontend) проверяет счётчики, сортировку, отсутствие параллельных запросов, активность вкладки, ошибку/восстановление и отбрасывание ответов после смены игры, ухода и unmount. Временные границы connected остаются в тестах сервиса этапа 12 с управляемыми часами; клиент пороги не пересчитывает. ## Wi-Fi и нагрузка (этапы 14–15) ```sh python3 tests/venue/load.py python3 tests/venue/flow.py --apply --browser ``` `load.py` использует тот же одноразовый стенд без WAN: 100 виртуальных UUID, 25 новых команд по четыре браузера, 60 секунд. Каждый профиль отправляет heartbeat раз в 20 секунд и читает историю раз в 5 секунд; по одному профилю команды выполняют два хода и сохраняют ответ. Организатор опрашивает состояние раз в 5 секунд. Проверяются ровно 100 доступных устройств, 50 сохранённых ходов, 25 ответивших команд и отсутствие HTTP-ошибок. Отчёт содержит число запросов, p50/p95/max; p95 ≤ 2 секунды — бюджет этого теста, не обещание для любого железа. Запросы идут прямо к backend по HTTP: DNS, HTTPS и прокси проверяются отдельно `dns.py --docker` и `https.py --docker`. Это нагрузка backend, не проверка радио. Go-тесты адаптера Cudy проверяют вход/продление сессии, ограничение URL/ответа, разбор обеих полос, отсутствующий сигнал, ошибку при неизвестной разметке, атомарный снимок, свежесть с управляемыми часами и venue/prod/роли. Firefox проверяет MAC/IP/диапазон/dBm, устаревание, ошибку и отсутствие сигнала; эти состояния Wi-Fi задаются fixture. Отдельно адаптер проверен чтением настоящего TR3000 V1 2.5.27-20260804-183625 без изменения настроек роутера. ### Аппаратная контрольная точка этапа 15 После согласованного обновления реальной площадки, только на тестовой игре: 1. Включить сбор Cudy по корневому README; отключить WAN и мобильные данные. На Android/iPhone открыть прежние домены, проверить DNS и доверенный HTTPS. 2. Подключить 100 настоящих Wi-Fi-устройств (несколько вкладок одного профиля не заменяют устройства); открыть игру 25 командами, держать нагрузку минимум 60 секунд, выполнять ходы и сохранять ответы. 3. Сверить клиентов Cudy с панелью, диапазоны и доступный сигнал; пройти края и проблемные зоны площадки, проверить материалы и действия в каждой зоне. MAC/UUID не сопоставлять предположениями; «Нет связи» относится к heartbeat. 4. Проверить паузу/продолжение, перезапуск venue и повторную регистрацию браузеров, смену контекста/несколько вкладок; убедиться, что панели в prod нет. 5. Временно остановить сборщик: через 30 секунд снимок должен устареть, прежние данные и время остаться видимыми. Запустить снова и проверить восстановление. Потерю API и восстановление проверить без потери снимка. 6. Завершить игру, вернуть ZIP на источник, проверить результаты и прежние ссылки. Зафиксировать оборудование, число клиентов, длительность, задержки/ошибки и покрытие; сообщить результат для приёмки ED-029. Автоматические проверки не заменяют эту приёмку. Пока она не подтверждена, ED-029 остаётся `IN_PROGRESS`. Фактический ZIP 1 ГиБ также не проверен.