Initial commit

This commit is contained in:
dahoud
2025-10-01 01:37:34 +00:00
commit f2bb633142
310 changed files with 86051 additions and 0 deletions

380
docs/concepts/02-CLIENT.md Normal file
View File

@@ -0,0 +1,380 @@
# 👤 CONCEPT: CLIENT
## 📌 Vue d'ensemble
Le concept **CLIENT** représente les clients de l'entreprise BTP, qu'ils soient **particuliers** ou **professionnels**. Il gère toutes les informations de contact, coordonnées, et relations avec les chantiers et devis.
**Importance**: ⭐⭐⭐⭐⭐ (Concept fondamental)
---
## 🗂️ Fichiers concernés
### **Entités JPA** (`domain/core/entity/`)
| Fichier | Description | Lignes |
|---------|-------------|--------|
| `Client.java` | Entité principale représentant un client | 113 |
| `TypeClient.java` | Enum des types de clients (PARTICULIER, PROFESSIONNEL) | 21 |
### **DTOs** (`domain/shared/dto/`)
| Fichier | Description |
|---------|-------------|
| `ClientCreateDTO.java` | DTO pour créer/modifier un client |
### **Services** (`application/service/`)
| Fichier | Description |
|---------|-------------|
| `ClientService.java` | Service métier pour la gestion des clients |
### **Resources (API REST)** (`adapter/http/`)
| Fichier | Description |
|---------|-------------|
| `ClientResource.java` | Endpoints REST pour les clients |
---
## 📊 Modèle de données
### **Entité Client**
<augment_code_snippet path="btpxpress-server/src/main/java/dev/lions/btpxpress/domain/core/entity/Client.java" mode="EXCERPT">
````java
@Entity
@Table(name = "clients")
@Data
@Builder
public class Client extends PanacheEntityBase {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private UUID id;
@NotBlank(message = "Le nom est obligatoire")
@Column(name = "nom", nullable = false, length = 100)
private String nom;
@NotBlank(message = "Le prénom est obligatoire")
@Column(name = "prenom", nullable = false, length = 100)
private String prenom;
@Column(name = "entreprise", length = 200)
private String entreprise;
@Email(message = "Email invalide")
@Column(name = "email", unique = true, length = 255)
private String email;
@Pattern(regexp = "^(?:(?:\\+|00)33|0)\\s*[1-9](?:[\\s.-]*\\d{2}){4}$")
@Column(name = "telephone", length = 20)
private String telephone;
@Enumerated(EnumType.STRING)
@Column(name = "type_client", length = 20)
private TypeClient type = TypeClient.PARTICULIER;
// Relations
@OneToMany(mappedBy = "client", cascade = CascadeType.ALL)
private List<Chantier> chantiers;
@OneToMany(mappedBy = "client", cascade = CascadeType.ALL)
private List<Devis> devis;
}
````
</augment_code_snippet>
### **Enum TypeClient**
<augment_code_snippet path="btpxpress-server/src/main/java/dev/lions/btpxpress/domain/core/entity/TypeClient.java" mode="EXCERPT">
````java
public enum TypeClient {
PARTICULIER("Particulier"),
PROFESSIONNEL("Professionnel");
private final String label;
TypeClient(String label) {
this.label = label;
}
public String getLabel() {
return label;
}
}
````
</augment_code_snippet>
### **Champs principaux**
| Champ | Type | Obligatoire | Description |
|-------|------|-------------|-------------|
| `id` | UUID | Oui | Identifiant unique |
| `nom` | String(100) | Oui | Nom du client |
| `prenom` | String(100) | Oui | Prénom du client |
| `entreprise` | String(200) | Non | Nom de l'entreprise (si professionnel) |
| `email` | String(255) | Non | Email (unique) |
| `telephone` | String(20) | Non | Téléphone (format français validé) |
| `adresse` | String(500) | Non | Adresse postale |
| `codePostal` | String(10) | Non | Code postal |
| `ville` | String(100) | Non | Ville |
| `numeroTVA` | String(20) | Non | Numéro de TVA intracommunautaire |
| `siret` | String(14) | Non | Numéro SIRET (entreprises françaises) |
| `type` | TypeClient | Oui | Type de client (défaut: PARTICULIER) |
| `actif` | Boolean | Oui | Client actif (défaut: true) |
| `dateCreation` | LocalDateTime | Auto | Date de création |
| `dateModification` | LocalDateTime | Auto | Date de modification |
### **Relations**
| Relation | Type | Entité cible | Description |
|----------|------|--------------|-------------|
| `chantiers` | OneToMany | Chantier | Liste des chantiers du client |
| `devis` | OneToMany | Devis | Liste des devis du client |
---
## 🔌 API REST
### **Base URL**: `/api/v1/clients`
### **Endpoints disponibles**
| Méthode | Endpoint | Description | Permission |
|---------|----------|-------------|------------|
| GET | `/api/v1/clients` | Liste tous les clients | CLIENTS_READ |
| GET | `/api/v1/clients/{id}` | Détails d'un client | CLIENTS_READ |
| POST | `/api/v1/clients` | Créer un client | CLIENTS_CREATE |
| PUT | `/api/v1/clients/{id}` | Modifier un client | CLIENTS_UPDATE |
| DELETE | `/api/v1/clients/{id}` | Supprimer un client | CLIENTS_DELETE |
| GET | `/api/v1/clients/search` | Rechercher des clients | CLIENTS_READ |
| GET | `/api/v1/clients/stats` | Statistiques clients | CLIENTS_READ |
### **Paramètres de requête (Query Params)**
| Paramètre | Type | Description | Exemple |
|-----------|------|-------------|---------|
| `page` | Integer | Numéro de page (0-based) | `?page=0` |
| `size` | Integer | Taille de la page | `?size=20` |
| `search` | String | Terme de recherche | `?search=dupont` |
---
## 💻 Exemples d'utilisation
### **1. Récupérer tous les clients**
```bash
curl -X GET http://localhost:8080/api/v1/clients \
-H "Accept: application/json"
```
**Réponse** (200 OK):
```json
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"nom": "Dupont",
"prenom": "Jean",
"email": "jean.dupont@example.com",
"telephone": "+33 6 12 34 56 78",
"adresse": "123 Rue de la Paix",
"codePostal": "75002",
"ville": "Paris",
"type": "PARTICULIER",
"actif": true,
"dateCreation": "2025-01-15T10:30:00"
},
{
"id": "660e8400-e29b-41d4-a716-446655440001",
"nom": "Martin",
"prenom": "Sophie",
"entreprise": "BTP Solutions SARL",
"email": "contact@btpsolutions.fr",
"telephone": "+33 1 23 45 67 89",
"siret": "12345678901234",
"numeroTVA": "FR12345678901",
"type": "PROFESSIONNEL",
"actif": true
}
]
```
### **2. Créer un nouveau client particulier**
```bash
curl -X POST http://localhost:8080/api/v1/clients \
-H "Content-Type: application/json" \
-d '{
"nom": "Durand",
"prenom": "Pierre",
"email": "pierre.durand@example.com",
"telephone": "+33 6 98 76 54 32",
"adresse": "45 Avenue des Champs",
"codePostal": "75008",
"ville": "Paris",
"type": "PARTICULIER"
}'
```
**Réponse** (201 Created):
```json
{
"id": "generated-uuid",
"nom": "Durand",
"prenom": "Pierre",
"email": "pierre.durand@example.com",
"type": "PARTICULIER",
"actif": true,
"dateCreation": "2025-09-30T14:25:00"
}
```
### **3. Créer un client professionnel**
```bash
curl -X POST http://localhost:8080/api/v1/clients \
-H "Content-Type: application/json" \
-d '{
"nom": "Entreprise",
"prenom": "Construction",
"entreprise": "ABC Construction SA",
"email": "contact@abc-construction.fr",
"telephone": "+33 1 45 67 89 01",
"adresse": "10 Boulevard Haussmann",
"codePostal": "75009",
"ville": "Paris",
"siret": "98765432109876",
"numeroTVA": "FR98765432109",
"type": "PROFESSIONNEL"
}'
```
### **4. Rechercher des clients**
```bash
# Par nom
curl -X GET "http://localhost:8080/api/v1/clients/search?search=dupont"
# Avec pagination
curl -X GET "http://localhost:8080/api/v1/clients?page=0&size=10"
```
### **5. Obtenir les statistiques**
```bash
curl -X GET http://localhost:8080/api/v1/clients/stats
```
**Réponse**:
```json
{
"totalClients": 156,
"clientsActifs": 142,
"particuliers": 98,
"professionnels": 58,
"nouveauxCeMois": 12,
"avecChantiers": 87,
"sansChantiers": 69
}
```
---
## 🔧 Services métier
### **ClientService**
**Méthodes principales**:
| Méthode | Description | Retour |
|---------|-------------|--------|
| `findAll()` | Récupère tous les clients | `List<Client>` |
| `findAll(int page, int size)` | Récupère avec pagination | `List<Client>` |
| `findById(UUID id)` | Récupère par ID | `Optional<Client>` |
| `findByIdRequired(UUID id)` | Récupère par ID (exception si absent) | `Client` |
| `create(ClientCreateDTO dto)` | Crée un client | `Client` |
| `update(UUID id, ClientCreateDTO dto)` | Met à jour | `Client` |
| `delete(UUID id)` | Supprime (soft delete) | `void` |
| `search(String term)` | Recherche textuelle | `List<Client>` |
| `findByType(TypeClient type)` | Filtre par type | `List<Client>` |
| `findActifs()` | Clients actifs uniquement | `List<Client>` |
| `getStatistics()` | Statistiques globales | `Object` |
---
## 🔐 Permissions requises
| Permission | Description | Rôles autorisés |
|------------|-------------|-----------------|
| `CLIENTS_READ` | Lecture des clients | ADMIN, MANAGER, CHEF_CHANTIER, COMPTABLE |
| `CLIENTS_CREATE` | Création de clients | ADMIN, MANAGER |
| `CLIENTS_UPDATE` | Modification de clients | ADMIN, MANAGER |
| `CLIENTS_DELETE` | Suppression de clients | ADMIN, MANAGER |
| `CLIENTS_ASSIGN` | Assignation à des chantiers | ADMIN, MANAGER |
---
## 📈 Relations avec autres concepts
### **Dépendances directes**:
- **CHANTIER** ➡️ Un client peut avoir plusieurs chantiers
- **DEVIS** ➡️ Un client peut avoir plusieurs devis
- **FACTURE** ➡️ Un client peut avoir plusieurs factures (via chantiers)
### **Utilisé par**:
- **CHANTIER** - Chaque chantier appartient à un client
- **DEVIS** - Chaque devis est lié à un client
- **FACTURE** - Chaque facture est adressée à un client
---
## ✅ Validations
### **Validations automatiques**:
- ✅ **Nom** : Obligatoire, max 100 caractères
- ✅ **Prénom** : Obligatoire, max 100 caractères
- ✅ **Email** : Format email valide, unique
- ✅ **Téléphone** : Format français valide (regex)
- ✅ **SIRET** : 14 caractères (si renseigné)
- ✅ **Type** : PARTICULIER ou PROFESSIONNEL
### **Règles métier**:
- Un client professionnel devrait avoir un SIRET et/ou numéro TVA
- Un client particulier n'a généralement pas d'entreprise
- L'email doit être unique dans le système
- Le téléphone doit respecter le format français
---
## 🧪 Tests
### **Tests unitaires**
- Fichier: `ClientServiceTest.java`
- Couverture: Logique métier, validations, recherche
### **Tests d'intégration**
- Fichier: `ClientResourceTest.java`
- Couverture: Endpoints REST, sérialisation JSON
### **Commande pour exécuter les tests**:
```bash
cd btpxpress-server
./mvnw test -Dtest=ClientServiceTest
./mvnw test -Dtest=ClientResourceTest
```
---
## 📚 Références
- [API Documentation complète](../API.md#clients)
- [Schéma de base de données](../DATABASE.md#table-clients)
- [Guide d'architecture](../architecture/domain-model.md#client)
- [Service ClientService](../../src/main/java/dev/lions/btpxpress/application/service/ClientService.java)
- [Resource ClientResource](../../src/main/java/dev/lions/btpxpress/adapter/http/ClientResource.java)
---
**Dernière mise à jour**: 2025-09-30
**Version**: 1.0
**Auteur**: Documentation BTPXpress