26 KiB
Завершённые задачи приложения площадки
SCREEN-002 — Собрать описание пакета через существующий API
- Статус:
DONE. - Дата: 2026-10-17.
- Репозиторий: только screen; бэкенд, frontend и protobuf не изменены.
- Уточнение владельца: использовать текущий API без изменений бэкенда; SCREEN-002 разрешена до завершения аппаратной приёмки SCREEN-001.
- Результат:
electron/screen-package.tsполучает игру, план и музыку через существующие GET endpoints и собирает ScreenPackage версии формата 1. Пакет содержит обложку, фон (с подстановкой обложки), вступительное аудио, заключительное видео, шаги и связанные плейлисты со всеми треками. Ссылки дедуплицируются, треки упорядочены по позиции/ID, посторонняя библиотека, данные участников и живые команды исключены. - Авторизация: существующий JWT используется только для API указанного сервера, не сохраняется в результате; редиректы API запрещены. Поддерживаются отмена, таймаут и безопасные ошибки без содержимого серверных ответов. Адреса с логином/паролем и ссылки с секретными параметрами отклоняются.
- Версия: metadataVersion — детерминированный SHA-256 нормализованных метаданных. Идентификаторы ресурсов — SHA-256 URL. Это не контрольные суммы файлов и не подтверждение готовности пакета. Размеры, хеши байтов и итоговая версия — SCREEN-003. Сервер не предоставляет атомарного снимка и хешей ресурсов.
- Проверки:
npm run type-check,npm run lint,npm run lint:css,npm test(12 тестов, включая 8 новых),npm run build,git diff --check— PASS. - Ограничения: проверено на фикстурах текущего JSON-контракта, живой сервер и реальные игровые файлы не проверялись. Загрузки файлов и новых кнопок нет; программный контракт подключается к интерфейсу при SCREEN-006. Существующие права доступа и публичная выдача файлов не менялись. Установочные архивы не пересобирались; аппаратная приёмка SCREEN-001 остаётся открытой.
- Следующий шаг: SCREEN-003 — скачать и проверить файлы, сформировать итоговую версию и атомарно активировать готовый локальный пакет.
SCREEN-003 — Скачивать и проверять материалы на диске
- Статус:
DONE. - Дата: 2026-10-17.
- Репозиторий: только screen; бэкенд, frontend и protobuf не изменены.
- Результат: PackageStore в основном процессе; потоковая последовательная загрузка, отмена, прогресс, контроль свободного места с резервом 64 МиБ, SHA-256/размер при записи и повторная проверка с диска. При обрыве повторяется целый текущий файл (выбор владельца); максимум три попытки, паузы 1/3 секунды, таймаут 30 секунд.
- Хранение: userData/packages, отдельные каталоги игры и версий, временная загрузка, синхронизация файлов, атомарная замена указателя текущей версии. Неудачное обновление сохраняет предыдущую готовую копию; отмена удаляет временные данные. При перезапуске проверяются все файлы и очищаются оставшиеся временные/старые версии. Повреждённый текущий пакет не становится готовым и доступен для удаления либо восстановления повторной загрузкой. Приложение запускается одним экземпляром.
- Доступ: локальная выдача только готовых файлов по ключу игры и ID ресурса, MIME/Range/no-store; произвольные пути и симлинки отклоняются. Скачивание медиа без JWT/cookies, до пяти проверенных редиректов, запрет HTTPS→HTTP и URL с секретами. Учтены MIME audio/wave и application/ogg существующего бэкенда.
- Проверки:
npm run type-check,npm run lint,npm run lint:css,npm test(26 тестов, 14 новых), сборка в составеnpm run smoke,git diff --check— PASS. Протестированы обрывы/повторы, отмена до активации, нехватка места до и во время загрузки, таймаут, повреждение при проверке/после перезапуска, восстановление, следы сбоя, редиректы, ошибочные ответы, симлинки и запрет параллельных изменений. - Офлайн-проверка: настоящий HTTP-сервер выключен после загрузки, новое хранилище восстановило и прочитало пакет. GUI smoke Electron 42.11.15: повторное открытие хранилища, WAV через локальный протокол, Range 206/44 байта, длительность 60 секунд, воспроизведение — PASS; тестовые --no-sandbox --mute-audio --disable-gpu.
- Ограничения: проверено на текущем Linux x64; macOS/Windows и аппаратная матрица SCREEN-001 остаются открытыми. GUI использовал синтетический второй дисплей. Рабочий сервер и реальные игровые материалы не проверялись; сервер не выдаёт эталонных хешей и атомарного снимка. Установочные архивы не пересобирались. UI загрузки/вход остаётся в SCREEN-006; хранилище предоставляет программный API.
- Следующий шаг: SCREEN-004 — подключить подготовленные локальные ресурсы к проигрывателю и игровым командам без ожидания сети.
SCREEN-005 — Пульт ведущего и все режимы показа
-
Статус:
DONE. -
Дата: 2026-10-17.
-
Репозиторий: только screen; бэкенд, frontend сайта и protobuf не изменены, новых зависимостей нет. Разработка продолжена по запросу владельца; аппаратная приёмка SCREEN-004 остаётся открытой.
-
Результат: все восемь ScreenMode, локальные обложка/фон, сообщения завершения, текст без HTML, список шагов с предыдущим/следующим, редакторы черновиков текста и таймера. Выбор шага не запускает звук/таймер, уход из основного медиарежима останавливает основной канал; музыка остаётся независимой. Ошибки и кнопки остаются на пульте. Готовность подтверждается окном после подготовки сцены.
-
Таймер: монотонное время в main, точный остаток, пауза/продолжение/сброс, отсчёт за другой сценой/закрытым окном, сброс при смене пакета. Интервалы и медиаснимки не накапливают дрейф; окончание не запускает звук или другой режим.
-
Предпросмотр: выбранный владельцем вариант реального окна, capturePage до 2 FPS, ширина до 960 px, один текущий кадр, проверка прав и сессии/ревизии. Нет второго проигрывателя; при закрытии окна и скрытии/сворачивании пульта захват прекращается.
-
Результаты: локальный контракт ResultsSnapshot, whitelist публичных полей, проверка ключа игры/времени/чисел/повторов, время снимка на пульте, таблица с прокруткой. Реальное получение/сохранение остаётся в SCREEN-006; без снимка честное пустое состояние. Смена пакета очищает снимок.
-
Проверки:
npm run type-check,npm run lint,npm run lint:css,npm test(46 тестов, 9 новых), сборка и GUI smoke,git diff --check— PASS. Проверены все восемь шагов, локальные изображения, кириллица/системный шрифт, черновик текста/экранирование HTML, таймер за скрытой сценой, права IPC, предпросмотр (10 захватов, ограничение частоты, без аудио/видео в пульте), повреждение/восстановление картинки, таблица на 50 синтетических командах и сохранение её прокрутки при обновлениях. Фикстура результатов существует только в тестовом renderer; после пересоздания окна в main результатов по-прежнему нет. -
Исправление по GUI: Chromium повторно использовал декодированную картинку после повреждения файла. Новый адрес изображения на каждую подготовку сцены устранил ложную готовность; повторный прогон проверил ошибку и восстановление.
-
Ограничения: текущий Linux x64/Electron 42.11.15, синтетический внешний дисплей, тестовые --no-sandbox --mute-audio --disable-gpu. Рабочий сервер, реальные игровые материалы и самостоятельный аппаратный/ручной проход владельца не проверялись. macOS/Windows и физический p95 на M1 не подтверждены; архивы не пересобирались. Инструкция ручной проверки — docs/SCREEN-005_ACCEPTANCE.md, запуск npm run acceptance.
-
Следующий шаг: SCREEN-006 — существующая авторизация, выбор игры/скачивание через интерфейс, снимок результатов и получение команд существующего сервера.
-
Исправление по ревизии (2026-10-17): повторный снимок той же таблицы обновляет дату получения без смены ревизии сцены и сброса прокрутки. Изменение вопросов, строк или очистка результатов по-прежнему обновляют сцену. Добавлен регрессионный тест.
SCREEN-006 — Подключение игры и синхронизация с сервером
- Статус:
DONE - Зависимости: SCREEN-002, SCREEN-005 (DONE, см. COMPLETED_TASKS.md).
- Цель: выбирать доступную организатору игру онлайн и сохранять автономность показа.
- Объём: существующая авторизация, список игр, загрузка пакета, снимок результатов, индикатор связи, проверка новой версии материалов, синхронизация статуса показа. Телефон отправляет команды существующему серверу сайта; desktop получает обновления через экранную сессию и GetScreenState (существующий polling 1000 мс). Серверные команды применяются локальным контроллером к подготовленным файлам; повторная версия не применяется дважды. Прямого подключения телефона к desktop нет. Уточнить минимальный серверный контракт по фактической реализации.
- Готовность: готовая игра открывается после перезапуска офлайн; секреты хранятся средствами ОС, не в пакете; истечение сессии не обрывает уже подготовленный локальный показ; обновления активируются явно. Результаты имеют время снимка. Возврат сети не повторяет устаревшие команды поверх локальных действий. При доступном сервере телефон управляет показом через существующий сайт; без сети воспроизведение и пульт компьютера продолжают работать.
- Проверка: сценарии offline/reconnect/истёкшей сессии/обновления игры; проверки затронутых репозиториев; существующий браузерный экран продолжает работать.
- Не входит: полноценная офлайн-игра, LAN-сервер и отдельный мобильный пульт desktop.
- Дата: 2026-10-17. Реализация только screen; бэкенд, сайт и protobuf не менялись.
- Результат: вход по email/паролю, проверка существующих прав, список игр, единое обновление JWT для конкурентных запросов, выход без прерывания показа. Токены и экранная сессия остаются в main; сохранение через safeStorage отдельно от пакетов. При недоступном шифровании ОС (включая Linux basic_text) вход только в памяти. Пароль не сохраняется, отказ в правах удаляет сохранённый вход.
- Материалы: загрузка/прогресс/отмена/проверка описания/повторная загрузка/удаление через существующий PackageStore. Выбранная игра обновляется только при закрытом показе; на время подготовки запрещены её открытие и смена выбора. Ошибка/отмена сохраняют прежний пакет; новая версия включается остановленной. Ключ выбранного пакета сохраняется, после перезапуска проверенная игра доступна офлайн без автоматического открытия окна и звука. Снимок результатов сохраняется отдельно по ключу пакета, содержит только поля таблицы и время получения; ошибка API оставляет последний успешный снимок. Сервер выдаёт результаты после finish.
- Управление: по выбору владельца общий пульт телефона и компьютера. Создание и привязка экранной сессии существующим API; GetScreenState раз в 1000 мс только при открытом показе, без параллельных запросов. Первая версия при подключении, повторном открытии и восстановлении сети — исходная отметка без старых команд. Локальные действия немедленны и не рассылаются другим экранам. Версии int64 сравниваются без потери точности, повторы и откат версии не повторяют команды; устаревшие ответы от другого окна/пакета/сессии отклоняются. Звук учитывается независимо от версии, первоначальное назначение звука не запускает медиа. Неподготовленные плейлисты не стримятся; переход музыки локальный, серверный AdvanceScreenMusic вызывается однократно только для соответствующего трека.
- Контракт: сервер не принимает точные подтверждения проигрывания/ошибки от экрана. На сайте сохраняется существующий heartbeat connected/disconnected; фактические подтверждения видны в desktop. Последнее состояние может объединять несколько команд между опросами. metadataVersion не обнаруживает замену байтов по тому же URL, для этого нужна повторная загрузка. После неопределённого исхода перехода музыки повторного POST нет. Права и публичная выдача файлов остались прежними.
- Проверки: type-check, ESLint, Stylelint, 63 теста (17 новых), сборка и GUI smoke — PASS. GUI с реальным тестовым HTTP-сервером проверил форму входа, загрузку, привязку, серверный play локального WAV, запрет обновления во время показа, локальную паузу при повторном опросе, offline/reconnect без старого STOP, новую команду после reconnect, результаты/выход и запреты IPC для окна показа. Старые сценарии всех восьми режимов, медиа, Range и preview также прошли. git diff --check — PASS; новые зависимости не добавлены, commit/push не выполнялись.
- Ограничения: тестовый сервер воспроизводит текущий JSON-контракт; рабочий сервер, реальные игровые файлы и прежний браузерный экран вручную не проверялись. GUI выполнен на Linux x64 с синтетическим внешним дисплеем и тестовыми флагами no-sandbox/mute-audio/disable-gpu. Хранилища секретов остальных ОС, физический звук/проектор и матрица платформ остаются для ручной приёмки; релизные архивы не пересобирались. SCREEN-001/SCREEN-004 сохраняют IN_PROGRESS.
- Инструкция: docs/SCREEN-006_ACCEPTANCE.md. Следующий этап: SCREEN-007 — устойчивость при отключении дисплея, управление сном и восстановление окон.
- Исправления по ревизии (2026-10-17, SCREEN-005/006): последнее полученное назначение звука сохраняется отдельно от исходной отметки команд. Изменение назначения после обрыва сети или повторного открытия показа применяется; неизменное назначение не отменяет локальный mute. Перестановка тех же треков теперь останавливает музыку с требованием повторной подготовки пакета.
- Проверка исправлений: 77 тестов (3 новых), type-check, ESLint, Stylelint, сборка, GUI smoke и git diff --check — PASS. Вручную проверен весь diff на применимые требования стандарта; нарушений не найдено. GUI: Linux x64, синтетический дисплей, no-sandbox/mute-audio/disable-gpu; физический звук, проектор и остальные ОС не проверялись, релизные архивы не пересобирались.
SCREEN-010 — Редактирование серверного плана экранов в пульте
- Статус:
DONE. - Дата: 2026-10-18.
- Результат: список шагов с «Показать», выделением текущего шага и переходами назад/вперёд; редактор добавления, удаления, порядка, восьми режимов, текста и параметров таймера. Сохранение и удаление общего плана через существующий API; отмена грязного черновика с подтверждением. Ошибка сохранения сохраняет черновик.
- Сервер: права и JWT проверяются прежним Online-транспортом; серверные операции доступны только пульту. Бэкенд, сайт, protobuf и зависимости не изменены.
- Офлайн: подтверждённый план хранится отдельно от пакета по ключу игры, восстанавливается после перезапуска. Локальная команда выполняется до сети; серверные запросы упорядочены, устаревшие ответы и неотправленные промежуточные переходы пропускаются. После обрыва ожидающие действия не повторяются; возврат сети сам не меняет показ. Следующее новое действие снова пробует сервер.
- Синхронизация: план обновляется и при закрытом показе; фоновый опрос не меняет черновик. Последнее сохранение заменяет общий план. Сохранение не меняет сцену; изменение активного шага снимает выделение. Собственные подтверждения не сбрасывают повторно таймер/медиа, конкурентный переход с сайта учитывается.
- Проверки: type-check, ESLint, Stylelint, 88 тестов, сборка и полный Electron GUI smoke — PASS. Smoke покрывает редактор, отказ сохранения, текст/таймер, перестановку, отмену, удаление и запрет IPC из окна показа. Отдельные тесты покрывают офлайн/перезапуск, быстрые переходы, запоздалые ответы, смену игры, конкурентный таймер и назначение звука. Проверки HTTP/GUI выполнялись вне песочницы; внутри неё HTTP-тест получает EPERM.
- Ревью: ручная проверка diff по применимым правилам и независимое ревью синхронизации; найденные ошибки исправлены, добавлены регрессионные тесты. git diff --check — PASS. README и руководство ведущего обновлены.
- Ограничения: GUI использует синтетический внешний дисплей и локальный тестовый сервер; физический проектор, звук и рабочий сервер отдельно не проверялись. Сборка предупреждает о JS chunk >500 kB. Установочные архивы не пересобирались; commit и push не выполнялись.