Save France

Backend

Architecture backend Symfony avec API Platform et FrankenPHP

Introduction

Le backend de Save France est construit avec Symfony 7.3 et utilise API Platform pour exposer une API REST. L'application suit une architecture modulaire organisée par domaines métier (Maintenance, Troubleshooting, Equipment) avec une séparation claire des responsabilités.

Architecture

flowchart TD
    A[Client] --> B[Caddy Reverse Proxy]
    B --> C[FrankenPHP]
    C --> D[API Platform]
    D --> E[Controllers]
    E --> F[Services]
    F --> G[Repositories]
    G --> H[(PostgreSQL)]
    
    E --> I[Processors]
    E --> J[Providers]
    
    F --> K[External Services]
    K --> L[Stripe]
    K --> M[Yousign]
    K --> N[Brevo]
    K --> O[Gotenberg]
    
    style C fill:#4CAF50
    style D fill:#42B883
    style H fill:#336791

Structure du projet

api/sources/src/
├── Command/                    # Commandes console Symfony
│   ├── EmailUnsignedContractsCommand.php
│   └── UpdateContractCommand.php
├── Controller/                 # Contrôleurs HTTP
│   ├── Admin/                  # Backoffice EasyAdmin
│   │   ├── Configuration/      # CRUD de configuration
│   │   ├── Equipment/          # CRUD équipements
│   │   ├── Filter/             # Filtres personnalisés
│   │   ├── Offer/              # Gestion des offres
│   │   ├── Request/            # Gestion des demandes
│   │   └── Troubleshooting/    # Gestion des dépannages
│   ├── Api/                    # Points d'API REST
│   ├── Sav/                    # API pour le SAV
│   └── Webhook/                # Webhooks externes
├── DataFixtures/               # Données de test
├── Doctrine/                   # Extensions Doctrine
│   └── Api/                    # Extensions API Platform
├── Dto/                        # Data Transfer Objects
├── Entity/                     # Entités Doctrine
│   ├── Equipment/              # Équipements
│   ├── Maintenance/            # Maintenance
│   ├── MaintenanceOffer/       # Offres de maintenance
│   └── Troubleshooting/        # Dépannage
├── Enum/                       # Énumérations
├── EventListener/              # Écouteurs d'événements
├── Form/                       # Formulaires Symfony
├── Mailer/                     # Système d'email
│   ├── Factory/                # Factories de mails
│   └── Mail/                   # Classes de mails
├── Processor/                  # Processors API Platform
├── Provider/                   # Providers API Platform
├── Repository/                 # Référentiels de données
├── Service/                    # Logique métier
│   ├── Contract/               # Services de contrat
│   ├── Request/                # Services de demande
│   └── Yousign/                # Intégration Yousign
└── Validator/                  # Contraintes de validation

Technologies clés

Framework et runtime

  • Framework : Symfony 7.3
  • Runtime : FrankenPHP 1.4.4 (PHP 8.4.4+)
  • ORM : Doctrine ORM 3.5+
  • Migrations : Doctrine Migrations 3.4+

API et authentification

  • API : API Platform 4.1+
  • Authentification JWT : LexikJWTAuthenticationBundle 3.1+
  • Refresh Tokens : GesdinetJWTRefreshTokenBundle 1.5+
  • CORS : NelmioCorsBundle 2.5+

Administration

  • Backoffice : EasyAdminBundle 4.25+

Services externes

  • Paiement : Stripe PHP SDK 17.6+
  • Signature électronique : Yousign (service personnalisé)
  • Email : Brevo PHP SDK 2.0+
  • Génération PDF : Gotenberg Bundle 1.0+

Extensions Doctrine

  • Extensions : StofDoctrineExtensionsBundle 1.14+ (soft delete, timestamps)

Outils de développement

  • Tests : PHPUnit 12.3+
  • Analyse statique : PHPStan 2.1+ (avec extensions Doctrine et Symfony)
  • Qualité de code : Easy Coding Standard 12.6+
  • Refactoring : Rector 2.1+
  • Fixtures : DoctrineFixturesBundle 4.1+

