Files
ds-galo/openspec/changes/archive/2026-10-11-local-fs-storage-backend/proposal.md
T
iu 8638d1bbfc chore(openspec): archive completed changes and sync main specs
- 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
2026-10-11 10:19:44 +03:00

2.9 KiB

Proposal

Why

S3-совместимое хранилище (Garage на s3.localnet) в проде недоступно извне, поэтому отдача медиа не может идти напрямую из хранилища в браузер. Нужен слой хранения, который всегда отдаёт блобы через бэкенд, и локальный бэкенд для инсталляций без S3.

What Changes

  • Ввести интерфейс storage.Backend: Put/Delete/Get/Ping/EnsureBucket/Bucket, URL (всегда подписанный URL приложения) и обязательный ServeObject.
  • Реализовать бэкенд локальной ФС: блобы под корневым каталогом по непрозрачным ключам objects/{id}/{role}{ext}, защита от обхода пути, отдача через ServeContent.
  • Реализовать отдачу S3 через бэкенд: ServeObject тянет объект ranged GetObject из Garage (внутренняя сеть) и стримит браузеру; presigned URL больше не используются.
  • Публичный маршрут /api/objects/<key> с HMAC-подписью, сроком, Range и Content-Type обслуживает и авторизованных, и анонимные share-ссылки.
  • Ввести STORAGE_BACKEND=s3|fs и FS_ROOT; убрать S3_PUBLIC_URL; переименовать S3_PRESIGN_TTL → OBJECT_URL_TTL; дефолт — s3.
  • Сделать метку хранилища в health динамической.
  • Сделать формулировки отдачи файлов нейтральными к бэкенду в спеках photos и share-links.

Capabilities

New Capabilities

  • storage-backends: выбор и работа объектного хранилища — S3-совместимое (Garage) и локальная ФС; блобы всегда отдаются через бэкенд по подписанному URL, хранилище клиенту не раскрывается.

Modified Capabilities

  • photos: получение фото и скачивание не требуют presigned URL и обслуживаются бэкендом (подписанный URL).
  • share-links: просмотр по ссылке отдаёт подписанный URL, обслуживаемый бэкендом.

Impact

  • backend/internal/storage (интерфейс, общий Signer, FS-бэкенд, S3-proxy-отдача), сервисы photos и albums, app (маршрут отдачи, health), cmd/*, config.
  • Удаление presign-пути AWS SDK из storage.
  • .env.example, project.md, deploy/nginx-sse.conf.
  • Спеки photos, share-links, новая storage-backends.
  • Не затрагивает слой метаданных.