Files
transcriber/docs/conventions/web-ui.md
T
av 115b3796e8 Нарезка задач под целевое состояние: 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 снята
целиком и оставлена честной строкой до итога разведки. Открытые вопросы
архитектуры, границы паспорта и триггеры метки ревью приведены в
соответствие.
2026-08-10 21:36:54 +03:00

42 lines
3.3 KiB
Markdown

# Веб-UI
Конвенция: *как* мы пишем код приложения. Это правила оформления кода (How), а не
спецификация поведения — что именно приложение показывает и какие действия
обязано поддерживать, живёт в спеке OpenSpec.
**Фреймворк не выбран, и до выбора эта конвенция пуста.** Здесь стоит только то,
что решено и от фреймворка не зависит; всё остальное появится по итогу разведки
`spa-framework-choice`, которая же заведёт запись в `research/` и ADR.
Прежняя редакция описывала htmx с прямым запретом на шаг сборки и реактивные
фреймворки. Решение сменилось на SPA 2026-08-10, и та редакция снята целиком:
частичная подмена фрагментов, ветвление по `HX-Request` и деградация без JS к
SPA не относятся ни одним пунктом.
Логирование запросов — [logging.md](logging.md). Трансляция доменных ошибок
наружу — [errors.md](errors.md).
## Что решено
- **Приложение — SPA**, а не страницы, отрисованные сервером. Сервер отдаёт
контракт данных, разметку собирает клиент.
- **Приложение ставится на телефон** и запускается с ярлыка: манифест, иконки,
service worker.
- **Статика вшивается в бинарник** через `go:embed` и раздаётся им же. Внешнего
веб-сервера под статику не заводим, бинарник остаётся самодостаточным.
- **Шрифты и скрипты — со своего хоста**, без внешних. Внешних ресурсов времени
выполнения нет.
- **Офлайн-чтения расшифровок и очереди отправки без сети не делаем** — граница
цели [web-access](../../tasks/items/web-access.md). Без сети приложение
показывает состояние, а не пустой экран.
- **Web Push не делаем**: уведомления идут через apprise и ntfy, цель
[ready-notification](../../tasks/items/ready-notification.md).
- **Записи звука в приложении не делаем** — файл выбирают системным диалогом.
## Что не решено
Фреймворк, форма сборки, способ хранения состояния на клиенте, правила
разбиения на компоненты, обращение к API и показ ошибок. Всё это — предмет
`spa-framework-choice`; писать их наперёд, не зная фреймворка, значит написать
правила, которые придётся выбросить второй раз.