Files
agents/docs/agent/TASKS.md
T
2026-10-10 15:58:44 +07:00

241 lines
58 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Задачи проекта
Активный список задач для разработки и работы агента.
Новые задачи добавляются сюда после уточнения требований; отдельный файл-план
для нетривиальной задачи не создаётся. Завершённые задачи переносятся в
[`COMPLETED_TASKS.md`](COMPLETED_TASKS.md).
## Формат задачи
Каждая активная задача содержит:
- цель и ожидаемый результат;
- критерии готовности;
- проверку и ручной smoke-сценарий, если он нужен;
- ограничения и явно исключённые из задачи изменения;
- следующий конкретный шаг.
## Статусы
- `TODO` — готово к работе.
- `IN_PROGRESS` — выполняется.
- `BLOCKED` — заблокировано, причина указана в задаче.
- `DONE` — завершено и проверено.
## Активные задачи
### ED-029 — Автономная площадка и панель организатора
- Статус: `BLOCKED` — HTTPS, сертификат, локальный DNS и привязка IP ноутбука готовы; выдача DNS через DHCP Cudy настроена; требуется проверить Android/iPhone без WAN.
- Репозитории: корневой, `evening_detective_server`, `evening_detective_frontend`.
- Цель: реализовать принятый пользователем план из 15 последовательных этапов: автономное окружение; локальные организаторы; прежние адреса через Cudy; пакет игры; экспорт с блокировкой; локальный импорт; интерфейс передачи; полный билетный и игровой flow; пакет результатов; возврат онлайн; интерфейс возврата; устройства; панель состояния; сбор данных Cudy; Wi-Fi и испытание площадки.
- Критерии: проверяемый результат каждого этапа; цикл «онлайн → ноутбук → проведение → онлайн» через интерфейс с сохранением QR, билетов и связей; повторные импорты без дублей; мониторинг устройств и Wi-Fi; полный прогон без WAN, 100 клиентов и проверка покрытия.
- Ограничения: только тестовые игры до завершения возврата; существующие правила игры и формат `offline` сохраняются; без несогласованных новых зависимостей и отклонений от стандартов; без персональных списков игроков, CPU/памяти Cudy и автоматического переключения серверов; настройки роутера менять только по явному запросу пользователя; секреты и пакеты вне Git; commit/push выполняет пользователь.
- Проверка: Go-стандарт и `go test ./...`; PostgreSQL-интеграционные тесты для атомарности; frontend-стандарт, type-check, lint, lint:css и build; штатная генерация protobuf; ручные контрольные точки после этапов 3, 8, 11, 15.
- Прогресс: этапы 1–2 реализованы и проверены в локальном Docker-окружении. Добавлены отдельный Compose, подготовка образов заранее, постоянные тома, миграции перед стартом, healthchecks и прокси. Явный `APP_MODE=venue` отключает SMTP, фоновые письма и внешний webhook; почтовые операции аккаунта возвращают безопасную ошибку до изменения данных. Локальные аккаунты создаются штатным `dev-user.sql`, роли и правила автоматического подтверждения команд сохраняются. Подготовка этапа 3 реализована; его аппаратная приёмка и этапы 4–15 ещё не завершены.
- Дополнение по запросу пользователя: структура `venue` приведена к `prod` (`backend/`, `frontend/dist/`, `migrations/`, `Dockerfile.backend`, `docker-compose.yml`, `deploy.sh`); имена основных Compose-сервисов совпадают. Общая генерация `make build` / `make prod-build` готовит артефакты обеих папок; frontend собирается отдельно с настройками своего окружения. Текущие файлы `prod` при этой работе не изменяются; сборка проверяется с production-выводом в `/tmp`.
- Упрощение запуска: отдельные `init.sh` и `prepare.sh` удалены, всё собрано в `deploy.sh`. Единственная команда запуска — `make venue`: создаёт `.env` только при его отсутствии, при необходимости готовит зависимости/образы и автоматически создаёт организатора. Повторный готовый запуск не собирает и не скачивает образы. `make venue-update` явно пересобирает окружение с интернетом. Аккаунт организатора синхронизируется со значениями `.env` при каждом запуске. Первый запуск, повторный запуск без интернета и обновление проверяются `python3 tests/venue/deploy.py` с подставными командами; реальный готовый запуск проверен через Docker и API-smoke.
- Настройки площадки: по запросу пользователя необязательный `venue/.env.example` удалён; настройки создаются автоматически через `make venue`. Убраны ссылка и проверка примера; `python3 tests/venue/deploy.py` прошёл. Существующая `.env` не изменялась.
- Группировка проверок: `deploy.py` и `smoke.py` собраны в `tests/venue/` с поясняющим README, пути к площадке и команды в документации обновлены; для обычного запуска эти файлы не нужны. `python3 tests/venue/deploy.py` и `python3 tests/venue/smoke.py --verify` прошли; diff проверен.
- Уточнение названия: автономная площадка называется `venue`, чтобы не смешивать её с локальной разработкой. Папка, Make-команды, образ, Docker-проект, режим `APP_MODE=venue` и настройки `VENUE_*` переименованы; существующая `.env` перенесена с сохранением секретов и учётной записи. Служебные имена прежних томов сохранены для сохранности данных; тома подключаются как внешние и создаются автоматически при первом запуске. Go-тесты, тест запуска и API-smoke после переименования прошли; `prod` не изменён. Ручное ревью diff по стандарту Go выполнено.
- Проверка дополнения завершена: `make build PROD_DIR=/tmp/evening-artifacts-check` прошёл, backend и миграции в обоих наборах совпадают; type-check и две frontend-сборки прошли. Проверены Compose config, shell-синтаксис и diff. Local собран и запущен через новый `deploy.sh`; API-smoke и Firefox подтвердили вход, тестовую игру, подтверждённую команду и сохранность материала. Контрольные суммы файлов `prod` до и после работы совпадают. Проверка production-запуска не выполнялась; существующие файлы и конфигурация `prod` не изменены.
- Результат проверки этапов 1–2: ручное ревью diff по Go- и frontend-стандартам выполнено, отклонений нет; `gofmt`, `go test ./...`, frontend `type-check`, `lint`, `lint:css`, сборка и полный `sh venue/prepare.sh` прошли. Compose config и shell-синтаксис проверены. Smoke через API создал тестовую игру, подтверждённую команду и материал; после `down` / `up --no-build --pull never` всё сохранилось. Firefox без окна подтвердил реальный вход, экран игры и команду после перезапуска. Приложение не имеет внешнего маршрута сети. Повторная инициализация не перезаписывает секреты. Инструкции запуска и повторяемый API-smoke находятся в корневом README и `tests/venue/smoke.py`. Проверка телефонов при отключённом WAN ещё не выполнена.
- Внешние данные: запрошены модель/IP Cudy, постоянный IP ноутбука, доступ к проверенной прошивке и возможность DNS-проверки для сертификатов. Проверки телефонов, 100 клиентов и покрытия требуют оборудования.
- Привязка ноутбука на Cudy по явному запросу «закрепи сам»: перед изменением подтверждены текущие IP 192.168.10.155 и MAC BC:D2:2C:29:4A:96. Через штатную форму IP/MAC Binding добавлена запись `Venue laptop`, выполнен Save & Apply; повторное чтение подтвердило ровно одну новую запись с нужной парой IP/MAC и сохранность обеих существующих привязок. DHCP/DNS-настройки и прошивка не менялись. Проверка DNS venue по UDP/TCP после сохранения прошла. Принудительное переподключение ноутбука для проверки новой DHCP-аренды не выполнялось; проверка телефонов без WAN остаётся обязательной.
- Локальный DNS по согласованию пользователя добавлен: CoreDNS 1.14.7 запускается с venue на TCP/UDP 53 только на `VENUE_BIND_IP`; оба домена возвращают этот IPv4, AAAA-запросы не получают внешних адресов. Отдельные локальные зоны не пересылаются upstream; остальные домены направляются в 1.1.1.1/8.8.8.8 при доступном WAN. DNS подключён только к сети публикации портов и не имеет доступа к внутренней сети приложения/БД. Образ закреплён по версии, скачивается при отсутствии и используется повторно; новая инфраструктурная зависимость явно согласована пользователем. Локальная `.env` изменена только в `VENUE_BIND_IP=192.168.10.155`, секреты сохранены. `make venue` успешно пересобрал образ из готовых файлов, выполнил миграции и перезапустил HTTPS/DNS с сохранением томов. Настройки Cudy не менялись.
- Проверки DNS: `python3 tests/venue/deploy.py`, `python3 tests/venue/https.py --docker`, `python3 tests/venue/dns.py --docker`, `python3 tests/venue/dns.py --server 192.168.10.155`, shell-/Python-синтаксис и `git diff --check` прошли. Реальный CoreDNS в отдельной внутренней Docker-сети подтвердил локальные ответы по UDP/TCP и отсутствие внешних IPv6-ответов без WAN до/после перезапуска. Проверены Compose mount/порты/DNS-IP и изоляция backend; обычный внешний домен успешно разрешается через upstream на запущенной площадке. HTTPS-smoke с принудительным разрешением обоих имён только в IP ноутбука и обычной проверкой TLS подтвердил вход организатора, сохранность тестовой игры/команды/материала, SPA и отключённые email-операции. Ручное ревью diff выполнено; код Go/Vue и protobuf не менялся. Проверка DNS через DHCP Cudy и телефонов без WAN ещё требуется; IP ноутбука пока динамический.
- Проверка реального Cudy: TR3000, прошивка 2.5.27 DE, панель доступна на 192.168.10.1; текущий DHCP-IP ноутбука 192.168.10.155 ещё не закреплён. По предоставленному пользователем файлу выполнен вход и прочитаны Custom DNS и DHCP. В этих разделах нет формы статических записей «домен → IP»: Custom DNS выбирает upstream DNS, DHCP позволяет выдавать клиентам Preferred/Alternate DNS. Настройки роутера не менялись. Для сохранения штатной прошивки предложен отдельный локальный DNS на ноутбуке с двумя записями и выдачей его адреса через DHCP; это дополнение к прежнему плану требует согласования инфраструктуры. Пользовательский pass.txt защищён режимом 600 и исключён из Git; пароль и сессионные данные не выводились. Следующий шаг — согласовать реализацию локального DNS, закрепить IP, настроить DHCP и выполнить аппаратную приёмку.
- Выпуск сертификата по запросу пользователя начат: скачан официальный образ Certbot, отдельный ACME-аккаунт и запрос на два домена созданы в игнорируемом `venue/certificates/acme/` с ограниченным доступом. Certbot ожидает добавления двух TXT-записей DNS-01 в публичный DNS; доступ к DNS в среде отсутствует, значения переданы пользователю. Сертификат ещё не выдан и не установлен; production-ключи и настройки не использованы, площадка не перезапускалась. После появления записей проверить публичный DNS, завершить валидацию, установить полную цепочку и ключ в `venue/certificates/` и проверить их перед запуском.
- Результат выпуска сертификата: после добавления пользователем TXT-записей оба значения проверены через публичный DNS, DNS-01 успешно пройден. Отдельный сертификат Let's Encrypt для обоих прежних доменов установлен в `venue/certificates/fullchain.pem`, ключ — в `privkey.pem` с режимом 600; каталог и ACME-файлы вне Git, production-ключ не использован. Срок действия до 2027-01-08 06:53:26 UTC. OpenSSL подтвердил системное доверие полной цепочке, оба домена и соответствие ключа; игнорирование обоих файлов проверено. Автопродления нет: до истечения срока повторить DNS-01 и установить обновлённые PEM-файлы. Площадка в рамках выпуска сертификата не перезапускалась; Cudy и телефоны без WAN ещё не проверены.
- Актуальный запуск по последующему запросу пользователя: `make venue` всегда использует HTTPS-дополнение, выполняет `docker compose build --pull=false` из заранее подготовленных артефактов и `up --force-recreate --no-build --pull never`; тома данных сохраняются. `venue-update` и `venue-https` — алиасы единого запуска. Сертификат проверяется до Docker; Go/Vue и npm-зависимости при деплое не собираются. Отсутствующие runtime-образы и базовый Alpine скачиваются, имеющиеся не обновляются автоматически. HTTPS теперь используется smoke-проверкой по умолчанию. README и тесты приведены к единому поведению; `python3 tests/venue/deploy.py`, shell-синтаксис, Python-синтаксис, dry-run всех трёх Make-команд и `git diff --check` прошли; diff вручную проверен. Реальный перезапуск площадки с публичным сертификатом и сборка Docker-образа без WAN не выполнялись; Cudy и проверка телефонов остаются внешней контрольной точкой.
- Уточнение сборки по запросу пользователя: деплой больше не вызывает `make build`, Go/Vue-сборку или установку npm-зависимостей. Артефакты заранее готовятся существующим `make prod-build` в обеих папках; при отсутствии бинарника, Goose, bootstrap SQL, frontend или SQL-миграций запуск завершается до Docker с понятной ошибкой. `make venue-update` только упаковывает готовые файлы в Docker-образ и подготавливает runtime-образы. README обновлён; тесты первого, автономного и update-запуска подтверждают отсутствие make/npm, ошибки отсутствующих артефактов и сохранность настроек. `python3 tests/venue/deploy.py`, `python3 tests/venue/https.py`, `bash -n venue/deploy.sh`, `git diff --check` прошли; diff вручную проверен. Повторная реальная сборка приложения и запуск площадки не выполнялись; код дочерних репозиториев не менялся.
- Подготовка этапа 3: добавлены `make venue-https`, отдельное Compose-дополнение и Nginx-конфигурация для прежних доменов интерфейса/API. HTTP перенаправляется на HTTPS с сохранением пути и параметров; API и материалы доступны через домен интерфейса и прежний API-домен. HTTPS-дополнение задаёт публичные адреса ссылок без изменения `.env`. Сертификат и ключ подключаются только для чтения из игнорируемого каталога; до Docker проверяются доверие полной цепочке, оба домена, срок действия и соответствие ключа. Повторный HTTPS-запуск перечитывает сертификат без пересборки. Обычный HTTP-запуск сохранён; добавлены HTTPS-smoke и инструкции DNS-01, LAN, продления и ручной приёмки. Код Go/Vue, protobuf, схема БД и конфигурация `prod` не менялись; новых зависимостей нет.
- Проверки подготовки этапа 3: `python3 tests/venue/deploy.py`, `python3 tests/venue/https.py --docker`, `bash -n venue/deploy.sh` и `git diff --check` прошли; Python-файлы проверены на синтаксис. Проверены реальный Compose merge, прежние тома и внутренняя сеть backend. Временные Docker-контейнеры с тестовым CA подтвердили проверяемый TLS/SNI, оба домена, redirects, API/материалы, SPA-пути с параметрами, перезапуск и замену сертификата через reload; свои ресурсы тест удалил. Проверки сертификатов покрывают отсутствующие/повреждённые файлы, неверный и зашифрованный ключ, недоверенную/неполную цепочку, отсутствие каждого домена и истечение срока; ошибка возникает до Docker, повторный готовый запуск не скачивает и не собирает образы, `.env` сохраняется. Ручное ревью diff выполнено; стандарты Go/Vue не затронуты. Реальное HTTPS-развёртывание, системное доверие телефонов, Cudy и WAN-off smoke не проверены из-за отсутствия оборудования/сертификата. Commit/push не выполнялись.
- Подтверждение пользователя: venue работает в браузере ноутбука и на телефоне после настройки DNS. Проверка Android/iPhone при отключённом WAN и мобильных данных ещё не подтверждена.
- Проверка ноутбука после изменения настроек роутера пользователем: системный DNS разрешает UI-домен в 192.168.10.155; HTTPS UI и API возвращают HTTP 200 с этого IP, сертификат проходит проверку. В DHCP также получен второй DNS 192.168.10.10; его назначение не проверено. Пользователь подтвердил открытие venue на телефоне, проверка без WAN ещё не выполнена. В браузере ноутбука остаётся проверить обновление DNS-кэша и использование системного DNS.
- Результат настройки DHCP: по запросу пользователя в Cudy сохранён Preferred DNS=192.168.10.155, Alternate DNS пустой. Повторное чтение формы подтвердило значения и сохранение остальных настроек DHCP; проверка локальных доменов по UDP/TCP прошла. Получение DNS клиентами после обновления DHCP-аренды ещё не проверено.
- Следующий шаг: разрешить LAN TCP/UDP 53 и TCP 80/443 на ноутбуке, переподключить устройства и проверить этап 3 на Android/iPhone без WAN, затем последовательно выполнить этапы 4–15. IP/MAC Binding ноутбука сохранён, DNS и HTTPS уже запущены. Прежние адреса сами по себе не переносят production-игры и билеты. Общая задача не завершена и не переносится в архив.
### ED-024 — Общая дизайн-система фронтенда
- Статус: `TODO`
- Приоритет: `P1`
- Репозиторий: `evening_detective_frontend`
- Цель: создать единый источник правил, по которому можно последовательно делать новые экраны, компоненты и другие визуальные материалы.
- Контекст: во фронтенде уже есть визуальный язык на основе `base.css`, `main.css`, бумажных и металлических текстур, шрифта `a_OldTyper`, собственных компонентов и `naive-ui`; его нужно формализовать без смены общего характера.
- Решение: создать в фронтенде документ дизайн-системы и CSS-токены в существующем стиле проекта; описать цвета, типографику, размеры, отступы, сетку, адаптивность, поверхности, текстуры, состояния, фокус и доступность; зафиксировать правила для кнопок, полей, карточек, панелей, списков, таблиц, модальных окон, уведомлений, навигации, загрузки и ошибок; описать правила иконок, изображений, иллюстраций, именования и примеры правильного использования.
- Критерии: по системе можно без дополнительных устных решений спроектировать новый экран и написать его Vue/CSS-код; токены имеют однозначные имена и назначение; описаны основные состояния и доступность; правила согласуются с текущим визуальным языком; существующий фронтенд не меняет поведение и внешний вид в рамках этой задачи.
- Ограничения: не менять существующие страницы и компоненты; не делать редизайн приложения; не добавлять зависимости; переиспользовать текущие стили, ассеты и `naive-ui`; не создавать Figma-файл или полноценную отдельную библиотеку компонентов.
- Не входит: миграция текущих экранов на новые токены; реализация всех описанных компонентов; изменение API и продуктовой логики.
- Проверка: проверить полноту и однозначность документа и CSS-токенов; выполнить `cd evening_detective_frontend && npm run type-check && npm run lint && npm run lint:css`.
- Следующий шаг: изучить текущие `base.css`, `main.css`, стили и повторяющиеся паттерны компонентов, затем подготовить минимальный документ и набор токенов без миграции существующих экранов.
### ED-018 — Удаление неиспользуемых пользовательских файлов
- Статус: `TODO`
- Приоритет: `P1`
- Репозиторий: `evening_detective_server`
- Цель: автоматически удалять с диска пользовательские файлы, которые больше не используются приложением.
- Контекст: после удаления или перезаписи файла его физическая копия может оставаться на диске и занимать память.
- Решение: при удалении или перезаписи пользовательского файла проверять отсутствие ссылок на него в базе данных и сразу физически удалять файл с диска. Удалять только файлы, загруженные пользователями.
- Критерии: удалённый пользовательский файл исчезает с диска; старая версия перезаписанного файла исчезает с диска; файл, на который есть ссылка в базе данных, не удаляется; очистка выполняется сразу; удаление не оставляет файлового мусора.
- Ограничения: не удалять файлы без подтверждённого отсутствия ссылок в базе; не добавлять корзину, задержку или отдельную инфраструктуру без необходимости; не затрагивать системные и статические файлы.
- Не входит: пакетная очистка уже накопившихся orphan-файлов без проверки текущих ссылок; восстановление удалённых файлов; изменение политики хранения пользовательских данных.
- Проверка: `cd evening_detective_server && go test ./...`
- Ручная проверка: загрузить файл, удалить его и проверить отсутствие на диске; загрузить новую версию вместо старой и проверить удаление старой копии; проверить, что используемый файл сохраняется.
- Следующий шаг: изучить полный flow загрузки, удаления и перезаписи пользовательских файлов, места хранения и все ссылки на них в базе, затем выбрать общую точку физического удаления.
### ED-021 — Магазин игр: каталог и доступ к сценариям
- Статус: `TODO`
- Приоритет: `P1`
- Репозитории: `evening_detective_server`, `evening_detective_frontend`
- Цель: дать игроку возможность выбрать опубликованный сценарий в магазине, получить одну игру по нему и запустить её.
- Решение: автор или администратор отправляет сценарий на модерацию; администратор одобряет или отклоняет публикацию; одобренный сценарий появляется в каталоге магазина и на странице игры; администратор может бесплатно выдать игроку доступ.
- Критерии: опубликованный сценарий проходит модерацию; одобренный сценарий виден в магазине; отклонённый сценарий не публикуется; игрок получает доступ к одной игре по сценарию и может её запустить; администратор может выдать доступ вручную; используются существующие данные сценария для карточки магазина.
- Ограничения: переиспользовать текущие модели, авторизацию, каталог и flow запуска игры; не добавлять зависимость без необходимости; оплату в эту задачу не включать — способ оплаты определить отдельно.
- Не входит: платёжный сервис, рейтинги, отзывы, корзина, промокоды и автоматические выплаты автору.
- Проверка: `cd evening_detective_server && go test ./...`; `cd evening_detective_frontend && npm run type-check && npm run lint && npm run lint:css`.
- Ручная проверка: отправить сценарий на модерацию от автора, одобрить и отклонить его от администратора, проверить видимость в каталоге и на странице игры, выдать игроку доступ вручную и запустить игру.
- Следующий шаг: изучить текущие модели и API сценариев, каталог, авторизацию, модерацию и выдачу доступа к игре, затем выбрать минимальную модель магазина и точки интеграции.
### ED-022 — Вход через Яндекс ID
- Статус: `TODO`
- Приоритет: `P1`
- Репозитории: `evening_detective_server`, `evening_detective_frontend`
- Цель: дать всем пользователям возможность регистрироваться и входить через Яндекс ID.
- Решение: добавить OAuth-вход через Яндекс; при новой регистрации получать только email и запрашивать позывной отдельной формой; сохранить существующий способ входа; если email уже есть в системе, отправлять ссылку для подтверждения привязки Яндекс ID к аккаунту.
- Критерии: новый пользователь регистрируется через Яндекс; позывной вводится пользователем; существующий аккаунт связывается с Яндекс ID после подтверждения ссылки; после связывания доступны оба способа входа; обычная регистрация и вход не ломаются; используются только email и идентификатор Яндекс ID, без аватара и других данных.
- Ограничения: использовать существующую авторизацию, пользователей и email-flow; OAuth client ID, secret и callback URL хранить в переменных окружения; не добавлять новый платёжный или внешний сервис без необходимости; ручную проверку выполняет пользователь.
- Не входит: отключение обычного входа, получение аватара, импорт других данных профиля и восстановление доступа через Яндекс сверх стандартного OAuth-flow.
- Проверка: ручная проверка пользователем регистрации, входа, привязки по ссылке и сохранения обычного входа; после реализации — релевантные backend- и frontend-проверки по изменённым репозиториям.
- Следующий шаг: изучить текущие модели пользователей, авторизацию, email-подтверждения и frontend-flow входа, затем выбрать минимальные точки интеграции Яндекс OAuth.
### ED-014 — Периодическое сохранение сценариев в Git
- Статус: `TODO`
- Приоритет: `P2`
- Репозиторий: `evening_detective_server`
- Цель: автоматически сохранять все сценарии в отдельный Git-репозиторий после изменений.
- Решение: после изменения сценария запускать отложенное сохранение с ограничением не чаще одного раза в 5 минут; экспортировать сценарии в текущем экспортном формате, выполнять commit и push на сервере. Адрес репозитория, ветка и учётные данные задаются через переменные окружения. Ошибку commit/push показывать в панели администратора.
- Критерии: изменение сценария приводит к его появлению в отдельном репозитории; частые изменения не создают операции чаще одного раза в 5 минут; commit и push выполняются автоматически; ошибка синхронизации видна администратору; все сценарии экспортируются без потери данных.
- Ограничения: использовать серверный flow сохранения сценария; не хранить URL, ключи и пароли в коде или Git; не добавлять новую инфраструктуру и зависимости без необходимости; не выполнять commit или push в текущих репозиториях проекта.
- Не входит: ручной UI для редактирования Git, восстановление сценария из Git и ручная проверка пользователем.
- Проверка: ручная проверка пользователем — изменить сценарий, убедиться в появлении commit и push в отдельном репозитории, проверить ограничение частоты и отображение ошибки при недоступном push.
- Следующий шаг: изучить серверный flow изменения сценариев, экспортный формат, текущие фоновые механизмы и конфигурацию окружения, затем выбрать минимальную точку запуска отложенной Git-синхронизации.
### ED-017 — Демо-игра из каталога
- Статус: `TODO`
- Приоритет: `P1`
- Репозитории: `evening_detective_server`, `evening_detective_frontend`
- Цель: дать зарегистрированному пользователю возможность один раз пройти выбранную администратором демо-игру из каталога.
- Контекст: демо использует один конкретный сценарий; каждая попытка пользователя создаёт отдельную обычную игру с одной командой.
- Решение: в админ-панели администратор выбирает игру из каталога и назначает её демо-игрой, а также задаёт используемый сценарий. Пользователь запускает демо обычным игровым flow; незавершённую игру можно продолжить. После завершения повторный запуск запрещён, вместо него показывается сообщение о прохождении и предлагаются другие игры каталога.
- Критерии: администратор может назначить и настроить демо-игру; зарегистрированный пользователь видит её в каталоге; при запуске создаётся отдельная игра с одной командой; выбранный сценарий используется без подмены; незавершённая игра возобновляется; завершивший пользователь не может создать вторую демо-игру и видит альтернативы каталога.
- Ограничения: переиспользовать существующие каталог, авторизацию, создание игры, игровые состояния и результаты; не добавлять отдельный игровой flow или зависимость без необходимости; не ломать обычные игры.
- Не входит: несколько сценариев в одной демо-игре, повторное прохождение одним пользователем, анонимный доступ и отдельная система прогресса.
- Проверка: `cd evening_detective_server && go test ./...`; `cd evening_detective_frontend && npm run type-check && npm run lint && npm run lint:css`.
- Ручная проверка: назначить игру демо и выбрать сценарий, запустить её двумя пользователями, продолжить незавершённую игру, завершить одну и проверить запрет повторного запуска и показ других игр каталога.
- Следующий шаг: изучить модель каталога, админ-панель, создание игр и проверку завершённых игр пользователя, затем выбрать минимальную модель настройки демо и точку запуска из каталога.
### ED-013 — Просмотр ответов перед окончательным завершением игры
- Статус: `TODO`
- Приоритет: `P1`
- Репозитории: `evening_detective_server`, `evening_detective_frontend`
- Цель: дать команде возможность после завершения игрового этапа посмотреть свои ответы и правильные ответы, затем автоматически окончательно закрыть игру через 15 минут.
- Контекст: в таких играх одна игра соответствует одной команде; любой игрок команды может открыть просмотр ответов.
- Решение: после обычного завершения переводить игру в отдельный статус просмотра ответов; при первом открытии просмотра сохранять время начала 15-минутного периода; по истечении периода переводить игру в финальный статус с фиксацией результата и отображением формы отзыва. Если просмотр не открыт, игра остаётся в статусе просмотра ответов.
- Критерии: любой игрок команды видит ответы команды вместе с правильными ответами; первый просмотр запускает общий для игры таймер; время хранится на сервере и не сбрасывается обновлением страницы; до истечения 15 минут игровые действия недоступны; после истечения игра окончательно завершена, результат доступен, форма отзыва показывается; повторные открытия не продлевают период; доступ к ответам и переходы статусов проверяются на сервере.
- Ограничения: переиспользовать существующие endpoint, авторизацию, сервисы и форму отзыва; не добавлять отдельный сервис или зависимость без необходимости; не ломать текущие сценарии `draft`/`run`/`pause`/`finish`; сгенерированные protobuf-файлы менять только через существующую генерацию.
- Не входит: отдельный таймер для команды, так как одна игра содержит одну команду; изменение состава или подсчёта результата; редизайн формы отзыва.
- Проверка: `cd evening_detective_server && go test ./...`; `cd evening_detective_frontend && npm run type-check && npm run lint && npm run lint:css`.
- Ручная проверка: завершить игру, открыть просмотр ответов, обновить страницу и убедиться, что отсчёт продолжается; проверить недоступность игровых действий, автоматическое финальное завершение через 15 минут, результат и форму отзыва.
- Следующий шаг: изучить текущие переходы статусов игры, авторизацию игрока, endpoint выдачи ответов и flow формы отзыва, затем выбрать минимальное серверное хранение времени первого просмотра и точку запуска финального завершения.
### ED-009 — Оптимизировать изображения для web
- Статус: `TODO`
- Приоритет: `P1`
- Репозиторий: `evening_detective_server`
- Цель: ускорить загрузку фотографий на сайте, сохраняя оригиналы для печати.
- Контекст: сейчас для просмотра на сайте используются оригинальные изображения, подготовленные для печати, поэтому страницы загружаются медленно.
- Решение: при загрузке фотографии сохранять оригинал и создавать облегчённую web-версию; сайт должен получать web-версию, а оригинал оставаться доступным для печати. Для уже загруженных фотографий предусмотреть отдельную безопасную пакетную обработку с созданием web-версий без удаления оригиналов.
- Следующий шаг: изучить текущий flow загрузки, хранения и выдачи фотографий, проверить объём уже загруженных файлов, затем выбрать минимальный способ генерации web-версий и запуска обработки без новой инфраструктуры.
- Критерии: оригинал не теряется; web-версия создаётся автоматически для новых файлов; web-версии создаются для уже загруженных фотографий; endpoint сайта выдаёт web-версию; размер и время загрузки заметно уменьшены; ошибки обработки не приводят к потере оригинала; повторный запуск обработки безопасен.
- Ограничения: не менять оригиналы; не добавлять зависимость или отдельный сервис без необходимости; не менять API шире требуемого для переключения выдачи.
- Не входит: изменение качества оригиналов; полноценный CDN.
- Проверка: `cd evening_detective_server && go test ./...`
- Ручная проверка: загрузить фото, убедиться в наличии оригинала и web-версии, открыть страницу сайта и проверить, что выдаётся облегчённый файл.
### ED-010 — Расширить MCP функциями автора сценария
- Статус: `TODO`
- Приоритет: `P2`
- Репозиторий: `evening_detective_server`
- Цель: дать автору сценария возможность работать со сценарием через существующий MCP.
- Контекст: текущий MCP нужно дополнить авторскими операциями, чтобы сценарий можно было просматривать и редактировать без обходных ручных действий.
- Решение: изучить существующий MCP и добавить минимальный набор авторских функций для просмотра сценария, добавления и редактирования точек, а также связанных сущностей и операций, необходимых для полноценного авторского flow.
- Следующий шаг: инвентаризировать текущие MCP-инструменты, модели и сервисы сценариев, затем зафиксировать точный набор операций и права доступа автора.
- Критерии: автор может получить структуру и содержимое сценария; добавлять точки; редактировать точки; выполнять необходимые связанные операции через MCP; ошибки и недоступные операции возвращаются предсказуемо; существующие MCP-инструменты не ломаются.
- Ограничения: переиспользовать существующие сервисы и правила доступа; не дублировать бизнес-логику в MCP; не менять сгенерированный API без необходимости.
- Не входит: отдельный новый MCP-сервер; полноценный визуальный редактор; изменение сценарной модели без подтверждённой необходимости.
- Проверка: `cd evening_detective_server && go test ./...`
- Ручная проверка: подключиться к MCP от имени автора, просмотреть сценарий, добавить точку, изменить её и проверить результат в редакторе/хранилище.
### ED-002 — Rate-limit публичной регистрации команды
- Статус: `TODO`
- Приоритет: `P1`
- Репозиторий: `evening_detective_server`
- Цель: ограничить спам-регистрации и расход SMTP-квоты.
- Контекст: публичный `POST /api/games/{id}/registrations` не требует авторизации и вызывает отправку email.
- Решение: ограничить регистрации как минимум по `(IP, game)`, а повторную отправку — по email; лимиты должны быть согласованы до реализации.
- Следующий шаг: определить лимиты и выбрать место хранения счётчика без зависимости от production-базы.
- Критерии: превышение лимита отклоняется предсказуемой ошибкой; нормальная регистрация не ломается; есть тесты на границы лимита.
- Ограничения: не добавлять внешнюю инфраструктуру без необходимости; не блокировать легитимные регистрации организатора.
- Не входит: полноценная CAPTCHA и общая защита всех публичных endpoint.
- Проверка: `cd evening_detective_server && go test ./...`
- Ручная проверка: отправить несколько регистраций с одного IP и проверить ответ после достижения лимита.
### ED-003 — Очистка персональных данных регистраций
- Статус: `TODO`
- Приоритет: `P1`
- Репозиторий: `evening_detective_server`
- Цель: удалять персональные данные завершённых игр по утверждённому сроку хранения.
- Контекст: `contact_email` и связанные данные регистрации остаются в БД после завершения игры.
- Решение: очищать персональные поля команд завершённых игр, сохраняя данные, нужные для итогов; удалять истёкшие confirmation-токены.
- Следующий шаг: утвердить срок хранения и точный список полей, затем спроектировать job.
- Критерии: срок хранения зафиксирован в политике; job идемпотентен; игровые итоги не ломаются; есть тест на очистку.
- Ограничения: не удалять команды и данные, необходимые для итоговой таблицы; не запускать очистку без утверждённого срока хранения.
- Не входит: изменение всей политики хранения данных приложения.
- Проверка: `cd evening_detective_server && go test ./...`
- Ручная проверка: проверить завершённую игру после запуска job и убедиться, что итоги доступны без персональных полей.
### ED-004 — Просмотр графа сценария
- Статус: `TODO`
- Приоритет: `P2`
- Репозиторий: `evening_detective_frontend`
- Цель: показывать граф переходов сценария в редакторе.
- Решения: граф открывается из редактора в полноэкранной модалке; узлы — вступление, точки и вопросы; двери и текстовые маркеры — рёбра; `[Код]` и `([Код])` равнозначны.
- Реализация: чистый построитель графа, иерархическая раскладка сверху вниз, динамический импорт `vis-network`, подсветка связей выбранного узла.
- Следующий шаг: сверить актуальное состояние редактора и реализовать построитель, модалку и интеграцию без изменения сгенерированного API.
- Критерии: отображаются скрытые точки и вопросы; ненайденные коды видны отдельно; выбор узла подсвечивает входящие/исходящие связи; граф работает на мобильной ширине.
- Ограничения: не менять `src/api/generated/**`; не добавлять новую библиотеку, если текущего frontend-стека достаточно.
- Не входит: редактирование сценария через граф и автоматическое исправление ненайденных ссылок.
- Проверка: `cd evening_detective_frontend && npm run type-check && npm run lint && npm run lint:css && npm run build`
- Ручная проверка: открыть граф сценария с дверями, текстовыми маркерами, скрытой точкой и ненайденным кодом.
## Правила обновления
1. Перед началом работы перевести выбранную задачу в `IN_PROGRESS`.
2. Не держать больше одной задачи в `IN_PROGRESS`, если работа не разделена явно.
3. При блокировке записать конкретную причину и следующий внешний шаг.
4. После проверки обновить результат, перевести задачу в `DONE` и перенести её в `COMPLETED_TASKS.md`.
5. Устойчивое знание записывать в будущую базу знаний отдельно, а не раздувать этот список.