# План приложения площадки ## Результат первой версии Оператор выбирает игру, скачивает пакет показа и видит подтверждение готовности. Пульт находится на основном экране компьютера; отдельное окно показа открывается на выбранном внешнем дисплее. Аудио, видео, изображения и выбранные музыкальные плейлисты читаются с диска. Пульт переключает показ и управляет воспроизведением локально. После подготовки потеря интернета не мешает локальному показу и таймеру. Телефон управляет через существующий сервер сайта; приложение экрана получает с сервера обновления состояния. При потере интернета доступен локальный пульт компьютера. «Все материалы» в первой версии — все ресурсы, необходимые окну показа: вступление, закрывающее видео, обложка, фон, материалы шагов плана, выбранные плейлисты и ресурсы интерфейса, включая шрифты. Полная локальная копия материалов игроков, редактора сценария и печатных документов не входит в первую версию. Это рабочая граница 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 используется без изменений бэкенда и protobuf. SCREEN-002 собирает локальное описание и отпечаток метаданных; SCREEN-003 вычисляет размеры и SHA-256 скачанных файлов, итоговую версию и подтверждает готовность пакета. Токены не записываются в пакет игры и логи. 6. После подготовки основной процесс применяет локальные команды пульта компьютера через IPC без ожидания сервера. Материалы воспроизводятся с диска. 7. Телефон использует существующий пульт на сайте и отправляет команды серверу. Приложение экрана подключается к серверу как экранная сессия и получает обновления через существующий API CreateScreenSession/GetScreenState. Текущий браузерный экран опрашивает состояние раз в 1000 мс; desktop использует тот же серверный поток. HTTP-сервер, WebSocket-сервер, сопряжение и отдельный мобильный пульт в desktop не нужны. 8. Подключение игры, авторизация и получение серверных обновлений реализуются в SCREEN-006. Серверные команды проходят через локальный контроллер и используют подготовленные файлы. Одну версию команды нельзя применять повторно. При потере сети телефон не управляет desktop; уже запущенное воспроизведение и локальный пульт продолжают работать. При восстановлении сети необходимо сверить версии и не повторять устаревшую команду поверх локальных действий; правила согласования проверяются в SCREEN-006 на существующих ScreenState/ScreenCommand. 9. Текущие результаты игры загружаются онлайн с отметкой времени; офлайн доступны только последние сохранённые данные с явным предупреждением оператору. Серверная игра, ответы команд и вычисление новых результатов офлайн не работают. ## Быстрый запуск Подготовить ближайшее медиа и следующий музыкальный трек заранее; не загружать все видео в оперативную память. Повторно использовать подготовленные элементы. Настроить autoplay для локального окна, проверить запуск со звуком после холодного старта. Не зависеть от кнопки разблокировки браузерного экрана. Рабочая цель измерения: для подготовленного медиа p95 от нажатия до фактического начала звука/первого кадра не более 150 мс на целевом M1. Это критерий проверки, а не уже подтверждённая гарантия. Измерять отдельно IPC, готовность проигрывателя и физический вывод; `play()` и событие `playing` сами по себе не доказывают задержку колонок или проектора. Если цель не достигнута, записать измерения и согласовать решение до расширения приложения. На остальных компьютерах фиксировать медиану/p95 и стабильность воспроизведения без обязательного порога 150 мс. Использовать синтетические тестовые аудио/видео; в SCREEN-001 зафиксировать их параметры и способ воспроизводимого получения. Бинарные тестовые файлы не коммитить. Звук проверять по кабелю/USB и HDMI; Bluetooth не входит в приёмочную матрицу. ## Порядок работ 1. SCREEN-001: проверить Electron на всех шести вариантах, два дисплея, локальное медиа и задержки; порог задержки — на M1. 2. SCREEN-002: собрать описание материалов показа через существующий API; вычисление хешей файлов и подтверждение готовности — SCREEN-003. 3. SCREEN-003: реализовать надёжную загрузку и локальное хранение пакетов. 4. SCREEN-004: реализовать локальный проигрыватель и команды, подготовку медиа. 5. SCREEN-005: собрать пульт, план показа и режимы экрана. 6. SCREEN-006: добавить подключение игры, обновления экрана с сервера и управление с телефона через сайт. 7. SCREEN-007: обработать отключение дисплея, звук, сон и восстановление. 8. SCREEN-008: собрать артефакты для всех шести вариантов и провести приёмку на площадке. После SCREEN-001 — решение о продолжении по результатам всей матрицы платформ. Разработка на одной ОС не заменяет аппаратную проверку остальных ОС и архитектур, полноэкранного режима (включая macOS Spaces), проектора и вывода звука. Для двух разных изображений рабочий стол должен быть расширен, а не дублирован. Непройденные аппаратные проверки оставлять открытыми, не объявлять их успешными по результату сборки или запуска на другой платформе. ## Границы и решения перед реализацией - Базовый сценарий: один компьютер, один внешний дисплей, один активный пакет игры. - Выбор аудиовыхода в MVP — системными настройками ОС; приложение показывает инструкцию проверки звука. Маршрутизация звука на несколько устройств не входит. - Не менять автоматическое приглушение/смешивание музыки без сверки текущего flow. - В SCREEN-001 для каждой тестовой конфигурации зафиксировать ОС, архитектуру, CPU/RAM, проектор/переходник, аудиовыход, форматы, разрешение и размер медиа. - Полное управление игрой, локальный Go-сервер/БД, редактирование сценария, автообновления и прямое управление desktop с телефона по LAN — за пределами 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 — на обоих дистрибутивах): подготовить пакет → отключить интернет → пройти весь показ, музыку и таймер → отключить/подключить проектор → перезапустить приложение → восстановить сеть. Не должно быть сетевых запросов для локальных файлов, внезапного повтора команд, потери готового пакета или показа пульта игрокам.