# Documentation Architecture API — ERP Rayhan **PFE Ali Guennari — SUARL Rayhan** ## Architecture Technique ``` ┌─────────────────────────────────────────────────────────┐ │ Application Flutter (Client) │ │ (Windows Desktop / Web / Android) │ └─────────────────────┬───────────────────────────────────┘ │ HTTP/HTTPS (JWT Bearer Token) ▼ ┌─────────────────────────────────────────────────────────┐ │ API REST Spring Boot (Port 8090) │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │Controller│→ │ Service │→ │Repository│ │ │ └──────────┘ └──────────┘ └──────────┘ │ │ ┌──────────┐ │ │ │ JPA/ │ │ │ │Hibernate │ │ └──────────────────────────────┴────┬─────┴──────────────┘ │ JDBC ▼ ┌─────────────────────┐ │ MySQL 8 (DB) │ │ rayhan_erp_db │ └─────────────────────┘ ``` ## Pattern d'Architecture N-Tiers L'API suit rigoureusement le **pattern Controller → Service → Repository → Model** : | Couche | Rôle | Exemple | |--------|------|---------| | **Controller** | Reçoit les requêtes HTTP, délègue au service, retourne la réponse | `ArticleController.java` | | **Service** | Contient la logique métier (règles, validations, transactions) | `StockService.java` | | **Repository** | Abstraction d'accès à la base de données (Spring Data JPA) | `ArticleRepository.java` | | **Model** | Entités JPA mappées sur les tables MySQL | `Article.java` | ## Tous les Endpoints de l'API ### Authentification (Public — sans token) | Méthode | URL | Description | |---------|-----|-------------| | POST | `/api/auth/signin` | Connexion → retourne JWT | | POST | `/api/auth/signup` | Créer un utilisateur | ### Articles (Catalogue) | Méthode | URL | Rôles autorisés | |---------|-----|-----------------| | GET | `/api/articles` | Tous | | GET | `/api/articles/{id}` | Tous | | GET | `/api/articles/type/{type}` | Tous (MP, PF, PSF) | | GET | `/api/articles/alertes-stock` | PDG, Magasinier, Production | | POST | `/api/articles` | PDG, Production, Magasinier | | PUT | `/api/articles/{id}` | PDG, Production | | DELETE | `/api/articles/{id}` | PDG (désactivation logique) | ### Clients | Méthode | URL | Rôles autorisés | |---------|-----|-----------------| | GET | `/api/clients` | PDG, Vente | | GET | `/api/clients/search?q=` | PDG, Vente | | GET | `/api/clients/{id}` | PDG, Vente | | POST | `/api/clients` | PDG, Vente | | PUT | `/api/clients/{id}` | PDG, Vente | ### Fournisseurs | Méthode | URL | Rôles autorisés | |---------|-----|-----------------| | GET | `/api/fournisseurs` | PDG, Achat | | GET | `/api/fournisseurs/search?q=` | PDG, Achat | | GET | `/api/fournisseurs/{id}` | PDG, Achat | | POST | `/api/fournisseurs` | PDG, Achat | | PUT | `/api/fournisseurs/{id}` | PDG, Achat | ### Cycle d'Achat | Méthode | URL | Rôles autorisés | |---------|-----|-----------------| | GET | `/api/purchase-orders` | PDG, Achat | | POST | `/api/purchase-orders` | PDG, Achat | | POST | `/api/purchase-orders/{id}/receive` | PDG, Achat, Magasinier | **Flux automatique lors de la réception :** `POST /receive` → Crée le BR → `StockService.entreeStock()` → Mise à jour `Article.stockActuel` + création `StockMovement` ### Cycle de Vente | Méthode | URL | Rôles autorisés | |---------|-----|-----------------| | GET | `/api/sales-orders` | PDG, Vente | | POST | `/api/sales-orders` | PDG, Vente | | POST | `/api/sales-orders/{id}/deliver` | PDG, Vente, Magasinier | **Flux automatique lors de la livraison :** `POST /deliver` → Crée le BL → `StockService.sortieStock()` → Mise à jour `Article.stockActuel` + création `StockMovement` ### Cycle de Production | Méthode | URL | Rôles autorisés | |---------|-----|-----------------| | GET | `/api/production/bom/{produitFiniId}` | PDG, Production | | POST | `/api/production/bom` | PDG, Production | | DELETE | `/api/production/bom/{id}` | PDG, Production | | GET | `/api/production/orders` | PDG, Production | | POST | `/api/production/orders/plan` | PDG, Production | | POST | `/api/production/orders/{id}/launch` | PDG, Production | | POST | `/api/production/orders/{id}/complete` | PDG, Production | **Cycle de vie d'un OF :** ``` PLANIFIE → (vérif stock MP) → LANCE → (consomme MP) → TERMINE → (entre PF en stock) ``` ### Gestion du Stock | Méthode | URL | Rôles autorisés | |---------|-----|-----------------| | GET | `/api/stock/historique/{articleId}` | PDG, Magasinier, Production | | POST | `/api/stock/adjust` | PDG, Magasinier | ### Tableau de Bord (KPIs) | Méthode | URL | Rôles autorisés | |---------|-----|-----------------| | GET | `/api/dashboard` | PDG uniquement | --- ## Modèle de Données Relationnel ``` users (id, username, email, password, firstName, lastName, enabled) └── user_roles (user_id, role_id) roles (id, name: ERole) tiers (id, raisonSociale, matriculeFiscal, adresse, telephone, email, ville, actif) ├── clients (tiers_id FK, typeClient, plafondCredit, delaiPaiement) └── fournisseurs (tiers_id FK, pays, categorieProduit, delaiLivraison, modePaiement) articles (id, reference, designation, type: MP|PSF|PF, uniteMesure, prixUnitaire, stockActuel, stockMinimum, actif) bom_lines (id, produit_fini_id FK→articles, composant_id FK→articles, quantiteParUnite) production_orders (id, reference, produit_fini_id FK, quantitePlanifiee, quantiteRealisee, datePlanifiee, dateLancement, dateTerminaison, statut) purchase_orders (id, reference, fournisseur_id FK, dateCommande, statut, totalHT, totalTVA, totalTTC) └── purchase_order_lines (id, purchase_order_id FK, article_id FK, quantiteCommandee, quantiteRecue, prixUnitaireHT, tauxTVA) goods_receipts (id, reference, purchase_order_id FK, dateReception) └── goods_receipt_lines (id, goods_receipt_id FK, purchase_order_line_id FK, article_id FK, quantiteRecue) sales_orders (id, reference, client_id FK, dateCommande, statut, totalHT, totalTVA, totalTTC) └── sales_order_lines (id, sales_order_id FK, article_id FK, quantiteCommandee, quantiteLivree, prixUnitaireHT, tauxTVA) delivery_notes (id, reference, sales_order_id FK, dateLivraison, statut) └── delivery_note_lines (id, delivery_note_id FK, sales_order_line_id FK, article_id FK, quantiteLivree) stock_movements (id, article_id FK, type: IN|OUT, quantite, stockAvant, stockApres, sourceDocument, referenceDocument, motif, dateHeure, user_id FK) ``` --- ## Sécurité ### Mécanisme JWT 1. Le client envoie `POST /api/auth/signin` avec username/password 2. Le serveur retourne un JWT signé (valide 24h) 3. Le client inclut `Authorization: Bearer ` dans chaque requête 4. `AuthTokenFilter` intercepte et valide le token avant chaque endpoint sécurisé ### Contrôle d'Accès par Rôle (`@PreAuthorize`) Chaque endpoint est annoté avec les rôles autorisés : ```java @PreAuthorize("hasAnyRole('ROLE_PDG', 'ROLE_RESPONSABLE_VENTE')") ``` --- ## Démarrage de l'Application ```bash # Via Docker Compose docker compose up -d # Vérifier que les conteneurs tournent docker ps # Voir les logs docker logs rayhan-backend -f # Premier démarrage : admin créé automatiquement # username: admin | password: Rayhan2024! ```