- 11 записей типа goal закрыты с причиной, называющей задачи-наследники; ROADMAP.md удалён, индекс остался один — BACKLOG.md; - 33 записи переписаны: ссылка «Двигает пункты N «Завершения» цели» уступила место прямому утверждению — без целей номера пунктов вели в никуда; - шапка BACKLOG.md размечена парой <!-- стадия -->, порядок строк теперь объявлен зависимостью, а не важностью.
56 lines
4.7 KiB
Markdown
56 lines
4.7 KiB
Markdown
# ✨ Собрать каркас приложения и раздать его из бинарника
|
|
|
|
- **Тип:** feature
|
|
- **Категория:** Очередь — Каркас приложения: экранов нет и собирать их нечем, а на экране стоят настройки, удаление, уровни текста и статистика.
|
|
- **Зачем:** Экранов нет и собирать их нечем: ни сборки фронтенда, ни раздачи статики в проекте не существует.
|
|
|
|
Каркас готовит четыре экрана — загрузку, состояние задачи, чтение текста и
|
|
список, — но сам по себе пользователю ничего не даёт. Видимое от него одно:
|
|
приложение открывается и достаёт данные с живого сервера, а не отдаёт пустую
|
|
страницу.
|
|
|
|
Фреймворк выбран 2026-08-11 — Vue 3 с роутером пятой версии и сборкой Vite
|
|
([ADR](../../docs/adr/ADR-2026-08-11-spa-on-vue.md)); правила кода приложения
|
|
лежат в [conventions/web-ui.md](../../docs/conventions/web-ui.md).
|
|
|
|
## Затрагивает
|
|
|
|
- новый каталог фронтенда: исходники, зависимости, конфигурация сборки;
|
|
- роут, отдающий `index.html` на неизвестный путь вне `/api/`: адреса маршрутов
|
|
обычные, а не после решётки;
|
|
- `Taskfile.yml` — шаг сборки статики и его место в `task gate` и `task image`;
|
|
- `Dockerfile` — сборка статики внутри образа, чтобы выкладка не зависела от
|
|
машины разработчика;
|
|
- раздача статики из бинарника через `go:embed` и роут под неё;
|
|
- `.gitignore` — каталог зависимостей и собранная статика;
|
|
- `docs/conventions/web-ui.md` — переписывается под выбранный фреймворк;
|
|
- `docs/architecture.md` — новый компонент и новая внешняя зависимость сборки.
|
|
|
|
## Критерии приёмки
|
|
|
|
- Статика собирается одной командой и вшивается в бинарник: запущенный бинарник
|
|
отдаёт приложение без каталога рядом. Оракул — сборка, запуск бинарника из
|
|
пустого каталога, запрос корня возвращает разметку приложения.
|
|
- Образ собирается на чистой машине без предустановленного окружения фронтенда.
|
|
Оракул — `task image` без локально установленных зависимостей фронтенда.
|
|
- Приложение показывает, кто вошёл, и обращается к API живого сервера. Оракул —
|
|
тест либо ручная проверка на запущенном сервере с сессией.
|
|
- Шаг сборки статики входит в `task gate` и краснеет при ошибке сборки. Оракул —
|
|
намеренно сломанный исходник роняет `task gate`.
|
|
- Обновление страницы на любом маршруте приложения открывает тот же экран, а
|
|
адрес внутри `/api/` в приложение не проваливается. Оракул — тест на два
|
|
запроса: неизвестный путь вне `/api/` отдаёт разметку, неизвестный путь внутри
|
|
`/api/` отдаёт ошибку контракта.
|
|
|
|
## Рамки
|
|
|
|
Экранов, кроме заглушки с именем вошедшего, не делаем — это `upload-and-status-screen`
|
|
и `records-list-screen`. Установку на телефон не делаем — это `installable-pwa`.
|
|
Готовый набор компонентов не берём: он не выбран, а способен удвоить собранный
|
|
файл.
|
|
|
|
Шаг сборки входит в гейт и в образ решением
|
|
[ADR](../../docs/adr/ADR-2026-08-11-spa-on-vue.md) 2026-08-11 — заново это
|
|
решение не принимается. Во что слой Node обходится образу по времени и по весу,
|
|
не замерялось: замер делает эта задача.
|