Aller au contenu

Changelog Urbafix

Toutes les modifications notables de ce projet seront documentées dans ce fichier.

[2.0.0] - 04 Janvier 2026

🏗️ Refactorisation Architecturale Majeure - Stateless-Ready

Résumé Exécutif

Refactorisation complète de l'architecture pour préparer le scaling horizontal, la haute disponibilité et la conformité ANSSI, tout en préservant 100% de compatibilité avec le déploiement actuel.

Principe directeur : Activation opt-in via variables d'environnement - l'application fonctionne exactement comme avant par défaut.

PHASE 1-4 : Fondations + Cache

Configuration Centralisée
  • Nouveau : /src/Config.php (300+ lignes) - Singleton avec validation typage
  • 40+ nouvelles variables .env.example pour tous les subsystèmes
  • Valeurs hardcodées supprimées de 6 fichiers (GPS 100m, pHash 12, export 10000...)
  • Fichiers modifiés : IncidentGrouper.php, Database.php, submit_incident.php, ExportQueryBuilder.php
Session Abstraction
  • Nouveau : SessionInterface, FileSessionHandler, RedisSessionHandler, SessionFactory
  • ANSSI-compliant : HttpOnly, Secure, SameSite=Strict
  • Session regeneration après login (anti-CSRF)
  • Fichiers modifiés : /src/Auth.php refactorisé pour injection SessionInterface
Storage Abstraction
  • Nouveau : StorageInterface, LocalStorage, S3Storage, StorageFactory
  • Méthodes : put(), get(), exists(), delete(), url(), size()
  • Permissions ANSSI : 0755 dirs, 0644 files (exit 0777)
  • Fichiers modifiés : submit_incident.php utilise StorageFactory
Cache Abstraction
  • Nouveau : CacheInterface, NullCache, RedisCache, CacheFactory
  • Pattern remember : cache->remember($key, $ttl, callback)
  • Fix N+1 queries : get_types.php refactorisé avec LEFT JOIN
  • TTL configurables : Types 3600s, Mairies 3600s, Services 1800s

PHASE 5 : Services Métier

  • Nouveau : TypeService, MairieService, IncidentService, UploadService
  • Séparation HTTP ↔ Business : Endpoints allégés, services réutilisables
  • Validation GPS Haversine : UploadService pour vidéos
  • Caching intégré : TypeService utilise cache->remember()

PHASE 6 : Queue Asynchrone + RGPD

Queue Abstraction
  • Nouveau : QueueInterface, SyncQueue, RedisQueue, QueueFactory
  • SyncQueue (default) : Exécution immédiate (comportement actuel préservé)
  • RedisQueue (stub) : LPUSH/RPOP pour workers futurs
Jobs Asynchrones
  • Nouveau : BlurFacesJob - Floutage visages RGPD automatique
  • Nouveau : CalculatePhashJob - Calcul pHash async
  • Nouveau : SendEmailNotificationJob - Emails notifications async
  • Intégration : submit_incident.php dispatch jobs via QueueFactory
Face Blurring RGPD
  • Nouveau : FaceBlurringService (240+ lignes)
  • Détection : Extension facedetect PHP ou Haar Cascade XML
  • Algorithme : Pixellisation 10x + Gaussian blur 3 passes
  • Marge : 20% autour visage détecté
  • Migration BDD : migration_face_blurring.sql
  • Colonnes : face_blurred (0/1), faces_count (int)
  • Index : idx_face_blurred
  • Configuration : FACE_BLURRING_ENABLED=true dans .env

PHASE 7 : Sécurité Multi-Tenant

Audit Complet
  • Nouveau : /docs/SECURITY_AUDIT_MULTI_TENANT.md (15 KB)
  • 10 endpoints API audités : Isolation mairie_id vérifiée
  • Vulnérabilité critique corrigée : get_all_unresolved_incidents.php
  • Avant : Aucune auth, retournait incidents de TOUTES les mairies
  • Après : Auth obligatoire + filtrage strict par code_postal
  • Tests recommandés : Cross-tenant access, export API keys
