# metadata-backends Specification ## Purpose Выбор и работа слоя метаданных: внешняя PostgreSQL или встроенная SQLite, с паритетным поведением для одного экземпляра приложения. ## Requirements ### Requirement: Выбор бэкенда метаданных Система SHALL поддерживать выбор бэкенда слоя метаданных параметром конфигурации, при этом встроенная SQLite SHALL быть значением по умолчанию. #### Scenario: Выбор по умолчанию - **WHEN** бэкенд метаданных не задан в конфигурации - **THEN** система использует встроенную SQLite с путём по умолчанию #### 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** схема метаданных выбранного бэкенда приведена к актуальному состоянию