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
This commit is contained in:
198
docs/ASSETS_PROXY.md
Normal file
198
docs/ASSETS_PROXY.md
Normal file
@@ -0,0 +1,198 @@
|
||||
# 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` обробляє всі ці випадки автоматично.
|
||||
|
||||
Reference in New Issue
Block a user