food-market/src
nns 7de159d5f2
Some checks are pending
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker API / Build + push API (push) Waiting to run
Docker API / Deploy API on stage (push) Blocked by required conditions
feat(storage): IObjectStorage abstraction (Local + MinIO) — P2-15
Backend:
- src/food-market.api/Storage/IObjectStorage.cs — абстракция
  (SaveAsync, OpenAsync, DeleteAsync, PublicUrl). Имя реализации (Kind)
  для логов.
- LocalObjectStorage — ContentRoot/uploads/{key}. По умолчанию.
- MinioObjectStorage — S3-совместимый bucket, ключ-объекта совпадает с
  тем что хранится в БД (products/{id:N}/{guid}.png). PutObject с явным
  size (для NetworkStream копируем в MemoryStream).
- StorageOptions: Type=Local|Minio, Endpoint, AccessKey, SecretKey,
  UseSsl, Bucket=food-market-uploads.
- StorageBootstrap.AddObjectStorage — DI-регистрация с runtime fallback
  на Local если MinIO-config пустой; MinioBootstrap (IHostedService)
  создаёт bucket на старте, ловит ошибку и не валит API.
- UploadsController: GET /uploads/{**path} → стримит из IObjectStorage
  (cache-control 7 дней). Нужен когда MinIO активен — для Local nginx
  раздаёт быстрее, но фолбэк работает.
- ProductImagesController отрефакторен на IObjectStorage; URL'ы в БД
  остаются /uploads/products/{id}/{guid}.ext.

Тесты:
- StorageAbstractionTests (3/3 ✓): Local default, round-trip bytes,
  PublicUrl pattern.

Stage-готовность:
- deploy/docker-compose.yml на стейдже обновлён (через scp): добавлен
  minio container, depends_on в api, env переменные Storage__*.
  Bucket автосоздаётся.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-31 20:17:10 +05:00
..
food-market.api feat(storage): IObjectStorage abstraction (Local + MinIO) — P2-15 2026-05-31 20:17:10 +05:00
food-market.application feat(cqrs): MediatR partial — 3 handler-образца (TD-1) 2026-05-28 17:51:08 +05:00
food-market.domain feat(telegram): OwnerDailySummaryJob + bot binding (P2-14) 2026-05-31 19:50:33 +05:00
food-market.infrastructure feat(telegram): OwnerDailySummaryJob + bot binding (P2-14) 2026-05-31 19:50:33 +05:00
food-market.pos Phase 0: project scaffolding and end-to-end auth 2026-04-21 13:59:13 +05:00
food-market.pos.core Phase 0: project scaffolding and end-to-end auth 2026-04-21 13:59:13 +05:00
food-market.public fix(validation): validatePassword проверяет заглавную и цифру (соответствует хинту) 2026-05-18 12:52:59 +05:00
food-market.shared feat(pos-shared): контракты POS v1 в food-market.shared (P1-12a) 2026-05-28 12:03:04 +05:00
food-market.web feat(i18n): react-i18next ru/en + language switcher (P2-6a — базовая) 2026-05-31 20:03:33 +05:00