# Architecture Technique — Imago Hub v2.0.0 Ce document détaille l'architecture logicielle, les flux de données et les choix technologiques. --- ## 1. Vue d'Ensemble | Composant | Technologie | Rôle | |---|---|---| | API Backend | FastAPI (Python 3.12+) + Uvicorn | Endpoints REST async, validation Pydantic | | Frontend Admin | React + TypeScript + Vite + Nginx | Interface d'administration | | Worker Queue | ARQ (Async Redis Queue) | Traitement asynchrone du pipeline AI | | Broker/Cache | Redis 7 | Jobs ARQ, Pub/Sub WebSocket, Rate Limiting, DLQ | | Base de données | PostgreSQL 16 + SQLAlchemy async | Données relationnelles, multi-tenant | | Stockage objets | MinIO (S3-compatible) ou stockage local | Fichiers binaires (images, thumbnails) | | Observabilité | structlog + Prometheus + Grafana | Logs structurés, métriques, dashboards | --- ## 2. Flux de Traitement (Pipeline AI) ``` Client → POST /api/v1/images/upload → Validation MIME + quota → Sauvegarde fichier (S3 ou local) + thumbnail → Insert BDD (status: PENDING) → Enqueue job ARQ: process_image_task(image_id, client_id) → Réponse 201 au client Worker ARQ (processus séparé): → status: PROCESSING → Étape 1: EXIF (piexif) → métadonnées appareil, GPS → Étape 2: OCR (Tesseract) → texte + fallback AI OCR → Étape 3: Vision AI (Gemini/OpenRouter) → description, tags → status: DONE (ou ERROR si échec après N tentatives) → Publication Redis Pub/Sub → WebSocket clients ``` **Résilience :** - Chaque étape est indépendante — un échec partiel n'arrête pas le pipeline - Circuit breaker AI : timeout configurable + retry exponentiel - Dead Letter Queue : jobs échoués après `PIPELINE_MAX_RETRIES` → Redis DLQ inspectable --- ## 3. Modèle de Données ### Table `api_clients` - `id` (UUID), `name`, `api_key_hash` (SHA-256 + pepper) - `scopes` (JSON), `plan` (free/standard/premium) - `storage_used_bytes`, `quota_storage_mb`, `quota_images` - `is_active` (soft delete) ### Table `images` - `id`, `uuid`, `client_id` → isolation multi-tenant - `original_name`, `file_path`, `thumbnail_path`, `mime_type`, `file_size` - `processing_status` (pending/processing/done/error) - **EXIF** : `exif_make`, `exif_model`, `exif_gps_lat/lon`, `exif_taken_at`, etc. - **OCR** : `ocr_text`, `ocr_language`, `ocr_confidence` - **AI** : `ai_description`, `ai_tags` (JSON), `ai_model_used`, `ai_prompt_tokens`, `ai_output_tokens` - Indexes composites : `(client_id, uploaded_at)`, `(client_id, processing_status)` --- ## 4. Sécurité | Couche | Mécanisme | |---|---| | Authentification | API Key via `Authorization: Bearer ` ou `X-API-Key` | | Hashage | SHA-256 + pepper (SECRET_KEY) — comparaison timing-safe | | Master Key | `ADMIN_API_KEY` configurable, bypass BDD avec tous les droits | | Autorisation | Scopes obligatoires par endpoint (`require_scope("images:write")`) | | Validation | Scopes rejetés si invalides (`VALID_SCOPES`) | | Rate Limiting | slowapi par client_id + plan, stockage Redis optionnel | | CORS | Configurable, rejette `["*"]` si `allow_credentials=True` | | URLs signées | HMAC via itsdangerous (local) ou S3 presigned URLs | --- ## 5. Observabilité - **structlog** : JSON en production, console colorée en dev. Trace ID (`X-Request-ID`) injecté. - **Prometheus** : `/metrics` — counters (uploads, tokens, erreurs), histograms (durée pipeline), gauges (stockage, WebSocket) - **Health checks** : `/health` (simple), `/health/detailed` (BDD, Redis, ARQ, MinIO, OCR, AI, worker) - **Grafana** : dashboard 10 panneaux fourni (`docs/grafana-dashboard.json`) --- ## 6. WebSocket — Temps Réel - `/ws/pipeline/{image_id}?token=API_KEY` — événements live du pipeline - `/ws/admin/monitor?token=ADMIN_KEY` — monitoring global admin - Buffer Redis 60s (10 derniers événements) pour reconnexion - Pub/Sub Redis : `pipeline:{image_id}` et `pipeline:admin` --- ## 7. Infrastructure & Déploiement ### Développement local ```bash docker compose up -d # PostgreSQL + Redis + MinIO + API + Worker ``` ### Production (serveur lab) L'image est poussée vers le registry local : ``` docker-registry.dev.home:5000/imago-backend:latest ``` Déploiement : `docker-compose.production.yml` + `.env.production` ### Build & Push ```powershell cd docker .\build-img.ps1 # Build via WSL Debian .\deploy-img.ps1 # Push vers registry (semver auto) ```