## Why Сервис отдаёт данные, но человеку их показать нечем: экранов нет вовсе, а браузер, открывший адрес сервиса, получает поверхность хранилища вместо приложения. Два основных сценария паспорта — «семейный архив» и «возвращение к записи» — не работают ни один, и упираются они в одно: приложения не существует. Каркас сам по себе экранов не приносит. Он приносит то, на чём они стоят: собранное приложение, которое сервис отдаёт браузером, открывается по любому своему адресу и показывает вошедшего, спросив об этом сервис. ## What Changes - Сервис начинает отдавать браузеру **приложение**: разметку и её ресурсы. Они лежат внутри самого бинарника, отдельного каталога рядом с ним не требуется, и внешнего веб-сервера под них не заводится. - Неизвестный адрес **вне корней сервиса** отдаёт разметку приложения, а не отказ. Так обновление страницы посреди приложения открывает тот же экран, а не ошибку. Корни перечислены поимённо, и адрес **внутри** корня в приложение не проваливается никогда: отказ контракта остаётся отказом контракта. - Разметка и её ресурсы отдаются **без сессии**: приложение само спрашивает сервис, кто вошёл, и уводит ко входу, когда не вошёл никто. Требование сессии на самой разметке отдавало бы отказ вместо экрана входа. - Открытое приложение показывает **вошедшего** — то, что сервис ответил о нём, — и это единственное, что оно сегодня показывает. - В сборку приходит **шаг сборки приложения**: он входит в набор проверок и в сборку образа. Спеками это не нормируется — у сборки другой потребитель, тот, кто собирает. ## Capabilities ### New Capabilities - `webapp`: приложение в браузере — чем сервис его отдаёт, каким адресом оно открывается, что делает обновление страницы посреди приложения и что человек видит, открыв его. ### Modified Capabilities - `access`: разметка приложения и её ресурсы пополняют перечень адресов, открытых без сессии; сегодня в нём только проба здоровья и метрики. ## Impact - новый каталог приложения: исходники, зависимости, настройка сборки; - `internal/controller/http` — маршрут, отдающий разметку на неизвестном пути вне корней, и раздача ресурсов приложения из бинарника; - `Taskfile.yml` — шаг сборки приложения, его место в наборе проверок и в сборке образа; - `Dockerfile` — приложение собирается внутри образа, чтобы выкладка не зависела от машины разработчика; - `.gitignore` — каталог зависимостей и собранное приложение; - новая внешняя зависимость сборки: Node и его установщик пакетов. На машину разработчика они не ставятся — шаг сборки зовёт их контейнером, поэтому требованием к машине становится docker, которым и так собирается образ; - `docs/conventions/web-ui.md` и `docs/architecture.md` — правила кода приложения перестают быть выведенными из выбора, а компонент и зависимость сборки появляются в описании устройства.