- pluggable per-domain Repository interfaces; PostgreSQL and SQLite impls - SQLite on modernc.org/sqlite (WAL, busy_timeout, foreign_keys, immediate tx) - separate migrations/sqlite and db.MigrateSQLite; store.NewPostgres/NewSQLite - cmd/reconcile compares object storage with the journal (report, then --delete) - storage.Backend.List and photos.Repository.AllStorageKeys - DB_BACKEND/SQLITE_PATH and STORAGE_BACKEND/FS_ROOT selectable; local defaults (sqlite ./galo.db, fs ./data) - Makefile reconcile/reconcile-delete; docs and .env.example updated
5.3 KiB
Spec Delta
Purpose
Выбор и работа слоя метаданных: внешняя PostgreSQL или встроенная SQLite, с паритетным поведением для одного экземпляра приложения.
ADDED Requirements
Requirement: Выбор бэкенда метаданных
Система SHALL поддерживать выбор бэкенда слоя метаданных параметром конфигурации, при этом PostgreSQL SHALL оставаться значением по умолчанию.
Scenario: Выбор PostgreSQL
- WHEN в конфигурации задан бэкенд PostgreSQL
- THEN метаданные читаются и пишутся во внешнюю PostgreSQL
Scenario: Выбор встроенной SQLite
- WHEN в конфигурации задан бэкенд SQLite
- THEN метаданные читаются и пишутся в локальный файл SQLite без внешней службы
Scenario: Неполная конфигурация
- WHEN конфигурация выбранного бэкенда неполна
- THEN система отказывается стартовать с явной ошибкой конфигурации
Requirement: Паритет поведения бэкендов
Оба бэкенда метаданных SHALL обеспечивать одинаковое наблюдаемое поведение системы: аутентификацию, альбомы, роли и доступ, фото, объектный журнал, сборку мусора и очередь генерации вариантов.
Scenario: Одинаковое поведение API
- WHEN один и тот же сценарий выполняется на PostgreSQL и на SQLite
- THEN наблюдаемые результаты и ошибки API совпадают
Scenario: Соблюдение прав доступа
- WHEN на любом бэкенде участник без прав выполняет запрещённое действие
- THEN система отклоняет действие одинаковым образом
Requirement: Встроенный одиночный экземпляр
Бэкенд SQLite SHALL работать как самодостаточный режим для одного экземпляра приложения, и система SHALL отвергать или явно документировать использование одного файла SQLite несколькими экземплярами.
Scenario: Один экземпляр
- WHEN приложение запущено в единственном экземпляре
- THEN SQLite корректно обслуживает всех пользователей этого экземпляра
Scenario: Совместная работа с файлом
- WHEN предполагается совместная работа нескольких экземпляров с одним файлом SQLite
- THEN конфигурация считает такой режим неподдерживаемым
Requirement: Атомарность жизненного цикла объектов
На обоих бэкендах привязка готового объекта к фото и заявка объекта на удаление SHALL быть атомарными и SHALL исключать привязку объекта, который собирается быть удалён, и удаление используемого объекта.
Scenario: Конкурентная привязка и сборка мусора
- WHEN привязка объекта и заявка на его удаление происходят одновременно
- THEN система либо привязывает объект без удаления, либо удаляет его без привязки
Scenario: Повторная привязка
- WHEN объект уже привязан к фото в роли
- THEN повторная привязка приводит к согласованному состоянию без дублей
Requirement: Устойчивость к перезапуску
Очередь генерации вариантов и сборка мусора SHALL восстанавливаться из состояния слоя метаданных после перезапуска на обоих бэкендах, и система SHALL применять схему метаданных при старте.
Scenario: Незавершённые задания
- WHEN процесс перезапускается с незавершёнными заданиями генерации вариантов
- THEN обработка заданий продолжается
Scenario: Применение схемы
- WHEN приложение стартует с выбранным бэкендом
- THEN схема метаданных выбранного бэкенда приведена к актуальному состоянию