- archive local-fs-storage-backend, sqlite-metadata-backend, storage-orphan-reconciliation, metadata-managed-jwt-secret, default-local-backends - sync specs: storage-backends, metadata-backends, storage-reconciliation, app-secrets; update photos/share-links - defaults reflected in specs: SQLite and local FS
65 lines
4.4 KiB
Markdown
65 lines
4.4 KiB
Markdown
# storage-reconciliation Specification
|
|
|
|
## Purpose
|
|
Ручная сверка объектного хранилища с журналом метаданных: инвентаризация обеих сторон,
|
|
отчёт о расхождениях и безопасное удаление осиротевших блобов.
|
|
|
|
## Requirements
|
|
|
|
### Requirement: Инвентаризация хранилища
|
|
Слой хранения SHALL перечислять объекты под заданным префиксом, возвращая ключ, размер и
|
|
время изменения, независимо от бэкенда (S3-совместимое или локальная ФС).
|
|
|
|
#### Scenario: Перечисление в S3-совместимом хранилище
|
|
- **WHEN** запрашивается список объектов под префиксом
|
|
- **THEN** возвращаются все ключи с этим префиксом с их размером и временем изменения
|
|
|
|
#### Scenario: Перечисление в локальной ФС
|
|
- **WHEN** хранилищем выбрана локальная ФС
|
|
- **THEN** возвращаются ключи всех блобов под префиксом с их размером и временем изменения
|
|
|
|
### Requirement: Инвентаризация журнала
|
|
Слой метаданных SHALL возвращать все ключи, зарегистрированные в журнале `objects`, на
|
|
обоих бэкендах (PostgreSQL и SQLite).
|
|
|
|
#### Scenario: Ключи журнала
|
|
- **WHEN** запрашиваются ключи журнала
|
|
- **THEN** возвращается множество ключей всех строк `objects`
|
|
|
|
### Requirement: Отчёт о расхождениях
|
|
По умолчанию сверка SHALL выполняться в режиме отчёта и SHALL не изменять хранилище;
|
|
отчёт SHALL различать сироты (в хранилище есть, в журнале нет) и пропавшие (в журнале
|
|
есть, в хранилище нет).
|
|
|
|
#### Scenario: Только отчёт
|
|
- **WHEN** сверка запущена без флага удаления
|
|
- **THEN** система выводит число и примеры сирот и пропавших, ничего не удаляя
|
|
|
|
#### Scenario: Пропавшие не восстанавливаются
|
|
- **WHEN** ключ есть в журнале, но отсутствует в хранилище
|
|
- **THEN** он сообщается как пропавший и не создаётся и не удаляется
|
|
|
|
### Requirement: Удаление сирот по явному запросу
|
|
Удаление сирот SHALL выполняться только по явному флагу, только для ключей под префиксом
|
|
объектов и только для блобов старше заданного минимального возраста.
|
|
|
|
#### Scenario: Удаление включено
|
|
- **WHEN** сверка запущена с флагом удаления
|
|
- **THEN** сироты старше минимального возраста удаляются из хранилища, а более молодые пропускаются
|
|
|
|
#### Scenario: Защита от гонки с загрузкой
|
|
- **WHEN** блоб создан недавно (моложе минимального возраста)
|
|
- **THEN** он не удаляется, даже если строки в журнале ещё нет
|
|
|
|
#### Scenario: Ограничение области
|
|
- **WHEN** удаление включено
|
|
- **THEN** удаляются только ключи под префиксом объектов, остальные не затрагиваются
|
|
|
|
### Requirement: Независимость от бэкендов
|
|
Сверка SHALL работать с любой комбинацией бэкенда хранения (S3 или ФС) и бэкенда
|
|
метаданных (PostgreSQL или SQLite).
|
|
|
|
#### Scenario: Комбинации бэкендов
|
|
- **WHEN** сверка запускается на выбранной конфигурации
|
|
- **THEN** она использует выбранные бэкенды хранения и метаданных без изменений кода
|