Middleware (Recommandation)
  • Proposition : MultiTenantMiddleware::enforce($requiredMairieId, $userMairieId)
  • Logging : Tentatives accès non autorisé
  • Tests PHPUnit : Isolation multi-tenant automatisée

PHASE 8 : Docker Stateless-Ready

Service Redis
  • Ajouté : docker-compose.yml avec service Redis 7 Alpine
  • Profil optionnel : --profile redis pour activation
  • Configuration :
  • AOF persistence (appendonly yes)
  • Maxmemory 256MB avec LRU eviction
  • Password obligatoire (REDIS_PASSWORD)
  • DB isolation : 0=sessions, 1=cache, 2=queue
Health Endpoint
  • Nouveau : /public/health.php
  • Checks : Database, Redis, Storage, Config, PHP extensions
  • Réponse : HTTP 200 OK / 503 Unhealthy
  • JSON : Status + détails checks + métriques système
  • Intégration : Docker healthcheck, load balancer checks
Docker Compose
  • Healthcheck web : curl http://localhost/health.php
  • Volume redis_data : Persistance AOF
  • Start period : 40s pour initialisation

PHASE 9 : Documentation Technique

Nouveaux Documents (7 fichiers, ~115 KB)
  • ARCHITECTURE.md (20 KB) : Architecture v2.0 complète
  • Vue d'ensemble, couches, modèle données, flux
  • Abstractions (Session, Storage, Cache, Queue)
  • Sécurité multi-tenant, RGPD
  • Diagrammes séquence, ADR
  • CONFIGURATION.md (16 KB) : 40+ variables .env
  • Par catégorie : DB, Redis, sessions, cache, storage, queue
  • Exemples par environnement (dev/staging/prod)
  • Génération secrets, validation config
  • SCALABILITY.md (21 KB) : 6 scénarios scaling
  • Single instance → Multi-régions
  • Comparaisons coûts/capacité
  • Migrations progressives
  • Métriques monitoring
  • DEPLOYMENT.md (18 KB) : Procédures production
  • Installation serveur, reverse proxy (au choix)
  • SSL Let's Encrypt, backups automatiques
  • Monitoring, troubleshooting
  • DOCKER_STATELESS.md (15 KB) : Configuration Docker
  • Services, volumes, health checks
  • Load balancer (au choix)
  • Horizontal scaling, blue-green deployment
  • SECURITY_AUDIT_MULTI_TENANT.md (15 KB) : Audit sécurité
  • Analyse 10 endpoints API
  • Vulnérabilité corrigée, tests sécurité
  • Conformité ANSSI
  • FACE_BLURRING.md (5 KB) : Face blurring RGPD
  • Détection, algorithme, installation
  • Monitoring, troubleshooting
Documentation Web
  • Nouveau : /public/documentation/architecture-v2.html
  • Page d'accueil Architecture v2.0
  • Grille 8 cartes documentations
  • Statistiques : 9 phases, 42 fichiers, 100% compatible
  • Modifié : /public/documentation/index.html
  • Section "🏗️ ARCHITECTURE v2.0" ajoutée
  • Version header : v1.5.0 → v2.0
  • Badge "🚀 Stateless-Ready"

Statistiques Refactorisation

Fichiers créés : 42 - 9 interfaces - 16 implémentations - 4 services métier - 3 jobs async - 1 health endpoint - 1 migration SQL - 7 documents techniques - 1 page documentation web

Fichiers modifiés : 12 - Config centralisée partout - Endpoints API sécurisés - docker-compose.yml stateless-ready - Documentation index

Lignes de code : ~3500+ lignes Documentation : ~2500+ lignes

État de l'Application

Avant v2.0 : - ❌ Monolithique single-instance - ❌ Sessions fichiers PHP locaux - ❌ Uploads filesystem hardcodé - ❌ Logique métier entrelacée HTTP - ❌ Valeurs hardcodées - ❌ Pas de cache - ❌ Traitements synchrones - ❌ Permissions 0777 (non-ANSSI) - ❌ Endpoint exposant toutes mairies sans auth

