Files
bare/docs/decisions/020-storage-schema-and-driver.md
mayatnikovandClaude Fable 5 ae55c846aa ADR-015…024 и спецификации v1: криптография, протокол, хранение, UI, деплой, план
Закрыты все открытые вопросы проектирования. Пароль не покидает клиент
(два ключа из мастера), 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
2026-08-22 10:53:24 +03:00

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-файл без основного файла бесполезен.