Flux de données

sequenceDiagram
    participant C as Client
    participant A as API Platform
    participant P as Processor
    participant S as Service
    participant R as Repository
    participant D as Database
    
    C->>A: Requête HTTP (JSON)
    A->>P: Dénormalisation
    P->>S: Validation & Logique métier
    S->>R: Récupération données
    R->>D: Requête SQL
    D-->>R: Résultats
    R-->>S: Entités Doctrine
    S-->>P: Traitement
    P->>A: Normalisation
    A-->>C: Réponse JSON

Domaines métier

Maintenance

Gestion des demandes de maintenance avec :

  • Création de demandes multi-étapes
  • Calcul d'offres personnalisées
  • Génération et signature de contrats
  • Gestion des paiements Stripe
  • Application de codes de réduction

Entités principales :

  • Maintenance\Request : Demande de maintenance
  • Maintenance\Offer : Offre associée
  • Maintenance\Equipment : Équipements concernés
  • Maintenance\Contract : Contrats générés
  • Maintenance\Price : Calculs de prix
  • Maintenance\Discount : Codes de réduction

Troubleshooting

Gestion des demandes de dépannage avec :

  • Création de demandes de dépannage
  • Sélection de diagnostics
  • Gestion des disponibilités
  • Envoi d'emails d'alerte

Entités principales :

  • Troubleshooting\Troubleshooting : Demande de dépannage
  • Troubleshooting\Diagnosis : Diagnostics possibles

Equipment

Référentiel des équipements avec :

  • Catégories d'équipements
  • Types d'équipements
  • Marques
  • Coefficients de tarification

Entités principales :

  • Equipment\Category : Catégories
  • Equipment\Type : Types
  • Equipment\Brand : Marques
  • CoefficientRate : Coefficients

API Platform

L'API est construite avec API Platform qui fournit :

Opérations automatiques

  • GET : Récupération de collection
  • GET /{id} : Récupération d'un élément
  • POST : Création
  • PATCH : Mise à jour partielle
  • DELETE : Suppression

Composants personnalisés

  • Processors : Traitement des données avant/après persistance
    • RequestDiscountPostProcessor : Application de codes de réduction
    • RequestPatchProcessor : Mise à jour des demandes
    • TroubleshootingPostProcessor : Traitement des dépannages
  • Providers : Personnalisation de la récupération des données
    • PostalCodeRequestProvider : Données enrichies pour les demandes
    • PostalCodeTroubleshootingProvider : Données enrichies pour les dépannages
    • GetContractProvider : Récupération de contrats
  • Extensions Doctrine : Filtres et extensions de requêtes
    • Doctrine\Api\RequestExtension : Filtres sur les demandes

Documentation

  • Swagger UI disponible en développement
  • Documentation désactivée en production
  • Authentification JWT via header Authorization

Services métier

CalculateOfferFromRequestService

Service de calcul des offres de maintenance :

  • Calcul des tarifs de déplacement avec coefficients
  • Calcul de la main d'œuvre par équipement
  • Calcul des fournitures
  • Application des TVA selon le profil client
  • Gestion robuste des paramètres configurables

Voir la documentation complète du calcul des tarifs pour plus de détails.

ContractService

Gestion complète des contrats :

  • Génération de PDF via Gotenberg
  • Envoi à Yousign pour signature
  • Gestion du cycle de vie (création, signature, expiration)

StripeService

Intégration avec Stripe :

  • Création de sessions de paiement
  • Gestion des webhooks
  • Mise à jour du statut de paiement

YouSignService

Intégration avec Yousign :

  • Création de dossiers de signature
  • Envoi de documents
  • Suivi du statut de signature
  • Vérification manuelle en cas de défaillance webhook

Voir la documentation complète YouSign pour plus de détails.

MailerService

Système d'email avec factories :

  • Factory\User\* : Emails utilisateurs
  • Factory\Admin\* : Emails administrateurs
  • Templates Twig pour le rendu

