# Documentation Technique API GeoSector ## đŸ—ïž Infrastructure **Stack** : PHP 8.3 | NGINX | MariaDB 10.11 | Alpine Linux (Incus) | Environnement | Container | DB (IP) | URL | Serveur | |---------------|-----------|---------|-----|---------| | **DEV** | dva-geo | maria3 (13.23.33.4) | https://dapp.geosector.fr | IN3 (195.154.80.116) | | **REC** | rca-geo | maria3 (13.23.33.4) | https://rapp.geosector.fr | IN3 (195.154.80.116) | | **PROD** | pra-geo | maria4 (13.23.33.4) | https://app3.geosector.fr | IN4 (51.159.7.190) | **Architecture** : MVC sans framework | Point d'entrĂ©e : `index.php` | Config : `AppConfig.php` singleton ## đŸ—„ïž Base de donnĂ©es ### ModĂšle d'isolation par opĂ©ration (CRITIQUE) **Principe** : Chaque opĂ©ration est un **univers fermĂ©** isolĂ© de la table centrale `users`. ``` users (table centrale, conservĂ©e aprĂšs suppression opĂ©ration) └── ope_users (id, fk_user, fk_operation) ← PIVOT par opĂ©ration ├── ope_users_sectors (fk_user → ope_users.id) └── ope_pass (fk_user → ope_users.id) ``` **⚠ IMPORTANT pour Flutter** : - **`users.id`** = Identifiant global (gestion membres, login) - **`ope_users.id`** = Identifiant opĂ©ration (passages, secteurs) - **Flutter doit gĂ©rer les 2 IDs** lors du login et des CRUD **RĂ©ponse login :** ```json { "users_sectors": [ { "id": 123, // users.id (gestion membres) "ope_user_id": 50, // ope_users.id (passages/secteurs) "name": "John Doe", "fk_sector": 456 } ] } ``` **RequĂȘtes API depuis Flutter :** ```json // ✅ CrĂ©ation secteur : envoyer ope_users.id POST /api/sectors { "users": [50, 51] } // ope_users.id // ✅ CrĂ©ation passage : fk_user = ope_users.id POST /api/passages { "fk_user": 50 } // ope_users.id // ✅ Modification membre : utiliser users.id PUT /api/users/123 // users.id ``` ### Tables principales - **`entites`** : Amicales (chiffrement AES-256-CBC sur nom, email, IBAN) - **`users`** : Table centrale utilisateurs (conservĂ©e mĂȘme si opĂ©ration supprimĂ©e) - **`operations`** : Campagnes liĂ©es Ă  une entitĂ© - **`ope_users`** : **PIVOT** users ↔ opĂ©rations (ON DELETE CASCADE depuis operations) - **`ope_sectors`** : Secteurs gĂ©ographiques (polygones) - **`ope_users_sectors`** : Affectation users ↔ secteurs (FK → `ope_users.id`) - **`ope_pass`** : Passages (FK → `ope_users.id`, ON DELETE CASCADE) - **`medias`** : Fichiers (logos, exports, reçus) - Stockage : `/uploads/` ## 🔒 SĂ©curitĂ© - **Auth** : Sessions PHP (httpOnly, secure, SameSite=Strict) - **Mots de passe** : NIST SP 800-63B, bcrypt, HIBP check (k-anonymity) - **Chiffrement** : AES-256-CBC (noms, emails, tĂ©lĂ©phones, IBAN) - **Protection** : Brute force (8 tentatives/5min), IP blocking, PDO prepared statements - **Monitoring** : `SecurityMonitor`, `AlertService`, `IPBlocker` ## 💳 Stripe Connect - **DEV** : ClĂ©s TEST Pierre - **REC** : ClĂ©s TEST client + webhook `webhook-rca` - **PROD** : ClĂ©s LIVE client + webhook `webhook-pra` - **API** : `2025-08-27.basil` - **Tap to Pay** : iOS 16.4+ (iPhone XS+) | Android 11+ (95+ devices certifiĂ©s) - **Flow** : Passage créé → PaymentIntent → Tap to Pay → Mise Ă  jour `stripe_payment_id` ## 📩 FonctionnalitĂ©s 1. **Reçus fiscaux** : PDF auto (<5KB) pour dons, envoi email queue 2. **Logos entitĂ©s** : Upload PNG/JPG, redimensionnement 250x250px, base64 3. **Migration** : Endpoints REST par entitĂ© (9 phases) 4. **CRONs** : Email queue (*/5), cleanup sĂ©curitĂ© (2h), Stripe devices (dim 3h) ## 🚀 DĂ©ploiement ```bash ./deploy-api.sh # Local → dva-geo (DEV) ./deploy-api.sh rca # dva-geo → rca-geo (REC) ./deploy-api.sh pra # rca-geo → pra-geo (PROD) ``` - Backup auto (10 versions) - PrĂ©servation `/logs/` et `/uploads/` - Permissions : `nginx:nginx` (code), `nginx:nginx` (logs/uploads) - Composer install avec `--optimize-autoloader` ## ⚠ Points d'attention API ↔ Flutter ### 1. Isolation opĂ©rations (depuis Oct 2025) **Avant** : `ope_pass.fk_user` → `users.id` (table centrale) **AprĂšs** : `ope_pass.fk_user` → `ope_users.id` (pivot opĂ©ration) **Impact Flutter** : - Login retourne **2 IDs** : `id` (users.id) + `ope_user_id` (ope_users.id) - CrĂ©ation secteur/passage : envoyer `ope_user_id` - Affichage passages : mapper avec `ope_user_id` ### 2. Endpoints critiques modifiĂ©s | Endpoint | Body envoyĂ© | Mapping | |----------|-------------|---------| | `POST /api/sectors` | `users: [50, 51]` | ope_users.id | | `PUT /api/sectors/{id}` | `users: [50, 51]` | ope_users.id | | `POST /api/passages` | `fk_user: 50` | ope_users.id | | `PUT /api/passages/{id}` | `fk_user: 50` | ope_users.id | | `POST /api/users` | - | Retourne `ope_user_id` | ### 3. RequĂȘte SQL typique ```sql -- ❌ AVANT (CASSÉ) SELECT op.*, u.encrypted_name FROM ope_pass op JOIN users u ON op.fk_user = u.id -- ✅ APRÈS (CORRECT) SELECT op.*, u.encrypted_name FROM ope_pass op JOIN ope_users ou ON op.fk_user = ou.id JOIN users u ON ou.fk_user = u.id ``` ### 4. Suppression en cascade ```sql DELETE FROM operations WHERE id = 850; -- Supprime automatiquement (CASCADE) : -- - ope_users -- - ope_users_sectors -- - ope_pass -- - ope_sectors -- ✅ users conservĂ© (table centrale) ``` ## 📝 Changelog critique **Version 3.3.7 (26 Oct 2025)** : - 🔧 Correction bug `SectorController::update()` : Recherche users par `ope_users.id` au lieu de `users.id` - 🔧 Permissions logs corrigĂ©es : `nginx:nginx` + `750/640` - 🔧 PHP `display_errors = Off` (warnings loggĂ©s dans `/var/log/php83/error.log`) **Version 3.3.6 (21 Oct 2025)** : - Validation inscription : Code postal + ville (doublon) **Version 3.2.7 (16 Oct 2025)** : - Migration RCA-GEO vers maria3 complĂ©tĂ©e - URL PROD : `app3.geosector.fr` **Version 3.2.4-3.2.6 (Sep 2025)** : - Stripe Connect complet (Tap to Pay, webhooks multi-env) --- **Mis Ă  jour : 26 Octobre 2025**