164 lines
17 KiB
Markdown
164 lines
17 KiB
Markdown
# План приложения площадки
|
||
|
||
## Результат первой версии
|
||
|
||
Оператор выбирает игру, скачивает пакет показа и видит подтверждение готовности.
|
||
Пульт находится на основном экране компьютера; отдельное окно показа открывается на выбранном
|
||
внешнем дисплее. Аудио, видео, изображения и выбранные музыкальные плейлисты
|
||
читаются с диска. Пульт переключает показ и управляет воспроизведением локально.
|
||
После подготовки потеря интернета не мешает локальному показу и таймеру.
|
||
Полный пульт телефона работает в доверенной локальной сети одновременно с пультом компьютера.
|
||
|
||
«Все материалы» в первой версии — все ресурсы, необходимые окну показа:
|
||
вступление, закрывающее видео, обложка, фон, материалы шагов плана, выбранные
|
||
плейлисты и ресурсы интерфейса, включая шрифты. Полная локальная копия материалов
|
||
игроков, редактора сценария и печатных документов не входит в первую версию.
|
||
Это рабочая граница MVP; расширить её до реализации, если нужна вся библиотека.
|
||
|
||
## Поддерживаемые платформы первой версии
|
||
|
||
| ОС | Версии | Архитектуры |
|
||
| --- | --- | --- |
|
||
| macOS | 13 Ventura и новее | x64 (Intel), arm64 (Apple Silicon) |
|
||
| Windows | 11 | x64, ARM64 |
|
||
| Linux | Ubuntu 24.04 LTS, Debian 13 | x64, ARM64 |
|
||
|
||
Все шесть вариантов входят в первую версию: общий код разрабатывается сразу
|
||
для трёх ОС, сборки и аппаратная проверка нужны для каждой архитектуры.
|
||
Linux проверяется на обоих указанных дистрибутивах. Эти границы — требования,
|
||
а не уже подтверждённая совместимость. Electron и инструменты сборки выбирать
|
||
с учётом всей матрицы, не привязывая общую реализацию к одной ОС.
|
||
|
||
Владелец подтвердил доступность всех шести вариантов и выполняет аппаратные
|
||
проверки по подготовленной агентом инструкции, передаёт результаты и замеры.
|
||
Известная конфигурация: MacBook Air M1, 16 ГБ RAM. Фактические версии ОС,
|
||
характеристики остальных компьютеров, дисплеи и переходники записать при проверке.
|
||
|
||
## Что существует сейчас
|
||
|
||
- `../evening_detective_frontend/src/components/ScreenPage.vue`: отдельный
|
||
браузерный экран, опрос сервера раз в 1000 мс, запуск через `media.play()`,
|
||
подготовка кнопкой и загрузка медиа по URL.
|
||
- `../evening_detective_frontend/src/components/GameScreensPanel.vue`: экраны,
|
||
привязка, звук и плейлисты. Найти callers и остальное управление в `GamePage.vue`
|
||
перед переносом поведения.
|
||
- `../evening_detective_frontend/src/components/ScreenPreview.vue`: предпросмотр.
|
||
- `../evening_detective_server/api/main.proto`: ScreenState, ScreenCommand,
|
||
ScreenPlan, MusicState, RPC управления экраном и результатами.
|
||
- `../evening_detective_server/internal/app/screens.go` и `screen_plan.go`:
|
||
серверный поток экранов и плана показа.
|
||
|
||
Режимы текущего экрана: обложка, вступление, завершение вступления, закрывающее
|
||
видео, завершение показа, результаты, таймер и текст. Существующие браузерные
|
||
экраны и управление ведущего должны продолжить работать.
|
||
|
||
## Архитектура
|
||
|
||
1. Основной процесс Electron управляет окнами, локальным состоянием показа,
|
||
загрузками и диском. Он принимает только ограниченный набор проверяемых IPC
|
||
команд; не предоставляет renderer произвольный доступ к Node.js или файлам.
|
||
2. Окно пульта на Vue отправляет локальные команды. Окно показа отображает
|
||
состояние и возвращает фактические события готовности, старта, паузы и ошибки.
|
||
UI не выдаёт отправку команды за успешный запуск.
|
||
3. Оба окна загружают поставляемые с приложением ресурсы. Для медиа используется
|
||
ограниченный локальный протокол с поддержкой Range для перемотки видео.
|
||
`contextIsolation` включён, `nodeIntegration` выключен; preload предоставляет
|
||
только необходимый интерфейс. Внешние страницы не получают доступ к нему.
|
||
4. Пакет игры: снимок плана и необходимых данных, версия, список ресурсов,
|
||
размеры и SHA-256. Загрузка во временные файлы, проверка, затем атомарная
|
||
активация полного пакета. Старый готовый пакет сохраняется при ошибке обновления.
|
||
Данные хранятся в каталоге приложения, не в Git и не рядом с исполняемым файлом.
|
||
5. Сервер проверяет право организатора на скачивание материалов. Существующий
|
||
API используется где достаточно; манифест добавляется минимальным расширением.
|
||
Токены не записываются в пакет игры и логи.
|
||
6. После подготовки основной процесс — единственный источник состояния локального показа.
|
||
Команды пульта компьютера через IPC и телефона через WebSocket обрабатываются
|
||
последовательно; состояние с возрастающей ревизией рассылается обоим пультам.
|
||
Серверная синхронизация не задерживает команды. Команды сайта не управляют
|
||
desktop-показом; возврат интернета не повторяет старые серверные команды.
|
||
7. Приложение по явному действию оператора раздаёт мобильный Vue-пульт со встроенного
|
||
HTTP-сервера на выбранном IPv4-интерфейсе. Код сопряжения, подтверждение на
|
||
компьютере и временная HttpOnly-cookie ограничивают доступ. Сеансы только в памяти;
|
||
отключение пульта отзывает их. Рабочая сеть — своя Wi-Fi/LAN или точка доступа:
|
||
HTTP не шифрует трафик. Сертификаты и управление через интернет не входят в MVP.
|
||
В сетевом API нет произвольного доступа к диску, IPC и токенам сайта.
|
||
8. Телефон управляет всеми режимами показа, шагами, таймером, музыкой, громкостью
|
||
и перемоткой. Подготовка игры и дисплея остаётся на компьютере. Команды имеют
|
||
идентификаторы для дедупликации; после потери связи управление блокируется,
|
||
показ продолжается. Переподключение получает снимок состояния без повтора команд.
|
||
Vue-компоненты и типы пультов общие внутри screen, различается транспорт.
|
||
Общий пакет с сайтом заранее не выделяется.
|
||
9. Текущие результаты игры загружаются онлайн с отметкой времени; офлайн доступны
|
||
только последние сохранённые данные с явным предупреждением оператору.
|
||
Серверная игра, ответы команд и вычисление новых результатов офлайн не работают.
|
||
|
||
## Быстрый запуск
|
||
|
||
Подготовить ближайшее медиа и следующий музыкальный трек заранее; не загружать
|
||
все видео в оперативную память. Повторно использовать подготовленные элементы.
|
||
Настроить autoplay для локального окна, проверить запуск со звуком после холодного
|
||
старта. Не зависеть от кнопки разблокировки браузерного экрана.
|
||
|
||
Рабочая цель измерения: для подготовленного медиа p95 от нажатия до фактического
|
||
начала звука/первого кадра не более 150 мс на целевом M1. Это критерий проверки,
|
||
а не уже подтверждённая гарантия. Измерять отдельно IPC, готовность проигрывателя
|
||
и физический вывод; `play()` и событие `playing` сами по себе не доказывают
|
||
задержку колонок или проектора. Если цель не достигнута, записать измерения и
|
||
согласовать решение до расширения приложения. На остальных компьютерах фиксировать
|
||
медиану/p95 и стабильность воспроизведения без обязательного порога 150 мс.
|
||
Использовать синтетические тестовые аудио/видео; в SCREEN-001 зафиксировать их
|
||
параметры и способ воспроизводимого получения. Бинарные тестовые файлы не коммитить.
|
||
Звук проверять по кабелю/USB и HDMI; Bluetooth не входит в приёмочную матрицу.
|
||
|
||
## Порядок работ
|
||
|
||
1. SCREEN-001: проверить Electron на всех шести вариантах, два дисплея, локальное
|
||
медиа и задержки, техническое подключение телефона по LAN; порог задержки — на M1.
|
||
2. SCREEN-002: получить полный и защищённый пакет материалов с сервера.
|
||
3. SCREEN-003: реализовать надёжную загрузку и локальное хранение пакетов.
|
||
4. SCREEN-004: реализовать локальный проигрыватель и команды, подготовку медиа.
|
||
5. SCREEN-005: собрать пульт, план показа и режимы экрана.
|
||
6. SCREEN-009: полный пульт телефона, сопряжение, общее состояние и восстановление связи.
|
||
7. SCREEN-006: добавить подключение игры и согласование с сервером.
|
||
8. SCREEN-007: обработать отключение дисплея, звук, сон и восстановление.
|
||
9. SCREEN-008: собрать артефакты для всех шести вариантов и провести приёмку на площадке.
|
||
|
||
После SCREEN-001 — решение о продолжении по результатам всей матрицы платформ.
|
||
Разработка на одной ОС не заменяет аппаратную проверку остальных ОС и архитектур,
|
||
полноэкранного режима (включая macOS Spaces), проектора и вывода звука.
|
||
Для двух разных изображений рабочий стол должен быть расширен, а не дублирован.
|
||
Непройденные аппаратные проверки оставлять открытыми, не объявлять их успешными
|
||
по результату сборки или запуска на другой платформе.
|
||
|
||
## Границы и решения перед реализацией
|
||
|
||
- Базовый сценарий: один компьютер, один внешний дисплей, один активный пакет игры.
|
||
- Выбор аудиовыхода в MVP — системными настройками ОС; приложение показывает
|
||
инструкцию проверки звука. Маршрутизация звука на несколько устройств не входит.
|
||
- Не менять автоматическое приглушение/смешивание музыки без сверки текущего flow.
|
||
- В SCREEN-001 для каждой тестовой конфигурации зафиксировать ОС, архитектуру,
|
||
CPU/RAM, проектор/переходник, аудиовыход, форматы, разрешение и размер медиа.
|
||
- Полное управление игрой, локальный Go-сервер/БД, редактирование сценария,
|
||
автообновления и управление desktop через интернет — за пределами MVP.
|
||
- Подпись и notarization зависят от наличия Apple Developer; без них не обещать
|
||
установку без предупреждений Gatekeeper. Для Windows отдельно зафиксировать наличие сертификата подписи и
|
||
возможные предупреждения установки. Учётные данные не хранить в репозитории.
|
||
|
||
## Общая проверка
|
||
|
||
Для нового приложения настроить type-check, lint, lint:css и build; покрывать
|
||
тестами нетривиальные переходы, IPC, проверку пакетов и восстановление загрузок.
|
||
Для Electron использовать sandbox, contextIsolation и отключённый nodeIntegration.
|
||
Мобильный пульт проверять в Safari на iPhone и Chrome на Android. Замеры для
|
||
телефона вести отдельно: порог 150 мс относится к пульту компьютера.
|
||
|
||
Перед изменениями Vue изучить `../evening_detective_frontend/docs/FRONTEND_CODE_STANDARD.md`
|
||
и применять подходящие правила. При изменениях соседних репозиториев обязательны
|
||
их стандарты и проверки из корневого AGENTS.md; при изменении protobuf — штатная
|
||
генерация обеих сторон. Не редактировать сгенерированный API вручную.
|
||
|
||
Приёмка на всех шести вариантах (Linux — на обоих дистрибутивах): подготовить пакет → отключить интернет → пройти весь показ, музыку и
|
||
таймер → отключить/подключить проектор → перезапустить приложение → восстановить
|
||
сеть. Не должно быть сетевых запросов для локальных файлов, внезапного повтора
|
||
команд, потери готового пакета или показа пульта игрокам.
|