Files
geo/api/docs/TECHBOOK.md
pierre 2f5946a184 feat: Version 3.5.2 - Configuration Stripe et gestion des immeubles
- Configuration complète Stripe pour les 3 environnements (DEV/REC/PROD)
  * DEV: Clés TEST Pierre (mode test)
  * REC: Clés TEST Client (mode test)
  * PROD: Clés LIVE Client (mode live)
- Ajout de la gestion des bases de données immeubles/bâtiments
  * Configuration buildings_database pour DEV/REC/PROD
  * Service BuildingService pour enrichissement des adresses
- Optimisations pages et améliorations ergonomie
- Mises à jour des dépendances Composer
- Nettoyage des fichiers obsolètes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 18:26:27 +01:00

5.8 KiB
Executable File

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 :

{
  "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 :

// ✅ 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

./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_userusers.id (table centrale) Après : ope_pass.fk_userope_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

-- ❌ 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

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