Après v2.0 : - ✅ Stateless-ready (activation opt-in) - ✅ Sessions abstraites (file/redis) - ✅ Stockage abstrait (local/S3) - ✅ Services métier réutilisables - ✅ Config centralisée (40+ variables) - ✅ Cache optionnel (null/redis) - ✅ Queue optionnelle (sync/redis) - ✅ Permissions ANSSI (0755/0644) - ✅ Multi-tenant sécurisé (audit complet) - ✅ Face blurring RGPD automatique - ✅ Health endpoint production - ✅ Documentation exhaustive

Compatibilité : 100% backward compatible - Fonctionne exactement comme avant par défaut.

Migration

Étapes recommandées : 1. Appliquer migration SQL : migration_face_blurring.sql 2. Tester health endpoint : curl http://localhost:8080/health.php 3. Activer Redis (optionnel) : docker-compose --profile redis up -d 4. Configurer SMTP : Variables .env pour emails 5. Déploiement staging : Tester configuration Redis

Breaking Changes

Aucun - 100% backward compatible.


[1.5.0] - 03 Janvier 2026

Support des Vidéos (5 secondes max)

Capture et Upload de Vidéos

  • Nouveau module VideoCompressor.kt : Compression et validation des vidéos
  • Durée maximale : 5 secondes (troncature automatique si dépassement)
  • Taille maximale : 5 MB
  • Format : MP4 (conversion automatique via MediaMuxer)
  • Validation automatique (dimensions, durée, taille)
  • utils/VideoCompressor.kt (240 lignes)

Base de Données Étendue

  • PhotoEntity modifié pour supporter les vidéos :
  • Nouveau champ mediaType: MediaType (PHOTO ou VIDEO)
  • Nouveau champ durationMs: Long? (durée en millisecondes)
  • Nouveau champ photoData: String? (données Base64 pour upload)
  • Nouveau enum MediaType { PHOTO, VIDEO }
  • Version base de données : 3 → 4
  • PhotoEntity.kt:34-38

Interface Utilisateur Enrichie

  • ReportScreen amélioré :
  • 4 boutons : Photo (caméra), Galerie (photos), Vidéo 5s (caméra), Galerie ▶ (vidéos)
  • Aperçu des vidéos avec indicateurs visuels :
    • Bordure bleue (2dp) pour distinguer des photos
    • Icône ▶ centrée
    • Badge durée en bas à droite (ex: "3s")
  • Compteur séparé : "2 photo(s) • 1 vidéo(s)"
  • ReportScreen.kt:310-534

Traitement des Vidéos

  • ReportViewModel étendu :
  • Nouvelle méthode addVideo(uri: Uri) pour traitement vidéo
  • Validation avec VideoCompressor.getVideoInfo()
  • Troncature automatique si durée > 5 secondes
  • Conversion Base64 pour upload API (compatible infrastructure existante)
  • PhotoItem étendu : isVideo: Boolean, durationMs: Long?
  • ReportViewModel.kt:24-28, 331-405

Algorithme de Troncature

  • trimVideoTo5Seconds() : Extraction des 5 premières secondes
  • Utilise MediaExtractor pour lire la vidéo source
  • Utilise MediaMuxer pour écrire la vidéo tronquée
  • Copie toutes les pistes (vidéo + audio)
  • Arrêt à 5000ms (5 secondes exactement)
  • VideoCompressor.kt:119-188

API et Backend

  • Nouveau format JSON pour submit_incident.php :
  • Méthode submitIncidentJson() avec @Body au lieu de multipart
  • Champ videos: List<VideoData>? dans SubmitIncidentRequest
  • Structure VideoData : {video: "data:video/mp4;base64,...", latitude, longitude}
  • Coordonnées GPS incluises pour chaque vidéo
  • UrbafixApi.kt:67-69, SubmitIncidentRequest.kt:5-26

  • Nouvelle table videos_incident (serveur) :

  • Colonnes : id, incident_id, type, filename, filepath, description
  • Champs supplémentaires : duration, filesize, mime_type, latitude, longitude, encrypted
  • Foreign key vers incidents (CASCADE DELETE)
  • Stockage : /uploads/videos/ (fichiers MP4)
  • Indexes : incident_id, type, encrypted, GPS (latitude, longitude)
  • database/migration_videos.sql

