# ✨ Собрать каркас приложения и раздать его из бинарника - **Тип:** feature - **Категория:** Очередь - **Зачем:** Экранов нет и собирать их нечем: ни сборки фронтенда, ни раздачи статики в проекте не существует. - **Теги:** goal:web-access Двигает «Завершение» цели опосредованно: сам по себе каркас пользователю ничего не даёт, но без него ни один экран не соберётся. Видимая польза — приложение открывается и показывает, что оно живо и кто вошёл. Берётся после `spa-framework-choice`: собирать не на чем, пока фреймворк не выбран. ## Затрагивает - новый каталог фронтенда: исходники, зависимости, конфигурация сборки; - `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`. ## Рамки Экранов, кроме заглушки с именем вошедшего, не делаем — это `upload-and-status-screen` и `records-list-screen`. Установку на телефон не делаем — это `installable-pwa`. Появление шага сборки в гейте меняет требования к машине разработчика: это решение уровня ADR, и оно записывается.