This commit is contained in:
2026-10-17 17:33:16 +07:00
commit 1c42ae2a75
3 changed files with 328 additions and 0 deletions
+144
View File
@@ -0,0 +1,144 @@
# План приложения площадки
## Результат первой версии
Оператор выбирает игру, скачивает пакет показа и видит подтверждение готовности.
Пульт находится на основном экране компьютера; отдельное окно показа открывается на выбранном
внешнем дисплее. Аудио, видео, изображения и выбранные музыкальные плейлисты
читаются с диска. Пульт переключает показ и управляет воспроизведением локально.
После подготовки потеря интернета не мешает локальному показу и таймеру.
«Все материалы» в первой версии — все ресурсы, необходимые окну показа:
вступление, закрывающее видео, обложка, фон, материалы шагов плана, выбранные
плейлисты и ресурсы интерфейса, включая шрифты. Полная локальная копия материалов
игроков, редактора сценария и печатных документов не входит в первую версию.
Это рабочая граница 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. После подготовки основной процесс — источник состояния локального показа.
Серверная синхронизация не задерживает команды. В MVP удалённые команды с
телефона не управляют desktop-показом: параллельные источники исключены.
Возврат сети не должен перезапускать старую серверную команду поверх локальной.
7. Текущие результаты игры загружаются онлайн с отметкой времени; офлайн доступны
только последние сохранённые данные с явным предупреждением оператору.
Серверная игра, ответы команд и вычисление новых результатов офлайн не работают.
## Быстрый запуск
Подготовить ближайшее медиа и следующий музыкальный трек заранее; не загружать
все видео в оперативную память. Повторно использовать подготовленные элементы.
Настроить autoplay для локального окна, проверить запуск со звуком после холодного
старта. Не зависеть от кнопки разблокировки браузерного экрана.
Рабочая цель измерения: для подготовленного медиа p95 от нажатия до фактического
начала звука/первого кадра не более 150 мс на целевом M1. Это критерий проверки,
а не уже подтверждённая гарантия. Измерять отдельно IPC, готовность проигрывателя
и физический вывод; `play()` и событие `playing` сами по себе не доказывают
задержку колонок или проектора. Если цель не достигнута, записать измерения и
согласовать решение до расширения приложения. На остальных компьютерах фиксировать
медиану/p95 и стабильность воспроизведения без обязательного порога 150 мс.
Использовать синтетические тестовые аудио/видео; в SCREEN-001 зафиксировать их
параметры и способ воспроизводимого получения. Бинарные тестовые файлы не коммитить.
Звук проверять по кабелю/USB и HDMI; Bluetooth не входит в приёмочную матрицу.
## Порядок работ
1. SCREEN-001: проверить Electron на всех шести вариантах, два дисплея, локальное
медиа и задержки; порог задержки — на M1.
2. SCREEN-002: получить полный и защищённый пакет материалов с сервера.
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 — за пределами MVP.
- Подпись и notarization зависят от наличия Apple Developer; без них не обещать
установку без предупреждений Gatekeeper. Для Windows отдельно зафиксировать наличие сертификата подписи и
возможные предупреждения установки. Учётные данные не хранить в репозитории.
## Общая проверка
Для нового приложения настроить type-check, lint, lint:css и build; покрывать
тестами нетривиальные переходы, IPC, проверку пакетов и восстановление загрузок.
Перед изменениями Vue изучить `../evening_detective_frontend/docs/FRONTEND_CODE_STANDARD.md`
и применять подходящие правила. При изменениях соседних репозиториев обязательны
их стандарты и проверки из корневого AGENTS.md; при изменении protobuf — штатная
генерация обеих сторон. Не редактировать сгенерированный API вручную.
Приёмка на всех шести вариантах (Linux — на обоих дистрибутивах): подготовить пакет → отключить интернет → пройти весь показ, музыку и
таймер → отключить/подключить проектор → перезапустить приложение → восстановить
сеть. Не должно быть сетевых запросов для локальных файлов, внезапного повтора
команд, потери готового пакета или показа пульта игрокам.
+22
View File
@@ -0,0 +1,22 @@
# Вечерний детектив — приложение площадки
Статус: планирование, реализация ещё не начата. Решения зафиксированы 17.10.2026.
Цель: ведущий управляет показом на компьютере с macOS, Windows или Linux, а подключённый монитор или
проектор показывает материалы игрокам. Все материалы показа заранее находятся
на диске; локальная команда не ждёт сеть или ответ сервера.
Стек: Electron + Vue + TypeScript + Vite. Первая версия включает шесть сборок:
macOS Intel/Apple Silicon, Windows x64/ARM64 и Linux x64/ARM64.
Поддерживаемые версии ОС и условия проверки описаны в PLAN.md.
Использовать текущие паттерны фронтенда и переиспользовать подходящие компоненты,
не переносить весь сайт в приложение и не выделять общий пакет заранее.
План: [PLAN.md](PLAN.md). Очередь реализации: [TASKS.md](TASKS.md).
Эти документы находятся здесь по прямому указанию владельца — исключение из
общего правила хранения задач в `../docs/agent`. Не дублировать их там.
Идентификаторы `SCREEN-*` относятся только к этому приложению.
Для начала: `Выполнить задачу: SCREEN-001`.
Новые задачи: `Новая задача: <описание>`.
Commit и push выполняет только пользователь. Вложенные `.git` не изменять.
+162
View File
@@ -0,0 +1,162 @@
# Задачи приложения площадки
Все задачи имеют статус TODO; выполнение ещё не начато. План и общие ограничения:
[PLAN.md](PLAN.md). Идентификаторы независимы от ED-* в корневом списке.
Обновлять статус и результат здесь; завершённые записи переносить в
`COMPLETED_TASKS.md` в этом каталоге после проверки. Коммиты и push не выполнять.
## SCREEN-001 — Проверить основу Electron на macOS, Windows и Linux
- Статус: `TODO`
- Зависимости: нет; первая задача.
- Цель: подтвердить выбор технологии на всех шести вариантах ОС/архитектуры
из PLAN.md до переноса функций проекта. Все задачи приложения учитывают эту
матрицу; Linux проверяется на Ubuntu 24.04 LTS и Debian 13.
- Объём: минимальный Electron + Vue + TypeScript + Vite; пульт и отдельное окно
показа; выбор дисплея; синтетические локальные аудио/видео; IPC start/pause/stop
и seek; безопасный preload и локальная выдача медиа с Range. Подготовить сборки
для всех шести вариантов, инструкцию получения тестовых медиа и аппаратной
проверки. Бинарные тестовые файлы не коммитить.
- Готовность: запуск на всех шести вариантах; пульт остаётся на основном экране,
показ — на внешнем; звук запускается без ручной разблокировки autoplay;
pause/seek работают. Зафиксированы ОС, архитектура, CPU/RAM, медиаформаты,
оборудование и замеры. На M1 с 16 ГБ RAM цель p95 ≤150 мс; на остальных
компьютерах — медиана/p95 и стабильность без обязательного порога 150 мс.
- Проверка: type-check, lint, lint:css, build; минимум 30 запусков аудио и видео
на каждой тестовой конфигурации; отдельно холодный старт, fullscreen, физический
звук/кадр и отключённая сеть. Проверить кабель/USB и HDMI. Владелец выполняет
аппаратные проверки по инструкции агента и передаёт результаты.
- Не входит: сервер, авторизация, скачивание, полный пульт, публикация.
- Следующий шаг: прочитать frontend-стандарт, создать минимальный проект с учётом
всей матрицы и подготовить сборки/инструкцию. Доступность всех шести вариантов
подтверждена владельцем; фактические конфигурации записать при проверке.
Непройденные аппаратные проверки явно оставить открытыми.
## SCREEN-002 — Выдать версионированный пакет показа
- Статус: `TODO`
- Зависимость: SCREEN-001 подтверждён на всей матрице платформ.
- Репозитории: screen, server; frontend только при изменениях общего protobuf.
- Цель: получить полный список данных и файлов для подготовки конкретной игры.
- Объём: изучить доступ организатора, план, обложки, фон, вступление, видео,
плейлисты и вложенные ресурсы; использовать текущие RPC, добавить недостающий
манифест с версией, размерами, контрольными суммами и авторизованной загрузкой.
- Готовность: все ресурсы показа перечислены; изменение файла меняет версию;
отсутствие обязательного ресурса обнаруживается; чужую игру скачать нельзя;
существующие клиенты продолжают работать. Токены не входят в снимок пакета.
- Проверка: тесты полноты, версий и отказа в доступе; `go test ./...`; штатная
генерация protobuf и проверки frontend при затрагивании контракта.
- Не входит: локальная копия всей серверной БД и материалов вне показа.
- Следующий шаг: проследить callers RPC экранов и доступ к файлам, описать
минимальный контракт пакета и только затем менять API.
## SCREEN-003 — Скачивать и проверять материалы на диске
- Статус: `TODO`
- Зависимость: SCREEN-002.
- Цель: гарантировать полноту локального пакета до начала игры.
- Объём: прогресс и отмена загрузки, проверка свободного места, временные файлы,
SHA-256/размер, повтор после обрыва, атомарная активация, явное удаление пакета.
Незавершённые файлы никогда не выдавать как готовые.
- Готовность: все материалы читаются без сети; повреждённый или неполный пакет
не получает статус готовности; неудачное обновление сохраняет предыдущую версию;
перезапуск сохраняет готовность; удаление не затрагивает файлы вне хранилища.
- Проверка: тесты повреждения, нехватки места, обрыва/повтора, путей и обновления;
штатные проверки приложения; ручной запуск скачанного пакета без сети.
- Не входит: фоновое автообновление активного пакета и неограниченный кэш.
- Следующий шаг: определить формат каталога и манифеста, реализовать одну полную
загрузку с проверкой и затем обработать сбои.
## SCREEN-004 — Локальное воспроизведение и быстрые команды
- Статус: `TODO`
- Зависимость: SCREEN-003; использовать основу SCREEN-001.
- Цель: применять команды пульта независимо от сервера.
- Объём: локальное состояние в основном процессе; play/pause/resume/stop/replay,
seek, громкость и mute; плейлист, следующий трек и повтор; подготовка ближайшего
медиа; подтверждения фактического воспроизведения и понятные ошибки.
- Готовность: нет ожидания HTTP/опроса; повтор или быстрые последовательности
команд не создают двойной звук; музыка переходит дальше офлайн; нет загрузки всех
видео в RAM; политика одновременной музыки и речи соответствует текущему flow.
- Проверка: тесты переходов и устаревших/повторных команд; проверки приложения;
ручные seek/replay/смена трека и повтор замеров на всей матрице;
порог p95 ≤150 мс — на M1.
- Не входит: стриминг, несколько независимых проигрывателей на разных компьютерах.
- Следующий шаг: сверить существующую семантику ScreenCommand/MusicState и
реализовать один последовательный путь команда → проигрыватель → подтверждение.
## SCREEN-005 — Пульт ведущего и все режимы показа
- Статус: `TODO`
- Зависимость: SCREEN-004.
- Цель: провести показ выбранной игры с ноутбука без телефона.
- Объём: выбор подготовленного пакета, план шагов, предпросмотр без второго звука,
обложка, фон, вступление, закрывающее видео, текст, таймер, результаты и музыка;
фактические статусы загрузки, подготовки и воспроизведения на пульте.
- Готовность: все текущие режимы ScreenMode доступны; таймер работает локально
без накопления дрейфа от интервалов; пульт и технические сообщения не попадают
на проектор; неготовый файл нельзя ошибочно запустить как готовый.
- Проверка: проверки приложения и ручной проход полного плана без интернета;
предпросмотр не дублирует звук; кириллица, шрифты и изображения доступны офлайн.
- Не входит: редактор сценариев и полное управление командами/регистрациями игры.
- Следующий шаг: сопоставить текущие компоненты и callers с экраном пульта;
переиспользовать подходящее без преждевременного общего пакета.
## SCREEN-006 — Подключение игры и синхронизация с сервером
- Статус: `TODO`
- Зависимости: SCREEN-002, SCREEN-005.
- Цель: выбирать доступную организатору игру онлайн и сохранять автономность показа.
- Объём: существующая авторизация, список игр, загрузка пакета, снимок результатов,
индикатор связи, проверка новой версии материалов, синхронизация статуса показа.
Уточнить минимальный серверный контракт по фактической реализации.
- Готовность: готовая игра открывается после перезапуска офлайн; секреты хранятся
средствами ОС, не в пакете; истечение сессии не обрывает уже подготовленный
локальный показ; обновления активируются явно. Результаты имеют время снимка.
Возврат сети не повторяет старые команды; телефон не перехватывает desktop-показ.
- Проверка: сценарии offline/reconnect/истёкшей сессии/обновления игры; проверки
затронутых репозиториев; существующий браузерный экран продолжает работать.
- Не входит: полноценная офлайн-игра и удалённое управление desktop с телефона.
- Следующий шаг: сверить auth flow и модель сессий; зафиксировать правила
локального владения показом и отображения статуса на сервере.
## SCREEN-007 — Устойчивость на площадке
- Статус: `TODO`
- Зависимости: SCREEN-005, SCREEN-006.
- Цель: переживать типовые сбои без потери материалов и случайного показа пульта.
- Объём: отключение/возврат дисплея, смена разрешения и fullscreen, проверка
аудиовыхода каждой ОС, предотвращение сна во время показа, восстановление окон и
выбранного пакета после перезапуска. После сбоя звук самопроизвольно не возобновлять.
- Готовность: при отключении проектора показ безопасно приостанавливается, пульт
остаётся доступен; повторный вывод требует явного действия; выбранный пакет
сохранён, сон не прерывает активный показ, закрытие приложения освобождает блокировку.
- Проверка: аппаратный smoke на всей матрице с реальным внешним дисплеем,
переходником и звуком по кабелю/USB и HDMI; тесты восстановления состояния;
проверки приложения. Результаты аппаратных проверок передаёт владелец.
- Не входит: бесшовный аварийный резервный компьютер и несколько проекторов.
- Следующий шаг: проверить события Electron display/window и определить
минимальную безопасную реакцию на отключение внешнего экрана.
## SCREEN-008 — Сборки всех платформ и приёмка
- Статус: `TODO`
- Зависимость: SCREEN-007.
- Цель: получить устанавливаемую первую версию и подтверждённый сценарий площадки.
- Объём: воспроизводимые сборки macOS x64/arm64, Windows x64/ARM64 и Linux
x64/ARM64; инструкции установки/обновления и подготовки игры; решение о подписи
macOS/notarization по доступности Apple Developer и о подписи Windows по наличию
сертификата; локальные диагностические логи без секретов. Подписание macOS
на Mac, секреты вне Git; предупреждения установки без подписи документировать.
- Готовность: все шесть артефактов запускаются на соответствующих компьютерах,
Linux — на обоих дистрибутивах из PLAN.md; обновление сохраняет пакеты;
полный сценарий PLAN.md пройден. Записаны ОС/архитектура/версия приложения,
медиана/p95, форматы и ограничения; порог задержки применяется только к M1.
Непройденные проверки явно перечисляются и не позволяют объявить задачу DONE.
- Проверка: type-check, lint, lint:css, build; установка и полный показ офлайн,
переподключение проектора, восстановление сети и минимум час работы на каждой
тестовой конфигурации. Владелец выполняет аппаратную приёмку по инструкции агента.
- Не входит: публикация в магазинах приложений и автообновления.
- Следующий шаг: выбрать минимальный инструмент упаковки для всей матрицы,
проверить среду сборки и наличие сертификатов, собрать артефакты и подготовить
инструкции для аппаратной приёмки.