ADR-007: Intégration complète S3 pour les rapports et photos
Date: 2026-02-01
Statut: Proposé
Décideurs: Équipe ObeeSmart
Contexte technique: ObeeSmart v5.1.0 → v6.0
Contexte
ObeeSmart dispose actuellement d'une intégration S3 partielle (v5.1.0) pour le stockage des photos. Cependant, cette intégration présente plusieurs lacunes qui impactent l'expérience utilisateur et la valeur métier des rapports :
État actuel (v5.1.0)
| Composant | État | Détails |
|---|---|---|
| PhotoService | ✅ Fonctionnel | Upload, miniatures, EXIF, URLs signées |
| Stockage photos S3 | ✅ Fonctionnel | Chemin: {entity_type}s/{user_id}/{entity_id}/{uuid}.ext |
| ReportStorageService | ⚠️ Partiel | Upload PDF vers S3, mais pas de gestion photos |
| Photos dans PDFs | ❌ Absent | Code préparé (drawPhotoGrid) mais jamais appelé |
| Preview PDF inline | ❌ Absent | Téléchargement direct uniquement |
| Gestion erreurs S3 | ⚠️ Insuffisant | Pas de retry, pas de fallback |
Problèmes identifiés
Valeur métier réduite : Les rapports PDF ne contiennent pas les photos des visites, traitements et récoltes, réduisant leur utilité documentaire et légale.
Ergonomie limitée :
- Pas de prévisualisation PDF avant téléchargement
- URLs signées expirent silencieusement (erreur 403)
- Pas de galerie photos intégrée aux rapports web
Robustesse insuffisante :
- Rapport reste en
status=generatingsi S3 échoue - Fichiers temporaires non nettoyés
- Pas de fallback local
- Rapport reste en
Fonctionnalités manquantes :
- Pas de statistiques d'utilisation S3
- Pas de nettoyage automatique des anciens rapports
- Pas d'export groupé avec photos
Décision
Objectif principal
Transformer le système de rapports en une solution documentaire complète où :
- Les rapports PDF incluent automatiquement les photos pertinentes de la période
- Les utilisateurs peuvent prévisualiser avant de télécharger
- Le stockage S3 est robuste avec retry et fallback
- L'expérience utilisateur est fluide et professionnelle
Architecture cible
┌─────────────────────────────────────────────────────────────────┐
│ GÉNÉRATION RAPPORT v6.0 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 1. COLLECTE DONNÉES │
│ ├── Ruches, Visites, Récoltes, Traitements, Alertes │
│ └── Photos (NEW) ← Photo.findAll({period, entity_types}) │
│ │
│ 2. PRÉPARATION PHOTOS │
│ ├── Sélection (max 20 photos pertinentes) │
│ ├── Téléchargement miniatures S3 → buffers │
│ └── Tri par date/entité │
│ │
│ 3. GÉNÉRATION PDF │
│ ├── Sections existantes (KPIs, tableaux, graphiques) │
│ └── Section "Galerie Photos" (NEW) │
│ ├── Grille 3 colonnes │
│ ├── Légendes (date, entité, caption) │
│ └── Pagination automatique │
│ │
│ 4. UPLOAD S3 + FALLBACK │
│ ├── Retry (3 tentatives, backoff exponentiel) │
│ ├── Fallback local si échec │
│ └── Mise à jour status Report │
│ │
│ 5. ACCÈS UTILISATEUR │
│ ├── Preview inline (PDF.js ou iframe) │
│ ├── Téléchargement direct │
│ └── Partage (token, expiration) │
│ │
└─────────────────────────────────────────────────────────────────┘
Composants modifiés
| Fichier | Modifications |
|---|---|
helpers/reports-export-premium.js |
Collecte photos, passage au Python |
helpers/generate_report_premium.py |
Section galerie photos avec ReportLab |
helpers/export-service.js |
Activation drawPhotoGrid(), récupération buffers S3 |
services/ReportStorageService.js |
Retry logic, fallback local, statistiques |
services/PhotoService.js |
Méthode getPhotosForReport() |
routes/reports.js |
Endpoint preview, stats stockage |
views/beekeeper/report-detail.pug |
Preview inline, amélioration UX |
views/beekeeper/reports.pug |
Indicateurs visuels, actions rapides |
Nouveaux composants
| Fichier | Rôle |
|---|---|
services/ReportPhotoService.js |
Orchestration photos pour rapports |
job/cleanup-old-reports.js |
Cron nettoyage S3 (rapports > 1 an) |
public/js/pdf-preview.js |
Viewer PDF inline (PDF.js) |
Alternatives considérées
Alternative 1 : Liens photos dans PDF (pas d'embed)
Description : Inclure des QR codes ou liens vers les photos S3 au lieu d'embarquer les images.
Avantages :
- PDF plus léger
- Pas de traitement images côté serveur
Inconvénients :
- ❌ Nécessite connexion internet pour voir les photos
- ❌ URLs signées expirent (rapport "cassé" après 1h)
- ❌ Moins professionnel pour documentation légale
Décision : Rejeté - Les rapports doivent être autonomes et consultables hors-ligne.
Alternative 2 : Génération PDF côté client (jsPDF)
Description : Générer le PDF dans le navigateur avec jsPDF.
Avantages :
- Moins de charge serveur
- Preview instantané
Inconvénients :
- ❌ Dépendant du navigateur/device
- ❌ Qualité variable
- ❌ Pas de stockage centralisé
- ❌ Impossible de partager via lien
Décision : Rejeté - Besoin de rapports standardisés et partageables.
Alternative 3 : Service externe de génération PDF
Description : Utiliser un service comme DocRaptor, PDFShift ou Anvil.
Avantages :
- Design avancé (CSS → PDF)
- Moins de code à maintenir
Inconvénients :
- ❌ Coût par génération
- ❌ Dépendance externe
- ❌ Données sensibles envoyées à un tiers
- ❌ Latence réseau
Décision : Rejeté - Préférence pour solution auto-hébergée.
Conséquences
Positives
Valeur documentaire accrue : Rapports complets avec preuves visuelles (visites, état des ruches, traitements).
Conformité réglementaire : Documentation photographique pour traçabilité sanitaire.
Expérience utilisateur améliorée :
- Preview avant téléchargement
- Galerie photos contextualisée
- Partage simplifié
Robustesse accrue :
- Retry automatique
- Fallback local
- Nettoyage programmé
Scalabilité : Architecture préparée pour augmentation du volume.
Négatives
Complexité accrue : Plus de code à maintenir (photos dans PDF, preview, retry).
Temps de génération : PDFs plus lourds (photos = 2-5 Mo vs 500 Ko).
Stockage S3 : Augmentation espace utilisé (~3× avec photos).
Dépendances : PDF.js pour preview (lib externe côté client).
Risques et mitigations
| Risque | Probabilité | Impact | Mitigation |
|---|---|---|---|
| PDFs trop volumineux | Moyenne | Moyen | Limiter à 20 photos, utiliser miniatures 600px |
| Timeout génération | Faible | Élevé | Génération async, notification quand prêt |
| S3 indisponible | Faible | Élevé | Fallback local, retry 3×, alerting |
| Migration données existantes | Moyenne | Moyen | Script migration progressif |
Plan d'implémentation
Voir document détaillé : IMPLEMENTATION-s3-reports.md
Phases
| Phase | Durée estimée | Livrable |
|---|---|---|
| Phase 1 : Photos dans PDFs | 3-4 jours | PDFs avec galerie photos |
| Phase 2 : Robustesse S3 | 2 jours | Retry, fallback, logs |
| Phase 3 : Preview PDF | 2 jours | Viewer inline |
| Phase 4 : Ergonomie | 2 jours | UX améliorée, stats |
| Phase 5 : Maintenance | 1 jour | Cron nettoyage, monitoring |
Total estimé : 10-12 jours de développement
Métriques de succès
| Métrique | Objectif | Mesure |
|---|---|---|
| Photos dans rapports | 100% des rapports avec photos | Comptage photos_count > 0 |
| Taux d'échec S3 | < 1% | Logs erreurs / total uploads |
| Temps génération PDF | < 30s (avec photos) | Monitoring durée |
| Adoption preview | > 50% des consultations | Analytics clics preview vs download |
| Satisfaction utilisateur | Retours positifs | Feedback qualitatif |
Références
Historique
| Date | Version | Auteur | Changements |
|---|---|---|---|
| 2026-02-01 | 1.0 | Claude | Création initiale |