Роадмап: 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 снята целиком и оставлена честной строкой до итога разведки. Открытые вопросы архитектуры, границы паспорта и триггеры метки ревью приведены в соответствие.
42 lines
3.3 KiB
Markdown
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`; писать их наперёд, не зная фреймворка, значит написать
|
|
правила, которые придётся выбросить второй раз.
|