Backend PHP - Upload Vidéos avec Validation GPS

  • API submit_incident.php étendue (lignes 175-245) :
  • Traitement tableau videos depuis JSON
  • Décodage Base64 : data:video/{type};base64,...
  • Extraction GPS depuis VideoData.latitude/longitude
  • Validation GPS automatique :
    • Comparaison distance vidéo ↔ incident via IncidentGrouper::calculateDistance()
    • Seuil alerte : 100 mètres
    • Warning logged si distance > 100m : ALERTE GPS: Vidéo N pour incident X - distance: Ym
  • Sauvegarde dans /uploads/videos/ : format {incident_id}_video_{timestamp}_{index}.{ext}
  • Insertion BDD avec métadonnées complètes (filesize, mime_type, GPS)
  • Réponse JSON enrichie : videos_uploaded, gps_warnings[]

Backoffice Mairies - Lecteur Vidéo

  • incident_detail.php modifié (/public/) :
  • Récupération vidéos déclarant + mairie (lignes 473-483)
  • Validation GPS vidéos (lignes 506-519) :
    • Comparaison avec incident (tolérance 0.0001° ≈ 11m)
    • Flag gps_differs si écart détecté
  • Section "Vidéos du signalement" (lignes 1248-1317) :
    • Lecteur HTML5 <video controls preload="metadata">
    • Grid responsive : minmax(400px, 1fr)
    • Affichage métadonnées : nom, date, taille MB
    • Alerte GPS si coordonnées différentes :
    • Badge orange ⚠️ "Localisation différente du signalement"
    • Coordonnées exactes (6 décimales)
    • Liens Google Maps + OpenStreetMap
    • Badge vert ✓ si localisation conforme
  • Section "Vidéos ajoutées" mairie (lignes 981-1013) :

    • Même lecteur dans réponse mairie
    • Bordure verte (réponse municipale)
    • GPS affiché si disponible
  • incident_detail.php backend (/public/backend/) également mis à jour

  • Upload Repository :

  • sendIncidentToApi() modifié pour séparer photos et vidéos
  • Photos → tableau photos (Base64 avec prefix "data:image/jpeg;base64,...")
  • Vidéos → tableau videos (objets VideoData avec GPS)
  • Validation prefix Base64 automatique
  • IncidentRepository.kt:406-502

  • Synchronisation Worker :

  • SyncIncidentsWorker utilise maintenant le repository
  • Support automatique photos + vidéos
  • Récupération via getPhotosByIncidentIdAndType()
  • workers/SyncIncidentsWorker.kt:61-88

Avertissement RGPD pour les Vidéos

  • Dialogue d'avertissement obligatoire avant capture/sélection vidéo
  • Icône ⚠️ orange (48dp)
  • Titre : "⚠️ Important - Protection des données"
  • Message explicatif : Floutage automatique non disponible pour vidéos
  • Recommandations RGPD :
    • Évitez de filmer des personnes identifiables
    • Concentrez-vous sur le problème à signaler
    • Respectez la vie privée des passants
  • Boutons : "Annuler" ou "J'ai compris, continuer"
  • Engagement utilisateur : Confirmation explicite requise
  • ReportScreen.kt:691-782

Limitations Connues

⚠️ Floutage des visages non implémenté pour les vidéos : - Complexité élevée (traitement frame par frame requis) - Solution future possible : ML Kit Face Detection sur chaque frame - Mitigation actuelle : Dialogue d'avertissement RGPD obligatoire avant capture

Fichiers Modifiés

  • utils/VideoCompressor.kt (nouveau, 240 lignes)
  • data/local/entities/PhotoEntity.kt - Ajout mediaType, durationMs
  • data/local/AppDatabase.kt - Version 4
  • data/local/Converters.kt - TypeConverters pour MediaType et PhotoType
  • ui/screens/report/ReportScreen.kt - Interface capture vidéo
  • ui/screens/report/ReportViewModel.kt - Traitement vidéo

