Закрыты все открытые вопросы проектирования. Пароль не покидает клиент (два ключа из мастера), TOFU для публичных ключей, устройства и конверт, атомарный rekey комнат, регистрация и контакты, схема SQLite и драйвер без cgo, сессии и CSRF, деплой через nginx+systemd, правила пушей, айдентика «Скобы» на системном mono. Иконки PWA в web/icons. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DbCjVfTFq4ZFG8juD45YJ
2.7 KiB
2.7 KiB
ADR-020: Схема SQLite, миграции и драйвер
Контекст
ADR-003 выбирает SQLite, но не схему и не драйвер. Выбор драйвера решает, нужен ли cgo: от этого зависит, можно ли собрать бинарь для Linux на Mac одной командой. Формулировка «ровно три внешних пакета» требует уточнения: прямые зависимости или всё содержимое go.sum.
Решение
- Драйвер —
modernc.org/sqlite, чистый Go. Сборка сCGO_ENABLED=0, кросс-компиляция тривиальна. - «Три внешних пакета» — три прямые зависимости в
go.mod:modernc.org/sqlite,github.com/SherClockHolmes/webpush-go,golang.org/x/crypto(радиargon2). Их транзитивные зависимости допускаются: они не выбираются нами и не импортируются напрямую. - Режим базы:
journal_mode=WAL,busy_timeout=5000,foreign_keys=ON,synchronous=NORMAL. Один файл, путь из конфигурации. - Миграции — нумерованные SQL-файлы, встроенные в бинарь через
embed. Версия схемы —PRAGMA user_version. При старте сервер применяет недостающие миграции по порядку, каждую в своей транзакции. Откатов нет: новая миграция исправляет предыдущую. - Таблицы:
users,sessions,devices,contacts,rooms,room_members,room_keys,queue. Полная схема —docs/storage.md. Никаких таблиц с историей сообщений. - Фоновые задачи раз в час: удаление из
queueзаписей старше 30 дней, устройств сlast_seenстарше 90 дней, истёкших сессий, лишних ключей комнат сверх двух последних.
Следствия
go buildбез тулчейна C. Деплой —GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build.modernc.org/sqliteмедленнее cgo-варианта в разы на тяжёлых запросах. Для очереди и метаданных маленького чата это незаметно.- Бэкап — копия файла базы при остановленном сервере или
VACUUM INTO. WAL-файл без основного файла бесполезен.