Files
microdao-daarion/docs/ASSETS_PROXY.md
Apple 1ca6a4f55a feat: Complete assets proxy implementation with documentation
- Add comprehensive documentation in docs/ASSETS_PROXY.md
- Add contract comments in normalizeAssetUrl and proxy_asset
- Verify all components use normalizeAssetUrl
- Verify ENV variables are correctly set
- Add troubleshooting guide
2025-12-02 08:36:55 -08:00

199 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Assets Proxy — Документація
## Огляд
DAARION використовує **MinIO** (S3-compatible object storage) для зберігання assets (логотипи, банери, аватарки). Для доступу до assets без налаштування DNS для `assets.daarion.space` використовується **Asset Proxy** через `city-service`.
## Архітектура
```
┌─────────────┐
│ 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';
// ✅ ПРАВИЛЬНО
<img src={normalizeAssetUrl(logo_url)!} alt="Logo" />
// ❌ НЕПРАВИЛЬНО
<img src={logo_url} alt="Logo" />
```
## Endpoint
### City Service
- **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=<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"
<img src={normalized} alt="Logo" />
```
## 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
<img src={normalizeAssetUrl(logo_url)!} alt="Logo" />
<div style={{ backgroundImage: `url(${normalizeAssetUrl(banner_url)})` }} />
```
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` обробляє всі ці випадки автоматично.