201 lines
8.3 KiB
Markdown
201 lines
8.3 KiB
Markdown
# 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 <token>` 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!
|
|
```
|