- 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
5.0 KiB
5.0 KiB
Tasks
1. Интерфейс хранилища и перевод S3
- 1.1 Ввести интерфейс
storage.Backend(Put/Delete/Get/Ping/EnsureBucket/Bucket/URL) и сделать S3-клиент его реализацией; проверка —go build ./...проходит. - 1.2 Заменить
PresignGetнаURL(ctx, key)во всех вызовах; проверка —go build ./...иgo vet ./...без ошибок. - 1.3 Перевести
photos.Service,albums.Service,app.Serverиcmd/*на типstorage.Backend; проверка — сборкаcmd/serverиcmd/backfill-exifуспешна. - 1.4 Прогнать существующие S3-тесты (под
S3_ENDPOINT); проверка — тесты зелёные или корректно пропущены без env.
2. Бэкенд локальной ФС
- 2.1 Реализовать
fs.Backend(Put/Get/Delete/Ping/EnsureBucket/Bucket) с раскладкой<root>/<key>и нормализацией пути; проверка — юнит-тесты записи, чтения, удаления и отказа на../абсолютный ключ проходят. - 2.2 Реализовать
URLс HMAC-SHA256 подписью (key+exp,URL_SECRETс fallback наJWT_SECRET) и срокомOBJECT_URL_TTL; проверка — юнит-тесты валидной, истёкшей и подделанной подписи проходят.
3. Маршрут отдачи объектов
- 3.1 Добавить публичный
GET /api/objects/<key>с проверкой подписи и срока и стримингом черезhttp.ServeContent; проверка — httptest-тесты: валидный доступ (200), истёкшая подпись (403), Range (206), отсутствующий ключ (404). - 3.2 Проверить вывод
Content-Typeпо расширению с fallbackapplication/octet-stream; проверка — тест на.jpg/.webpи неизвестное расширение. - 3.3 Убедиться, что share-ссылки отдают рабочие подписанные URL на обоих бэкендах; проверка — интеграционный тест
share/*сfsиs3.
4. Конфигурация, health, проводка, документация
- 4.1 Ввести
STORAGE_BACKEND=s3|fs,FS_ROOT,URL_SECRETс условной валидацией; проверка — юнит-тестыconfig.Loadдляs3,fsи неполной конфигурации. - 4.2 Сделать метку хранилища в health динамической по выбранному бэкенду; проверка — тест
/api/healthдляs3иfs. - 4.3 Обновить
.env.exampleиproject.md; проверка — документированный запуск сSTORAGE_BACKEND=fsстартует и отдаёт файл.
5. Интеграционные проверки
- 5.1 Прогнать полный поток (загрузка → превью → просмотр → скачивание → share) на
fs; проверка — наблюдаемые результаты совпадают сs3. - 5.2 Убедиться, что дефолт
s3не меняет текущее развёртывание; проверка — запуск без новых переменных проходит как раньше.
6. Доставка только через бэкенд (без presign)
- 6.1 Вынести подпись URL в общий
Signerи использовать его вFSиS3; проверка — юнит-тесты подписи иgo build ./...проходят. - 6.2 Сделать
ServeObjectобязательной частьюstorage.Backend;app.serveObjectдиспетчеризуется без type-assert; проверка —go build ./.... - 6.3 Реализовать
S3.ServeObjectчерез rangedGetObject+ стриминг и HEAD черезHeadObject; проверка — httptest-тесты 200/206/416/404. - 6.4 Удалить presign-путь (
PresignClient/PresignGetObject), вернутьS3.URLкак app-signed; проверка — код presign отсутствует, тесты отдачи проходят. - 6.5 Конфиг: переименовать
S3_PRESIGN_TTL→OBJECT_URL_TTL, удалитьS3_PUBLIC_URL; обновить.env.example,project.md,deploy/nginx-sse.conf(proxy_buffering offдля/api/objects/); проверка — юнит-тестыconfig.Loadи документированный запуск. - 6.6 Интеграция: полный поток и share на
s3в proxy-режиме при недоступном извне хранилище; проверка — тест зелёный, наружу уходит URL бэкенда, не S3.