# 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!
```
