From 1c42ae2a75936f08d5bd4d5d49b1a11eadeb53f0 Mon Sep 17 00:00:00 2001 From: Fedorov Vladimir Date: Sat, 17 Oct 2026 17:33:16 +0700 Subject: [PATCH] init --- PLAN.md | 144 ++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 22 ++++++++ TASKS.md | 162 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 328 insertions(+) create mode 100644 PLAN.md create mode 100644 README.md create mode 100644 TASKS.md diff --git a/PLAN.md b/PLAN.md new file mode 100644 index 0000000..c89e5df --- /dev/null +++ b/PLAN.md @@ -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 — на обоих дистрибутивах): подготовить пакет → отключить интернет → пройти весь показ, музыку и +таймер → отключить/подключить проектор → перезапустить приложение → восстановить +сеть. Не должно быть сетевых запросов для локальных файлов, внезапного повтора +команд, потери готового пакета или показа пульта игрокам. diff --git a/README.md b/README.md new file mode 100644 index 0000000..a8862f2 --- /dev/null +++ b/README.md @@ -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` не изменять. diff --git a/TASKS.md b/TASKS.md new file mode 100644 index 0000000..25aeac2 --- /dev/null +++ b/TASKS.md @@ -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; установка и полный показ офлайн, + переподключение проектора, восстановление сети и минимум час работы на каждой + тестовой конфигурации. Владелец выполняет аппаратную приёмку по инструкции агента. +- Не входит: публикация в магазинах приложений и автообновления. +- Следующий шаг: выбрать минимальный инструмент упаковки для всей матрицы, + проверить среду сборки и наличие сертификатов, собрать артефакты и подготовить + инструкции для аппаратной приёмки.