Нарезка задач под целевое состояние: PWA, вход, хранилище

Роадмап: web-access переименована под приложение, которое ставится на
телефон; заведена цель ready-notification — уведомление о готовности
без открытого приложения.

Беклог: десять задач. Многопользовательская цепочка (oidc-login,
record-ownership, telegram-account-link), веб (json-api-for-spa,
spa-skeleton, upload-and-status-screen, records-list-screen,
installable-pwa), уведомления через apprise и ntfy, разведка выбора
фреймворка. Очередь: долги, хранилище, вход, приложение.

Решение сменилось с htmx на SPA, поэтому conventions/web-ui.md снята
целиком и оставлена честной строкой до итога разведки. Открытые вопросы
архитектуры, границы паспорта и триггеры метки ревью приведены в
соответствие.
This commit is contained in:
av
2026-08-10 21:36:54 +03:00
parent 4d1c2bf44c
commit 115b3796e8
19 changed files with 536 additions and 160 deletions
+43
View File
@@ -0,0 +1,43 @@
# ✨ Собрать каркас приложения и раздать его из бинарника
- **Тип:** 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, и оно записывается.