Dépendances

  • Utilise MediaExtractor, MediaMuxer, MediaMetadataRetriever (Android SDK)
  • Aucune dépendance externe ajoutée

Tests

  • ✅ Compilation réussie (BUILD SUCCESSFUL)
  • ⏳ Tests sur appareil physique requis
  • ⏳ Validation de l'upload vers l'API backend

[1.4.0] - 03 Janvier 2026

Filtrage Géographique Dynamique

Filtrage par Rayon de la Carte

  • Rayon de 10 km : Les incidents affichés sont filtrés selon la position actuelle de la carte
  • Utilise l'algorithme Haversine pour calculer la distance entre le centre de la carte et chaque incident
  • Constante FILTER_RADIUS_METERS = 10000.0 (10 km)
  • Filtre appliqué via Flow.combine() pour réactivité
  • HomeViewModel.kt:42-74

Synchronisation Basée sur la Position GPS

  • Code postal dynamique : La synchronisation récupère le code postal basé sur la position GPS actuelle
  • Utilise l'API geo.gouv.fr pour géolocalisation inverse
  • Récupère automatiquement : nom commune, code INSEE, code postal
  • Fallback sur "06500" (Menton) si échec de géolocalisation
  • HomeViewModel.kt:116-144

Nouvelle Méthode Repository

  • getCommuneData() : Récupération complète des données d'une commune
  • Paramètres : latitude, longitude
  • Retourne : CommuneData(nom, codeInsee, codePostal)
  • Utilise GeoGouvApi pour appel à geo.api.gouv.fr
  • IncidentRepository.kt:244-276

Comportement

Avant v1.4.0 : - Liste affichait TOUS les incidents de la base de données (Menton hardcodé) - Carte centrée sur Nice mais liste montrait Menton - Code postal hardcodé à "06500"

Après v1.4.0 : - Liste affiche UNIQUEMENT les incidents à moins de 10 km du centre de la carte - Synchronisation récupère les incidents pour le code postal détecté via GPS - Code postal dynamique basé sur la position actuelle

Exemple :

Position GPS : Nice (43.7102, 7.2620)
  ↓
geo.gouv.fr → Commune: Nice, CP: 06000, INSEE: 06088
  ↓
API sync → GET /api/get_incidents.php?code_postal=06000
  ↓
Filtrage 10km → Affiche uniquement incidents de Nice

Fichiers Modifiés

  • ui/screens/home/HomeViewModel.kt - Filtrage géographique + sync dynamique
  • data/repository/IncidentRepository.kt - Nouvelle méthode getCommuneData()

Dépendances

  • Utilise GeoGouvApi existant (geo.api.gouv.fr)
  • Aucune nouvelle dépendance

Conformité

  • ✅ Pas de hardcoding de code postal
  • ✅ Détection automatique de la commune
  • ✅ Filtrage géographique précis (Haversine)
  • ✅ Synchronisation contextuelle (position utilisateur)

[1.3.0] - 03 Janvier 2026

Refonte de l'Écran de Détail d'Incident

Nouvelle Mise en Page

  • Layout ⅓ + ⅔ : Écran divisé en deux parties fixes
  • ⅓ supérieur : Carte OSM plein écran avec marqueur
  • ⅔ inférieur : Bloc de contenu scrollable avec fond opaque
  • Aucun chevauchement entre la carte et le contenu
  • IncidentDetailScreen.kt:78-170

