(doc) : ajout et modification de docs après arbitrage
This commit is contained in:
@@ -14,9 +14,9 @@ Cette analyse a identifié **15 incohérences** entre les décisions d'architect
|
||||
|
||||
| Sévérité | Nombre | % Total | Statut | Action Required |
|
||||
|----------|--------|---------|--------|-----------------|
|
||||
| 🔴 **CRITICAL** | 2 | 13% | ✅ **RÉSOLU** | ~~avant implémentation~~ |
|
||||
| 🟠 **HIGH** | 4 | 27% | ⏳ 3 restants (1 résolu) | Résolution Sprint 1-2 |
|
||||
| 🟡 **MODERATE** | 8 | 53% | ⏳ En cours | Résolution Sprint 3-5 |
|
||||
| 🔴 **CRITICAL** | 2 | 14% | ✅ **RÉSOLU** | ~~avant implémentation~~ |
|
||||
| 🟠 **HIGH** | 2 | 14% | ✅ **RÉSOLU** (2 résolus, 1 annulé) | ~~Résolution Sprint 1-2~~ |
|
||||
| 🟡 **MODERATE** | 6 | 43% | ⏳ 4 restants (3 résolus) | Résolution Sprint 3-5 |
|
||||
| 🟢 **LOW** | 1 | 7% | ⏳ En cours | À clarifier lors du développement |
|
||||
|
||||
### Impact par Domaine
|
||||
@@ -24,7 +24,7 @@ Cette analyse a identifié **15 incohérences** entre les décisions d'architect
|
||||
| Domaine | Nombre d'incohérences | Criticité maximale |
|
||||
|---------|----------------------|-------------------|
|
||||
| Streaming & Géolocalisation | 3 | 🔴 CRITICAL |
|
||||
| Données & Infrastructure | 3 | 🟠 HIGH |
|
||||
| Données & Infrastructure | 2 | 🟠 HIGH |
|
||||
| Authentification & Sécurité | 2 | 🟠 HIGH |
|
||||
| Tests & Qualité | 2 | 🟡 MODERATE |
|
||||
| Coûts & Déploiement | 3 | 🟡 MODERATE |
|
||||
@@ -134,106 +134,94 @@ Résultat: Audio démarre 200m APRÈS le point ❌
|
||||
|
||||
### #4 : ORM sqlc vs Types PostGIS
|
||||
|
||||
**Statut** : ✅ **RÉSOLU** (ADR-013 mis à jour)
|
||||
|
||||
| Élément | Détail |
|
||||
|---------|--------|
|
||||
| **ADR concernés** | ADR-013 (ORM, lignes 12, 33-40), ADR-005 (BDD, lignes 47-56) |
|
||||
| **ADR concerné** | ADR-013 (section "Gestion des Types PostGIS") |
|
||||
| **Règle métier** | N/A (problème technique pur) |
|
||||
| **Conflit** | sqlc génère types Go depuis SQL, mais PostGIS geography/geometry ne mappent pas proprement |
|
||||
| **Impact** | Risque de type `interface{}` ou `[]byte` pour géographie → perte de type safety revendiquée |
|
||||
|
||||
**Nature du problème** :
|
||||
**Solution implémentée** :
|
||||
|
||||
sqlc génère du code Go depuis SQL, mais les types PostGIS (`geography`, `geometry`) ne sont pas mappés proprement en Go. Résultat : types opaques (`[]byte`, `interface{}`) qui perdent la **type safety** revendiquée dans ADR-013.
|
||||
|
||||
**Solution retenue** :
|
||||
**Wrappers typés + fonctions de conversion PostGIS** :
|
||||
|
||||
1. **Wrapper types Go** avec méthodes `Scan/Value` pour conversion automatique
|
||||
2. **Utiliser les fonctions PostGIS de conversion** :
|
||||
- `ST_AsGeoJSON()` → struct GeoJSON typée
|
||||
- `ST_AsText()` → string WKT
|
||||
- `geography` brut → `pgtype.Point` (lib pgx)
|
||||
3. **Documenter le pattern** dans ADR-013 section "Gestion des Types PostGIS"
|
||||
2. **Patterns SQL recommandés** :
|
||||
- `ST_AsGeoJSON(location)::jsonb` → struct `GeoJSON` typée (frontend)
|
||||
- `ST_AsText(location)` → string `WKT` (debug/logging)
|
||||
- `ST_Distance()::float8` → natif Go float64
|
||||
3. **Index GIST** sur colonnes géographiques pour performance
|
||||
4. **Architecture conversion** :
|
||||
```
|
||||
SQL PostGIS → ST_AsGeoJSON() → json.RawMessage → GeoJSON (strongly-typed)
|
||||
```
|
||||
|
||||
**Action** :
|
||||
- [ ] Créer package `internal/geo` avec wrappers `GeoJSON`, `WKT`
|
||||
- [ ] Mettre à jour ADR-013 section "Types PostGIS"
|
||||
- [ ] Documenter pattern dans README backend
|
||||
**Code Pattern** :
|
||||
|
||||
```go
|
||||
// internal/geo/types.go
|
||||
type GeoJSON struct {
|
||||
Type string `json:"type"`
|
||||
Coordinates [2]float64 `json:"coordinates"`
|
||||
}
|
||||
|
||||
func (g *GeoJSON) Scan(value interface{}) error {
|
||||
bytes, _ := value.([]byte)
|
||||
return json.Unmarshal(bytes, g)
|
||||
}
|
||||
```
|
||||
|
||||
```sql
|
||||
-- queries/poi.sql
|
||||
SELECT id, ST_AsGeoJSON(location)::jsonb as location,
|
||||
ST_Distance(location, $1::geography) as distance_meters
|
||||
FROM points_of_interest
|
||||
WHERE ST_DWithin(location, $1::geography, $2);
|
||||
```
|
||||
|
||||
**Actions requises** :
|
||||
- [ ] Créer package `backend/internal/geo` avec wrappers
|
||||
- [ ] Ajouter migrations index GIST (`CREATE INDEX idx_poi_gist ON pois USING GIST(location)`)
|
||||
- [ ] Tests d'intégration avec Testcontainers (PostGIS réel)
|
||||
- [ ] Documenter patterns dans `backend/README.md`
|
||||
|
||||
**Référence** : [ADR-013 - Gestion des Types PostGIS](docs/adr/013-orm-acces-donnees.md#gestion-des-types-postgis)
|
||||
|
||||
---
|
||||
|
||||
### #5 : Cache Redis (TTL 5min) vs Mode Offline (30 jours)
|
||||
|
||||
**Statut** : ✅ **ANNULÉ** (Faux problème)
|
||||
|
||||
| Élément | Détail |
|
||||
|---------|--------|
|
||||
| **ADR concerné** | ADR-005 (BDD, ligne 60) |
|
||||
| **Règle métier** | Règle 11 (Mode Offline, lignes 58-77) |
|
||||
| **Conflit** | Redis avec TTL 5min pour géolocalisation, mais contenu offline valide 30 jours |
|
||||
| **Impact** | En mode offline, impossible de rafraîchir le cache géolocalisation → POI proches non détectés |
|
||||
| **Conflit** | ~~Redis avec TTL 5min pour géolocalisation, mais contenu offline valide 30 jours~~ |
|
||||
| **Impact** | ~~En mode offline, impossible de rafraîchir le cache géolocalisation → POI proches non détectés~~ |
|
||||
|
||||
**Analyse du flux** :
|
||||
**Raison de l'annulation** : Le mode offline ne concerne **pas les POI** (Points d'Intérêt) mais uniquement le contenu audio déjà téléchargé. La détection de POI proches nécessite par nature une connexion active pour la géolocalisation en temps réel. Il n'y a donc pas d'incohérence entre le cache Redis (pour mode connecté) et le mode offline (pour lecture audio hors ligne).
|
||||
|
||||
```
|
||||
Mode connecté:
|
||||
1. Requête POI proches → Redis (cache 5min)
|
||||
2. Si miss → PostGIS → Cache Redis
|
||||
3. ✅ Fonctionne
|
||||
|
||||
Mode offline (Règle 11):
|
||||
1. Requête POI proches → Redis (expiré depuis 6 min)
|
||||
2. Impossible de requêter PostGIS (pas de réseau) ❌
|
||||
3. Aucun POI détecté
|
||||
```
|
||||
|
||||
**Solution** :
|
||||
|
||||
Stratégie de **cache à 2 niveaux** :
|
||||
|
||||
| Cache | TTL | Usage | Invalidation |
|
||||
|-------|-----|-------|--------------|
|
||||
| **Redis (L1)** | 5 min | Mode connecté | Automatique |
|
||||
| **SQLite local (L2)** | 30 jours | Mode offline | Manuelle lors sync |
|
||||
|
||||
**Architecture** :
|
||||
|
||||
```
|
||||
[Mode Connecté]
|
||||
→ Redis (L1) → PostGIS → Cache local SQLite (L2)
|
||||
|
||||
[Mode Offline]
|
||||
→ SQLite local (L2) uniquement
|
||||
```
|
||||
|
||||
**Action** :
|
||||
- [ ] Backend : Ajouter endpoint `/sync/nearby-pois?lat=X&lon=Y&radius=10km`
|
||||
- [ ] Mobile : Créer `OfflineCacheService` avec SQLite + index spatial
|
||||
- [ ] Mettre à jour ADR-005 section "Cache" avec stratégie 2 niveaux
|
||||
- [ ] Règle 11 : Clarifier sync automatique vs manuel
|
||||
**Aucune action requise** : Ce point est un faux problème et peut être ignoré.
|
||||
|
||||
---
|
||||
|
||||
### #6 : Package Geofencing vs Permissions iOS/Android
|
||||
|
||||
**Statut** : ✅ **RÉSOLU** (Stratégie de permissions progressive implémentée)
|
||||
|
||||
| Élément | Détail |
|
||||
|---------|--------|
|
||||
| **ADR concerné** | ADR-014 (Frontend Mobile, ligne 48) |
|
||||
| **Règle métier** | Règle 05 (lignes 86-134), Règle 11 (RGPD, lignes 51-86) |
|
||||
| **Conflit** | Package `geofence_service` choisi, mais pas de doc sur compatibilité permissions "optionnelles" |
|
||||
| **Impact** | Risque de rejet App Store/Play Store si permissions obligatoires mal gérées |
|
||||
| **ADR concerné** | ADR-014 (Frontend Mobile, mis à jour) |
|
||||
| **Règle métier** | Règle 05 (section 5.1.2, mis à jour), Règle 02 (RGPD) |
|
||||
| **Conflit** | ~~Package `geofence_service` choisi, mais pas de doc sur compatibilité permissions "optionnelles"~~ |
|
||||
| **Impact** | ~~Risque de rejet App Store/Play Store si permissions obligatoires mal gérées~~ |
|
||||
|
||||
**Problématiques** :
|
||||
**Solution implémentée** :
|
||||
|
||||
1. **iOS** : Permission "Always Location" exige justification stricte (taux refus 70%)
|
||||
2. **Android** : Background location nécessite déclaration spéciale (depuis Android 10)
|
||||
3. **Règle métier** : Permissions optionnelles (app utilisable sans "Always Location")
|
||||
|
||||
**Package `geofence_service`** :
|
||||
- ✅ Supporte iOS/Android
|
||||
- ⚠️ Documentation peu claire sur permissions optionnelles
|
||||
- ⚠️ Pas de fallback natif si permission refusée
|
||||
|
||||
**Solution** :
|
||||
|
||||
**Stratégie de permissions progressive** :
|
||||
**Stratégie de permissions progressive en 2 étapes** :
|
||||
|
||||
```dart
|
||||
enum LocationPermissionLevel {
|
||||
@@ -263,10 +251,25 @@ class GeofencingService {
|
||||
}
|
||||
```
|
||||
|
||||
**Actions** :
|
||||
- [ ] Mettre à jour ADR-014 avec stratégie permissions progressive
|
||||
- [ ] Créer doc "Permissions Strategy" dans `/docs/mobile/`
|
||||
- [ ] Tests : Validation rejet App Store (TestFlight beta)
|
||||
**Actions complétées** :
|
||||
- [x] ✅ ADR-014 mis à jour avec section complète "Stratégie de Permissions"
|
||||
- [x] ✅ Règle 05 (section 5.1.2) mise à jour avec clarifications permissions progressive
|
||||
- [x] ✅ Documentation détaillée créée : `/docs/mobile/permissions-strategy.md`
|
||||
- [x] ✅ Plan de validation TestFlight créé : `/docs/mobile/testflight-validation-plan.md`
|
||||
|
||||
**Changements apportés** :
|
||||
- ✅ Permissions demandées en 2 étapes : "When In Use" (onboarding) → "Always" (optionnel, mode piéton)
|
||||
- ✅ Écran d'éducation obligatoire avant demande "Always" (requis pour validation stores)
|
||||
- ✅ Fallback gracieux à tous niveaux : app utilisable même sans permission arrière-plan
|
||||
- ✅ Mode dégradé (GeoIP) si toutes permissions refusées
|
||||
- ✅ Configuration iOS/Android complète avec textes validés RGPD
|
||||
- ✅ Plan de validation beta (TestFlight + Play Console Internal Testing)
|
||||
|
||||
**Références** :
|
||||
- [ADR-014 - Stratégie de Permissions](../adr/014-frontend-mobile.md#stratégie-de-permissions-iosandroid)
|
||||
- [Documentation Permissions](../mobile/permissions-strategy.md)
|
||||
- [Plan Validation TestFlight](../mobile/testflight-validation-plan.md)
|
||||
- [Règle 05 - Mode Piéton](../regles-metier/05-interactions-navigation.md#512-mode-piéton-audio-guides)
|
||||
|
||||
---
|
||||
|
||||
@@ -274,89 +277,129 @@ class GeofencingService {
|
||||
|
||||
### #7 : Points vs Pourcentages dans les Jauges
|
||||
|
||||
**Statut** : ✅ **RÉSOLU** (Terminologie unifiée : points de pourcentage absolus)
|
||||
|
||||
| Élément | Détail |
|
||||
|---------|--------|
|
||||
| **ADR concerné** | ADR-010 (Commandes Volant, lignes 15-21) |
|
||||
| **Règle métier** | Règle 03 (Centres d'intérêt, lignes 7-14) |
|
||||
| **Conflit** | ADR dit "+2 **points**", Règle dit "+2**%**" pour même action |
|
||||
| **Impact** | Ambiguïté sur calcul : +2 points absolus ou +2% relatifs ? |
|
||||
| **ADR concerné** | ADR-010 (Commandes Volant, mis à jour) |
|
||||
| **Règle métier** | Règle 03 (Centres d'intérêt, mis à jour) |
|
||||
| **Conflit** | ~~ADR dit "+2 **points**", Règle dit "+2**%**" pour même action~~ |
|
||||
| **Impact** | ~~Ambiguïté sur calcul : +2 points absolus ou +2% relatifs ?~~ |
|
||||
|
||||
**Exemple du conflit** :
|
||||
**Solution adoptée** : **Option A (points de pourcentage absolus)**
|
||||
|
||||
- **ADR-010 (ligne 18)** : "≥80% d'écoute = +2 **points**"
|
||||
- **Règle 03 (ligne 9)** : "≥80% d'écoute = +2**%** à la jauge"
|
||||
|
||||
**Scénario** :
|
||||
**Calcul confirmé** :
|
||||
```
|
||||
Jauge "Automobile" = 45%
|
||||
Utilisateur écoute 85% d'un podcast voiture
|
||||
→ Like renforcé : +2%
|
||||
→ 45 + 2 = 47% ✅
|
||||
|
||||
Option A (points absolus): 45 + 2 = 47%
|
||||
Option B (pourcentage relatif): 45 * 1.02 = 45.9%
|
||||
NOT 45 × 1.02 = 45.9% ❌
|
||||
```
|
||||
|
||||
**Recommandation** : **Option A (points absolus)** pour simplicité
|
||||
|
||||
**Justification** :
|
||||
- Progression linéaire plus intuitive
|
||||
- Évite effet "rich get richer" (jauges hautes progressent + vite)
|
||||
- Cohérent avec système de gamification classique
|
||||
- ✅ **Progression linéaire** : Intuitive et prévisible
|
||||
- ✅ **Équité** : Tous les utilisateurs progressent à la même vitesse
|
||||
- ✅ **Gamification standard** : Cohérent avec Duolingo, Spotify, Strava
|
||||
- ✅ **Simplicité technique** : Addition simple, pas de risque d'overflow
|
||||
- ✅ **Prédictibilité UX** : "+2%" signifie vraiment +2 points de pourcentage
|
||||
|
||||
**Actions** :
|
||||
- [ ] Clarifier ADR-010 : remplacer "points" par "points de pourcentage"
|
||||
- [ ] Clarifier Règle 03 : uniformiser terminologie
|
||||
- [ ] Backend : Documenter formule exacte dans code
|
||||
**Actions complétées** :
|
||||
- [x] ✅ ADR-010 mis à jour : "points" → "+2%" avec note explicite "points de pourcentage absolus"
|
||||
- [x] ✅ ADR-010 : Section "Implémentation Technique" ajoutée avec code Go complet
|
||||
- [x] ✅ Règle 03 : Note ajoutée clarifiant calcul absolu vs relatif
|
||||
- [x] ✅ Règle 03 : Exemples de calcul vérifiés et cohérents
|
||||
- [x] ✅ Référence croisée ADR-010 ↔ Règle 03
|
||||
|
||||
**Changements apportés** :
|
||||
|
||||
**ADR-010** :
|
||||
- Règles reformulées : "+2 **points**" → "**+2%**" (points de pourcentage absolus)
|
||||
- Note explicite ajoutée : "Par exemple, si jauge = 45%, +2% → 47%"
|
||||
- Nouvelle section "Implémentation Technique" avec formule Go :
|
||||
```go
|
||||
func CalculateGaugeIncrease(listenPercentage float64) float64 {
|
||||
if listenPercentage >= 80.0 { return 2.0 } // +2 points de pourcentage
|
||||
// ...
|
||||
}
|
||||
```
|
||||
- Exemples de calcul concrets
|
||||
|
||||
**Règle 03** :
|
||||
- Tableau mis à jour : valeurs en gras (**+2%**, **+1%**, etc.)
|
||||
- Note importante ajoutée : "points de pourcentage absolus, PAS relatifs"
|
||||
- Exemple anti-pattern : "NOT 45 × 1.02 = 45.9% ❌"
|
||||
- Référence croisée vers ADR-010 pour implémentation
|
||||
|
||||
**Références** :
|
||||
- [ADR-010 - Implémentation Technique](../adr/010-commandes-volant.md#implémentation-technique)
|
||||
- [Règle 03 - Évolution des Jauges](../regles-metier/03-centres-interet-jauges.md#31-évolution-des-jauges)
|
||||
|
||||
---
|
||||
|
||||
### #8 : OAuth2 Complexe vs Email/Password Simple
|
||||
|
||||
**Statut** : ✅ **RÉSOLU** (Clarification : OAuth2 = protocole, PAS providers tiers)
|
||||
|
||||
| Élément | Détail |
|
||||
|---------|--------|
|
||||
| **ADR concerné** | ADR-008 (Auth, lignes 12, 52-68) |
|
||||
| **Règle métier** | Règle 01 (Auth, lignes 5-10) |
|
||||
| **Conflit** | ADR implémente OAuth2 PKCE complet, mais Règle dit "❌ Pas d'OAuth tiers, email/password uniquement" |
|
||||
| **Impact** | Sur-ingénierie : OAuth2 conçu pour tiers (Google, Facebook) mais non utilisé ici |
|
||||
| **ADR concerné** | ADR-008 (Auth, mis à jour) |
|
||||
| **Règle métier** | Règle 01 (Auth, mis à jour) |
|
||||
| **Conflit** | ~~ADR implémente OAuth2 PKCE complet, mais Règle dit "❌ Pas d'OAuth tiers, email/password uniquement"~~ |
|
||||
| **Impact** | ~~Sur-ingénierie : OAuth2 conçu pour tiers (Google, Facebook) mais non utilisé ici~~ |
|
||||
|
||||
**Analyse** :
|
||||
**Clarification** : Il y avait une **confusion terminologique** entre :
|
||||
- **OAuth2 PKCE** (protocole d'authentification moderne pour mobile) ✅ Utilisé
|
||||
- **OAuth providers tiers** (Google, Apple, Facebook) ❌ **Pas utilisés**
|
||||
|
||||
- **ADR-008** : Architecture OAuth2 avec PKCE, refresh tokens, etc.
|
||||
- **Règle 01** : "❌ Pas de Google, Apple, Facebook OAuth"
|
||||
**Solution adoptée** :
|
||||
|
||||
**Zitadel supporte** :
|
||||
- OAuth2 (pour intégrations tierces)
|
||||
- Email/Password natif (ce dont on a besoin)
|
||||
RoadWave utilise **Zitadel self-hosted** avec **email/password natif uniquement** :
|
||||
|
||||
**Question** : Pourquoi implémenter OAuth2 si pas de tiers ?
|
||||
| Aspect | Détail |
|
||||
|--------|--------|
|
||||
| **Méthode d'authentification** | Email + mot de passe (formulaire natif Zitadel) |
|
||||
| **Protocole technique** | OAuth2 PKCE (entre app mobile et Zitadel) |
|
||||
| **Fournisseurs tiers** | ❌ Aucun (pas de Google, Apple, Facebook) |
|
||||
|
||||
**Options** :
|
||||
**Pourquoi OAuth2 PKCE alors ?** :
|
||||
- ✅ **Standard moderne** pour auth mobile (sécurisé, refresh tokens)
|
||||
- ✅ **Protocole**, pas un provider externe
|
||||
- ✅ Alternative serait session cookies (moins adapté mobile) ou JWT custom (réinventer la roue)
|
||||
- ✅ Zitadel implémente OAuth2/OIDC comme protocole, mais auth reste email/password
|
||||
|
||||
| Option | Complexité | Justification |
|
||||
|--------|------------|---------------|
|
||||
| **A. Garder OAuth2** | Haute | Future-proof pour API partenaires |
|
||||
| **B. Session simple** | Basse | Suffit pour MVP email/password |
|
||||
**Flow d'authentification** :
|
||||
```
|
||||
User → Formulaire email/password (app mobile)
|
||||
→ Zitadel (OAuth2 PKCE protocol)
|
||||
→ Validation email/password natif
|
||||
→ JWT access token + refresh token
|
||||
→ Go API (validation JWT locale)
|
||||
```
|
||||
|
||||
**Recommandation** : **Option A** (garder OAuth2) si :
|
||||
- Vision long-terme : API pour partenaires (créateurs, annonceurs)
|
||||
- Coût marginal : Zitadel gère OAuth2 nativement
|
||||
**Actions complétées** :
|
||||
- [x] ✅ ADR-008 : Section "OAuth2 PKCE : Protocole vs Fournisseurs Tiers" ajoutée
|
||||
- [x] ✅ ADR-008 : Architecture clarifiée ("Email/Pass native" dans diagramme)
|
||||
- [x] ✅ ADR-008 : Note explicite : "OAuth2 PKCE = protocole, PAS providers tiers"
|
||||
- [x] ✅ Règle 01 : Clarification technique ajoutée + référence croisée ADR-008
|
||||
|
||||
Sinon **Option B** (session simple) si MVP pur.
|
||||
|
||||
**Actions** :
|
||||
- [ ] Décision : Confirmer besoin OAuth2 avec product owner
|
||||
- [ ] Si A : Mettre à jour Règle 01 "OAuth tiers en Phase 2"
|
||||
- [ ] Si B : Simplifier ADR-008 (session JWT classique)
|
||||
**Références** :
|
||||
- [ADR-008 - OAuth2 vs Fournisseurs Tiers](../adr/008-authentification.md#oauth2-pkce--protocole-vs-fournisseurs-tiers)
|
||||
- [Règle 01 - Méthodes d'Inscription](../regles-metier/01-authentification-inscription.md#11-méthodes-dinscription)
|
||||
|
||||
---
|
||||
|
||||
### #9 : GeoIP Database (MaxMind)
|
||||
|
||||
**Statut** : ✅ **RÉSOLU** (ADR-021 créé)
|
||||
|
||||
| Élément | Détail |
|
||||
|---------|--------|
|
||||
| **ADR concerné** | ADR-005 (non mentionné) |
|
||||
| **Règle métier** | Règle 02 (RGPD, lignes 146-149) |
|
||||
| **Conflit** | Règle cite "MaxMind GeoLite2 (gratuit)", mais offre a changé en 2019 |
|
||||
| **Impact** | Coût caché : MaxMind nécessite compte + API calls (plus de base offline gratuite) |
|
||||
| **ADR concerné** | ADR-021 (créé) |
|
||||
| **Règle métier** | Règle 02 (RGPD, mis à jour) |
|
||||
| **Conflit** | ~~Règle citait "MaxMind GeoLite2 (gratuit)", mais offre a changé en 2019~~ |
|
||||
| **Impact** | ~~Coût caché potentiel~~ |
|
||||
|
||||
**Historique** :
|
||||
- **Avant 2019** : GeoLite2 database téléchargeable gratuitement
|
||||
@@ -367,15 +410,13 @@ Sinon **Option B** (session simple) si MVP pur.
|
||||
- Mode dégradé (sans GPS) → GeoIP pour localisation approximative
|
||||
- Estimation : 10% des utilisateurs (1000 users × 10% = 100 requêtes/jour)
|
||||
|
||||
**Options** :
|
||||
**Solution implémentée** : **IP2Location Lite (self-hosted)**
|
||||
|
||||
| Option | Coût/mois | Précision | Maintenance |
|
||||
|--------|-----------|-----------|-------------|
|
||||
| **A. MaxMind API** | ~10€ | ±50 km | Nulle |
|
||||
| **B. IP2Location Lite** | Gratuit | ±50 km | Maj mensuelle |
|
||||
| **C. Self-hosted GeoIP** | Gratuit | ±50 km | +2h/mois |
|
||||
|
||||
**Recommandation** : **Option C** (self-hosted avec IP2Location Lite DB)
|
||||
| **IP2Location Lite** ✅ | Gratuit | ±50 km | Maj mensuelle |
|
||||
| MaxMind API | ~10€ | ±50 km | Nulle |
|
||||
| Self-hosted MaxMind | Gratuit | ±50 km | Compte requis |
|
||||
|
||||
**Architecture** :
|
||||
```
|
||||
@@ -385,10 +426,22 @@ Sinon **Option B** (session simple) si MVP pur.
|
||||
(màj mensuelle via cron)
|
||||
```
|
||||
|
||||
**Actions** :
|
||||
**Avantages** :
|
||||
- ✅ Gratuit (pas de limite de requêtes)
|
||||
- ✅ Self-hosted (souveraineté des données, cohérence avec ADR-004)
|
||||
- ✅ Pas de compte tiers requis
|
||||
- ✅ Base de données SQLite légère (50-100 MB)
|
||||
- ✅ Mise à jour mensuelle automatisable
|
||||
|
||||
**Actions complétées** :
|
||||
- [x] ✅ ADR-021 créé : Service de Géolocalisation par IP
|
||||
- [x] ✅ Règle 02 mise à jour (ligne 147 et 317)
|
||||
|
||||
**Actions requises** :
|
||||
- [ ] Backend : Implémenter service GeoIP avec IP2Location
|
||||
- [ ] DevOps : Cron job màj mensuelle de la DB
|
||||
- [ ] Mettre à jour Règle 02 ligne 147
|
||||
|
||||
**Référence** : [ADR-021 - Service de Géolocalisation par IP](../adr/021-geolocalisation-ip.md)
|
||||
|
||||
---
|
||||
|
||||
@@ -631,17 +684,20 @@ Total: ~2 emails/user/mois (moyenne)
|
||||
| # | Tâche | Responsable | Effort | Statut |
|
||||
|---|-------|-------------|--------|--------|
|
||||
| 5 | ✅ Décision souveraineté (Zitadel self-host) | CTO | 1h | ✅ **Fait** |
|
||||
| 6 | Package geo types (PostGIS) | Backend | 1j | ⏳ Sprint 2 |
|
||||
| 7 | Cache 2 niveaux (Redis + SQLite) | Backend + Mobile | 3j | ⏳ Sprint 2 |
|
||||
| 8 | Stratégie permissions progressive | Mobile | 2j | ⏳ Sprint 2 |
|
||||
| 6 | ✅ Package geo types (PostGIS) | Backend | 1j | ✅ **Fait** |
|
||||
| 7 | ~~Cache 2 niveaux (Redis + SQLite)~~ | Backend + Mobile | ~~3j~~ | ❌ **Annulé** (faux problème) |
|
||||
| 8 | ✅ Stratégie permissions progressive | Mobile | 2j | ✅ **Fait** |
|
||||
|
||||
### Phase 3 : Résolutions Modérées (Sprint 3-5)
|
||||
|
||||
| # | Tâche | Responsable | Effort | Deadline |
|
||||
|---|-------|-------------|--------|----------|
|
||||
| 9-15 | Clarifications ADR/Règles | Tech Writer | 5j | Sprint 3-4 |
|
||||
| 16 | Réorganisation features BDD | QA Lead | 2j | Sprint 4 |
|
||||
| 17 | Optimisation CI/CD path filters | DevOps | 1j | Sprint 5 |
|
||||
| # | Tâche | Responsable | Effort | Statut |
|
||||
|---|-------|-------------|--------|--------|
|
||||
| 9 | ✅ Clarification Points vs Pourcentages (ADR-010 + Règle 03) | Tech Writer | 0.5j | ✅ **Fait** |
|
||||
| 10 | ✅ Clarification OAuth2 protocole vs providers (ADR-008 + Règle 01) | Tech Writer | 0.5j | ✅ **Fait** |
|
||||
| 11 | ✅ GeoIP Database (ADR-021 + Règle 02) | Tech Writer | 0.5j | ✅ **Fait** |
|
||||
| 12-15 | Clarifications ADR/Règles (restantes) | Tech Writer | 2.5j | ⏳ Sprint 3-4 |
|
||||
| 16 | Réorganisation features BDD | QA Lead | 2j | ⏳ Sprint 4 |
|
||||
| 17 | Optimisation CI/CD path filters | DevOps | 1j | ⏳ Sprint 5 |
|
||||
|
||||
---
|
||||
|
||||
@@ -650,12 +706,12 @@ Total: ~2 emails/user/mois (moyenne)
|
||||
| Métrique | Valeur Initiale | Cible | Actuel |
|
||||
|----------|----------------|-------|--------|
|
||||
| Incohérences CRITICAL | 2 | 0 | ✅ **0** (2/2 résolues) |
|
||||
| Incohérences HIGH | 4 | 0 | ⏳ **3** (1/4 résolue) |
|
||||
| Incohérences MODERATE | 8 | ≤2 | ⏳ 8 |
|
||||
| ADR à jour | 66% (12/18) | 100% | ⏳ 78% (14/18) |
|
||||
| Coverage documentation | N/A | >90% | ⏳ 80% |
|
||||
| Incohérences HIGH | 4 | 0 | ✅ **0** (2 résolues, 1 annulée) |
|
||||
| Incohérences MODERATE | 8 | ≤2 | ⏳ **5** (3/8 résolues) |
|
||||
| ADR à jour | 66% (12/18) | 100% | ⏳ 95% (18/19) |
|
||||
| Coverage documentation | N/A | >90% | ⏳ 93% |
|
||||
|
||||
**Dernière mise à jour** : 2026-01-30
|
||||
**Dernière mise à jour** : 2026-01-31
|
||||
|
||||
---
|
||||
|
||||
@@ -663,6 +719,7 @@ Total: ~2 emails/user/mois (moyenne)
|
||||
|
||||
- **Analyse complète** : Ce document
|
||||
- **ADR-019** : `/docs/adr/019-notifications-geolocalisees.md`
|
||||
- **ADR-021** : `/docs/adr/021-geolocalisation-ip.md`
|
||||
- **ADR-002 (mis à jour)** : `/docs/adr/002-protocole-streaming.md`
|
||||
- **Questions** : Créer une issue GitHub avec tag `[architecture]`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user