# Assets Proxy — Документація
## Огляд
DAARION використовує **MinIO** (S3-compatible object storage) для зберігання assets
(логотипи, банери, аватарки). Для доступу до assets без налаштування DNS для
`assets.daarion.space` використовується **Asset Proxy** через `city-service`.
## Архітектура
```text
┌─────────────┐
│ Frontend │ → /api/city/assets/proxy/microdao/logo/...
└─────────────┘
│
↓
┌─────────────┐
│ city-service│ → /city/assets/proxy/{path}
│ (FastAPI) │
└─────────────┘
│
↓
┌─────────────┐
│ MinIO │ → daarion-assets/microdao/logo/...
│ (Docker) │
└─────────────┘
```
## Контракт normalizeAssetUrl ↔ Asset Proxy
### Вхідний URL з БД
```text
https://assets.daarion.space/daarion-assets/microdao/logo/2025/12/02/abc123.png
```
### Вихідний URL для фронта (після normalizeAssetUrl)
```text
/api/city/assets/proxy/microdao/logo/2025/12/02/abc123.png
```
### Шлях до MinIO (всередині proxy)
```text
daarion-assets/microdao/logo/2025/12/02/abc123.png
```
**Важливо:** `normalizeAssetUrl` відрізає `daarion-assets/` з URL, тому proxy отримує шлях без префіксу бакету. Proxy додає `ASSETS_BUCKET` автоматично.
## Використання в компонентах
**ЗАВЖДИ** використовуйте `normalizeAssetUrl` для всіх asset URLs:
```typescript
import { normalizeAssetUrl } from '@/lib/utils/assetUrl';
// ✅ ПРАВИЛЬНО
// ❌ НЕПРАВИЛЬНО
```
## Endpoint
### City Service ENV
- **Path:** `/city/assets/proxy/{path:path}`
- **Method:** `GET`
- **Router prefix:** `/city` (монтується в `main.py` без додаткового префіксу)
- **Повний URL:** `/api/city/assets/proxy/{path}`
### Параметри
- `path` — шлях до файлу в MinIO (без префіксу бакету)
- Приклад: `microdao/logo/2025/12/02/abc123.png`
### Відповідь
- **200 OK** — файл знайдено
- `Content-Type`: `image/png`, `image/jpeg`, тощо
- `Cache-Control`: `public, max-age=86400, immutable`
- `Access-Control-Allow-Origin`: `*`
- **404 Not Found** — файл не знайдено в MinIO
## ENV змінні
### City Service
```env
MINIO_ENDPOINT=http://minio:9000
MINIO_ROOT_USER=assets-admin
MINIO_ROOT_PASSWORD=
ASSETS_BUCKET=daarion-assets
ASSETS_PUBLIC_BASE_URL=https://assets.daarion.space/daarion-assets
```
**Примітка:** `ASSETS_PUBLIC_BASE_URL` використовується тільки для генерації URL при завантаженні. Для читання використовується proxy.
## Приклади
### Завантаження asset
```python
from lib.assets_client import upload_asset
url = upload_asset(
file_obj,
content_type="image/png",
prefix="microdao/logo",
filename="logo.png"
)
# Повертає: https://assets.daarion.space/daarion-assets/microdao/logo/2025/12/02/abc123.png
```
### Відображення asset на фронті
```typescript
const logoUrl = "https://assets.daarion.space/daarion-assets/microdao/logo/2025/12/02/abc123.png";
const normalized = normalizeAssetUrl(logoUrl);
// normalized = "/api/city/assets/proxy/microdao/logo/2025/12/02/abc123.png"
```
## Troubleshooting
### 404 Not Found
1. Перевірте чи файл існує в MinIO:
```bash
docker exec daarion-minio mc ls minio/daarion-assets/microdao/logo/2025/12/02/
```
2. Перевірте чи правильний шлях передається в proxy:
```bash
curl -I "https://daarion.space/api/city/assets/proxy/microdao/logo/2025/12/02/abc123.png"
```
3. Перевірте логи city-service:
```bash
docker logs daarion-city-service | grep "assets/proxy"
```
### 500 Internal Server Error
1. Перевірте ENV змінні в docker-compose:
```bash
docker exec daarion-city-service env | grep MINIO
```
2. Перевірте чи MinIO доступний:
```bash
docker exec daarion-city-service curl -I http://minio:9000/minio/health/live
```
### Assets не відображаються на фронті
1. Перевірте чи компонент використовує `normalizeAssetUrl`:
```typescript
// ✅ ПРАВИЛЬНО
src={normalizeAssetUrl(url)}
// ❌ НЕПРАВИЛЬНО
src={url}
```
2. Перевірте в DevTools Network tab:
- Чи запити йдуть на `/api/city/assets/proxy/...`?
- Який статус відповіді (200/404/500)?
## Додавання нових компонентів
При додаванні нового компонента, який відображає assets:
1. **Імпортуйте** `normalizeAssetUrl`:
```typescript
import { normalizeAssetUrl } from '@/lib/utils/assetUrl';
```
2. **Використовуйте** для всіх asset URLs:
```typescript
```
3. **НЕ використовуйте** прямі URLs з БД без нормалізації.
## Міграція зі старих URL
Якщо в БД є старі формати URL:
- `/static/uploads/logo.png` → автоматично конвертується в `/api/static/uploads/logo.png`
- `/assets/logos/logo.png` → залишається як є
- `https://assets.daarion.space/...` → конвертується в `/api/city/assets/proxy/...`
`normalizeAssetUrl` обробляє всі ці випадки автоматично.