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

6.1 KiB
Raw Blame History

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 з БД

https://assets.daarion.space/daarion-assets/microdao/logo/2025/12/02/abc123.png

Вихідний URL для фронта (після normalizeAssetUrl)

/api/city/assets/proxy/microdao/logo/2025/12/02/abc123.png

Шлях до MinIO (всередині proxy)

daarion-assets/microdao/logo/2025/12/02/abc123.png

Важливо: normalizeAssetUrl відрізає daarion-assets/ з URL, тому proxy отримує шлях без префіксу бакету. Proxy додає ASSETS_BUCKET автоматично.

Використання в компонентах

ЗАВЖДИ використовуйте normalizeAssetUrl для всіх asset URLs:

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

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

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 на фронті

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:

    docker exec daarion-minio mc ls minio/daarion-assets/microdao/logo/2025/12/02/
    
  2. Перевірте чи правильний шлях передається в proxy:

    curl -I "https://daarion.space/api/city/assets/proxy/microdao/logo/2025/12/02/abc123.png"
    
  3. Перевірте логи city-service:

    docker logs daarion-city-service | grep "assets/proxy"
    

500 Internal Server Error

  1. Перевірте ENV змінні в docker-compose:

    docker exec daarion-city-service env | grep MINIO
    
  2. Перевірте чи MinIO доступний:

    docker exec daarion-city-service curl -I http://minio:9000/minio/health/live
    

Assets не відображаються на фронті

  1. Перевірте чи компонент використовує normalizeAssetUrl:

    // ✅ ПРАВИЛЬНО
    src={normalizeAssetUrl(url)}
    
    // ❌ НЕПРАВИЛЬНО
    src={url}
    
  2. Перевірте в DevTools Network tab:

    • Чи запити йдуть на /api/city/assets/proxy/...?
    • Який статус відповіді (200/404/500)?

Додавання нових компонентів

При додаванні нового компонента, який відображає assets:

  1. Імпортуйте normalizeAssetUrl:

    import { normalizeAssetUrl } from '@/lib/utils/assetUrl';
    
  2. Використовуйте для всіх asset URLs:

    <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 обробляє всі ці випадки автоматично.