Files
ds-galo/openspec/changes/local-fs-storage-backend/proposal.md
T
iu ec8d907565 feat(storage): serve media through backend and add local FS backend
- introduce storage.Backend with S3 and local file-system implementations
- deliver all blobs via signed GET/HEAD /api/objects/<key> (Range, Content-Type)
- stream S3 objects through the backend; remove presigned URL path
- share shared HMAC Signer between backends
- remove S3_PUBLIC_URL; rename S3_PRESIGN_TTL to OBJECT_URL_TTL
- make storage label in health dynamic; nginx proxy_buffering off for objects
2026-10-11 09:15:03 +03:00

41 lines
2.9 KiB
Markdown

# 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`.
- Не затрагивает слой метаданных.