Animation de Zoom

  • Effet de zoom progressif lors de l'ouverture du détail
  • Zoom initial : 12 (vue éloignée)
  • Zoom final : 17 (vue rapprochée sur l'incident)
  • Durée : 1200ms avec easing FastOutSlowInEasing
  • Recentrage automatique sur le marqueur pendant l'animation
  • IncidentDetailScreen.kt:180-250

Galerie Photos Améliorée

  • Miniatures réduites : 100dp (au lieu de 150dp)
  • Zoom cliquable : Dialog plein écran avec gestes
  • Pinch-to-zoom : de 1x à 5x
  • Pan pour déplacer l'image zoomée
  • Fond noir avec bouton fermer
  • PhotoZoomDialog : IncidentDetailScreen.kt:576-648
  • Cache optimisé : Clés de cache uniques par photo
  • memoryCacheKey("photo_${photo.id}")
  • diskCacheKey("photo_${photo.id}_${photoUrl.hashCode()}")
  • IncidentDetailScreen.kt:478-480

Corrections UX

  • Galerie conditionnelle : N'apparaît que si des photos existent
  • Condition if (allPhotos.isNotEmpty())
  • IncidentDetailScreen.kt:142-149
  • Tous les incidents affichés en fullscreen : Suppression de IncidentDetailSheet
  • Incidents individuels ET groupes utilisent IncidentDetailScreen
  • UX cohérente pour tous les cas
  • HomeScreen.kt:90-121

Retour à l'Accueil Amélioré

  • Dézoomer au retour : La carte de l'accueil dézoome et recentre
  • Stockage de la position GPS initiale dans userHomePosition
  • Restauration du zoom 13f et du centre GPS au retour
  • HomeViewModel.kt:29,73-78,163-167,215-219

Fixes Techniques

  • ViewModel avec clé unique : Résout le bug des photos manquantes
  • key = "incident_detail_${id}" pour éviter recréation
  • HomeScreen.kt:94
  • Surface avec fond opaque : Empêche le texte de se superposer à la carte
  • color = MaterialTheme.colorScheme.background
  • shadowElevation = 8.dp
  • IncidentDetailScreen.kt:95-101

Fichiers Modifiés

  • ui/screens/home/IncidentDetailScreen.kt - Refonte complète du layout et animations
  • ui/screens/home/HomeScreen.kt - Suppression IncidentDetailSheet, ajout clé ViewModel
  • ui/screens/home/HomeViewModel.kt - Gestion position GPS initiale et retour

Dépendances

  • Ajout imports animations : animateFloatAsState, tween, FastOutSlowInEasing
  • Ajout imports gestes : detectTransformGestures
  • IncidentDetailScreen.kt:19-21

[1.2.0] - 01 Janvier 2026

Ajouts

Floutage Automatique des Visages (RGPD)

  • FaceBlurrer.kt : Nouveau module de détection et anonymisation des visages
  • Détection on-device avec ML Kit Face Detection (v16.1.6)
  • 100% on-device : aucune donnée envoyée sur le réseau
  • RGPD : obligatoire, automatique, non désactivable
  • Deux méthodes d'anonymisation :
    • Flou gaussien : Stack Blur optimisé (rayon 25px, marge 30%)
    • Pixelisation : Alternative rapide (blocs de 20px)
  • Gestion mémoire optimisée (bitmap recycling)
  • Logs détaillés pour debug
  • FaceBlurrer.kt (430 lignes)

Pipeline de Traitement Photo Sécurisé

  • ImageCompressor.kt : Intégration du floutage dans la compression
  • Ordre de traitement :
    1. Chargement image
    2. Correction orientation EXIF
    3. Redimensionnement (max 1024px)
    4. Floutage visages (étape obligatoire)
    5. Compression JPEG 85%
    6. Encodage Base64
  • Fonction convertie en suspend fun pour traitement asynchrone
  • Rejet de l'image si échec du floutage (sécurité RGPD)
  • ImageCompressor.kt:45-115

Modifications

Configuration ML Kit

  • Détecteur configuré en mode PERFORMANCE_MODE_ACCURATE
  • Détection de visages ≥10% de la taille de l'image
  • Pas de landmarks ni classification (économie CPU)
  • Tracking activé pour futures évolutions (vidéo)

Algorithme Stack Blur

  • Alternative rapide au Gaussian Blur (complexité O(n) vs O(n²))
  • Optimisé pour appareils mobiles
  • Passes horizontale et verticale séparées
  • Qualité visuelle proche du Gaussian Blur

Dépendances Ajoutées

  • com.google.mlkit:face-detection:16.1.6 - Détection visages on-device
  • org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.7.3 - Extension coroutines pour Google Play Services

Fichiers Modifiés

  • app/src/main/java/com/example/monquartierkotlin/utils/ImageCompressor.kt
  • app/build.gradle.kts

Nouveaux Fichiers

  • app/src/main/java/com/example/monquartierkotlin/utils/FaceBlurrer.kt (430 lignes)

Conformité RGPD

  • ✅ Traitement 100% on-device (pas d'envoi réseau)
  • ✅ Anonymisation automatique et obligatoire
  • ✅ Pas d'option de désactivation
  • ✅ Image originale jamais sauvegardée après traitement
  • ✅ Floutage appliqué AVANT envoi au serveur
  • ✅ Compatible Android 8+ (API 26+)

[1.1.1] - 01 Janvier 2026

Corrections de Bugs

Synchronisation des Photos

  • Fix : Les photos des incidents sont maintenant synchronisées depuis l'API
  • Ajout de la synchronisation des photos dans syncIncidentsFromApi()
  • Déduplication automatique des photos en double (.distinct())
  • Nettoyage systématique avant insertion (photoDao.deleteByIncidentId())
  • IncidentRepository.kt:156-180

Base de Données

  • Fix : Correction du nom de table photos → photos_incident
  • Alignement avec le schéma serveur
  • PhotoEntity.kt:9
  • PhotoDao.kt (toutes les requêtes mises à jour)
  • Version de la base de données : 2 → 3 (AppDatabase.kt:20)

Vue Détaillée - Mes Signalements

  • Fix : Utilisation de la même vue détaillée que l'écran d'accueil
  • Remplacement de IncidentDetailSheet par IncidentDetailScreen
  • Affichage de la carte OSM intégrée
  • Galerie photos horizontale
  • MyReportsScreen.kt:260-290

Améliorations

Synchronisation

  • Les photos sont maintenant synchronisées pour tous les incidents (pas seulement les nouveaux)
  • Gestion robuste des doublons via déduplication
  • Logs détaillés pour le debug (IncidentRepository.kt, IncidentDetailViewModel.kt)

Fichiers Modifiés

  • app/src/main/java/com/example/monquartierkotlin/data/local/entities/PhotoEntity.kt
  • app/src/main/java/com/example/monquartierkotlin/data/local/dao/PhotoDao.kt
  • app/src/main/java/com/example/monquartierkotlin/data/local/AppDatabase.kt
  • app/src/main/java/com/example/monquartierkotlin/data/repository/IncidentRepository.kt
  • app/src/main/java/com/example/monquartierkotlin/ui/screens/myreports/MyReportsScreen.kt

[1.1.0] - 31 Décembre 2025

Ajouts

Vue Détaillée Complète des Incidents

  • IncidentDetailScreen : Nouvel écran plein écran remplaçant le ModalBottomSheet
  • Carte OSM intégrée (200dp) centrée sur l'incident (zoom 16)
  • Badge "⭐ Incident principal" avec compteur (affiché uniquement pour les groupes)
  • Section détails avec icônes : type, description, adresse, date, statut
  • Galerie photos horizontale scrollable (LazyRow)
    • Affiche TOUTES les photos de TOUS les incidents du groupe
    • Photos 150x150dp, coins arrondis 12dp, bordure
    • Chargement asynchrone avec Coil
    • Titre avec compteur : "Photos (5)"
    • Sous-titre conditionnel : "• De tous les incidents"
  • Liste des incidents secondaires (affichée uniquement pour les groupes)

    • Triés par date décroissante
    • Header avec couleur du type + date relative
    • Description limitée à 3 lignes (ellipsis)
    • Séparateurs visuels (Divider)
  • IncidentDetailViewModel : Chargement et combinaison des photos

  • Utilise Flow.combine() pour fusionner les photos de tous les incidents
  • StateFlow réactif pour mise à jour automatique de l'UI
  • Factory pattern pour injection de dépendances

Formatage des Dates

  • Dates courtes : Format "28 déc. à 14:30" (SimpleDateFormat avec Locale.FRENCH)
  • Dates relatives :
  • Moins d'1h : "il y a Xmin"
  • Moins de 24h : "il y a Xh"
  • 1 jour : "il y a 1 jour"
  • Plus : "il y a X jours"

Partage de l'Application

  • Nouvelle section dans ProfileScreen : "Partager l'application"
  • Card avec icône Share et couleur tertiaryContainer
  • Bouton "Partager via SMS, WhatsApp..."
  • Intent Android ACTION_SEND (type: text/plain)
  • Compatible avec toutes les apps de partage (SMS, WhatsApp, Email, Telegram, Messenger, etc.)

  • Message de partage personnalisé :

    🏘️ Rejoins-moi sur UrbaFix !
    
    UrbaFix permet de signaler facilement les problèmes dans ton quartier
    (nids-de-poule, dépôts sauvages, éclairage défaillant, etc.).
    
    📱 Télécharge l'application ici :
    https://urbafix.fr/download
    
    Ensemble, améliorons notre cadre de vie !
    

Modifications

HomeScreen

  • Remplacement du ModalBottomSheet par Dialog plein écran
  • DialogProperties avec usePlatformDefaultWidth = false
  • Passage du repository au HomeScreen pour créer IncidentDetailViewModel
  • Meilleure intégration avec le système de navigation Android

Affichage des Photos

  • Normalisation des URLs photos (préfixe https://urbafix.fr pour les URLs relatives)
  • Gestion des URLs serveur vs chemins locaux
  • Support des états de chargement et d'erreur

Améliorations

Performance

  • Chargement des photos uniquement quand nécessaire (Flow lazy)
  • Combinaison efficace des Flow avec combine()
  • Réutilisation des composables existants (StatusBadge)

UX/UI

  • Visibilité conditionnelle des sections selon le type (groupe vs individuel)
  • Effet empilé conservé pour les cartes de groupes
  • Transitions fluides entre liste et vue détaillée
  • Scrolling vertical dans la vue détaillée

Documentation

  • Mise à jour complète de README.md
  • Mise à jour de CLAUDE.md avec les nouvelles fonctionnalités
  • Ajout de schémas ASCII pour la vue détaillée
  • Changelog détaillé (ce fichier)

Fichiers Modifiés

  • app/src/main/java/com/example/monquartierkotlin/ui/screens/home/HomeScreen.kt
  • app/src/main/java/com/example/monquartierkotlin/ui/screens/profile/ProfileScreen.kt
  • app/src/main/java/com/example/monquartierkotlin/MainActivity.kt
  • README.md
  • CLAUDE.md

Nouveaux Fichiers

  • app/src/main/java/com/example/monquartierkotlin/ui/screens/home/IncidentDetailScreen.kt (530 lignes)
  • app/src/main/java/com/example/monquartierkotlin/ui/screens/home/IncidentDetailViewModel.kt (47 lignes)
  • CHANGELOG.md (ce fichier)

Corrections de Bugs

  • Fix : Utilisation de Divider au lieu de HorizontalDivider (compatibilité Material3)
  • Fix : Import manquant StatusBadge dans IncidentDetailScreen

Dépendances

Aucune nouvelle dépendance ajoutée. Utilisation des bibliothèques existantes : - Jetpack Compose Material3 - Coil (chargement images) - osmdroid (cartes) - Room + Flow (données réactives)


[1.0.0] - 30 Novembre 2024

Version Initiale

Fonctionnalités Principales

  • Écran d'accueil avec carte OpenStreetMap et liste des incidents
  • Groupement intelligent des incidents proches (< 10m, même type)
  • Profil utilisateur (anonyme par défaut)
  • Synchronisation offline-first avec Room Database
  • Chiffrement AES-256 de la base de données (SQLCipher)
  • Certificate pinning pour sécurité réseau
  • WorkManager pour synchronisation en arrière-plan

Architecture

  • MVVM (Model-View-ViewModel)
  • Jetpack Compose + Material Design 3
  • Room Database + SQLCipher
  • Retrofit + OkHttp
  • osmdroid (OpenStreetMap)

Sécurité

  • Conforme recommandations ANSSI
  • Chiffrement base de données locale (AES-256)
  • Certificate pinning (double : OkHttp + Network Security Config)
  • Logs conditionnels (production : aucun log)
  • HTTP en clair bloqué

Format du changelog : Keep a Changelog Versioning : Semantic Versioning