Authentification

JWT

  • Access Token : Token court (15 minutes)
  • Refresh Token : Token long (1 semaine)
  • Stockage dans les cookies côté client
  • Endpoint /api/auth/refresh pour renouveler

Admin

  • Authentification via EasyAdmin
  • Rôles Symfony (ROLE_USER, ROLE_ADMIN)
  • Réinitialisation de mot de passe via SymfonyCastsResetPasswordBundle

Bonnes pratiques

Contrôleurs

  • Contrôleurs API légers, logique dans les services
  • Utilisation de Processors pour la logique API Platform
  • Validation automatique via les contraintes Symfony
  • Gestion d'erreurs cohérente avec les exceptions HTTP

Services

  • Une classe = une responsabilité
  • Injection de dépendances via constructeur
  • Interfaces pour les services réutilisables (ex: ContractServiceInterface)
  • Services marqués comme readonly quand possible

Entités

  • Logique métier dans les services, pas dans les entités
  • Types stricts (PHP 8.4+)
  • Utilisation d'énumérations pour les statuts
  • Soft delete via StofDoctrineExtensionsBundle
  • Lifecycle callbacks pour les timestamps

API Platform

  • Utilisation de Groups de sérialisation pour contrôler les données exposées
  • Processors pour la logique métier liée à l'API
  • Providers pour personnaliser la récupération
  • Extensions Doctrine pour les filtres complexes

Tests

  • Tests d'intégration API dans tests/Api/
  • Tests unitaires pour les services dans tests/Service/
  • Utilisation de fixtures pour les données de test
  • Tests de robustesse avec paramètres manquants
  • PHPStan pour l'analyse statique

Voir la documentation des tests du calcul des tarifs pour un exemple complet.

Workflow de développement

  1. Créer une branche
    git checkout -b feature/ma-nouvelle-fonctionnalite
    
  2. Développer
    • Créer/modifier les entités Doctrine
    • Générer la migration : php bin/console make:migration
    • Implémenter la logique dans les services
    • Exposer via API Platform si nécessaire
    • Écrire les tests
  3. Vérifier la qualité
    # Tests
    php bin/phpunit
    
    # Analyse statique
    vendor/bin/phpstan analyse
    
    # Qualité de code
    vendor/bin/ecs check
    
  4. Soumettre une PR
    • Décrire les changements
    • Lier les issues
    • Demander des relecteurs

Commandes utiles

Pour les opérations sur la base (restauration, dump, vidage des données) avec Docker, voir Manipulation de la base de données.

# Migrations
php bin/console make:migration
php bin/console doctrine:migrations:migrate

# Fixtures
php bin/console doctrine:fixtures:load

# Cache
php bin/console cache:clear

# Créer une entité
php bin/console make:entity

# Créer un contrôleur API Platform
php bin/console make:api-platform:resource

# Créer un service
php bin/console make:service

Déploiement

Le déploiement se fait via GitLab CI/CD avec :

  • Build de l'image Docker
  • Push vers le registry
  • Déploiement sur l'environnement cible (review/production)
  • Utilisation de FrankenPHP pour les performances

Monitoring

  • Logs structurés JSON via Monolog
  • Métriques Caddy disponibles sur /metrics
  • Healthcheck configuré pour Docker

Sécurité

  • Validation des entrées avec Symfony Validator
  • Protection CSRF pour les formulaires
  • Authentification JWT avec tokens courts
  • Rate limiting via Caddy
  • Audit des logs de sécurité
  • Mises à jour de sécurité régulières

Liens utiles

Résumé

  • Symfony 7.3 avec FrankenPHP pour les performances
  • API Platform pour l'exposition REST automatique
  • Architecture modulaire par domaines métier
  • Intégrations externes (Stripe, Yousign, Brevo, Gotenberg)
  • Backoffice EasyAdmin pour la gestion
  • Tests et outils de qualité intégrés
  • Déploiement containerisé avec Docker