Initial commit
This commit is contained in:
421
DATABASE.md
Normal file
421
DATABASE.md
Normal file
@@ -0,0 +1,421 @@
|
||||
# 🗄️ BASE DE DONNÉES - BTPXPRESS
|
||||
|
||||
## 📋 Table des matières
|
||||
|
||||
- [Vue d'ensemble](#vue-densemble)
|
||||
- [Configuration](#configuration)
|
||||
- [Schéma de base de données](#schéma-de-base-de-données)
|
||||
- [Tables principales](#tables-principales)
|
||||
- [Migrations](#migrations)
|
||||
- [Indexation](#indexation)
|
||||
- [Sauvegarde et restauration](#sauvegarde-et-restauration)
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Vue d'ensemble
|
||||
|
||||
### **Technologie**
|
||||
|
||||
- **SGBD** : PostgreSQL 15
|
||||
- **ORM** : Hibernate ORM Panache
|
||||
- **Migrations** : Flyway (optionnel)
|
||||
- **Pool de connexions** : Agroal
|
||||
|
||||
### **Bases de données**
|
||||
|
||||
| Environnement | Nom de la base | Utilisateur | Port |
|
||||
|---------------|----------------|-------------|------|
|
||||
| **Développement** | `btpxpress_dev` | `btpxpress` | 5432 |
|
||||
| **Test** | `btpxpress_test` | `btpxpress_test` | 5432 |
|
||||
| **Production** | `btpxpress_prod` | `btpxpress_prod` | 5432 |
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Configuration
|
||||
|
||||
### **application.properties**
|
||||
|
||||
```properties
|
||||
# Datasource
|
||||
quarkus.datasource.db-kind=postgresql
|
||||
quarkus.datasource.username=btpxpress
|
||||
quarkus.datasource.password=btpxpress123
|
||||
quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/btpxpress_dev
|
||||
|
||||
# Hibernate
|
||||
quarkus.hibernate-orm.database.generation=update
|
||||
quarkus.hibernate-orm.log.sql=true
|
||||
quarkus.hibernate-orm.sql-load-script=import.sql
|
||||
|
||||
# Pool de connexions
|
||||
quarkus.datasource.jdbc.min-size=5
|
||||
quarkus.datasource.jdbc.max-size=20
|
||||
```
|
||||
|
||||
### **Docker Compose**
|
||||
|
||||
```yaml
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:15-alpine
|
||||
environment:
|
||||
POSTGRES_DB: btpxpress_dev
|
||||
POSTGRES_USER: btpxpress
|
||||
POSTGRES_PASSWORD: btpxpress123
|
||||
ports:
|
||||
- "5432:5432"
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Schéma de base de données
|
||||
|
||||
### **Diagramme ERD simplifié**
|
||||
|
||||
```
|
||||
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
||||
│ CLIENT │──────<│ CHANTIER │>──────│ DEVIS │
|
||||
└─────────────┘ └─────────────┘ └─────────────┘
|
||||
│
|
||||
│
|
||||
┌─────▼─────┐
|
||||
│ MATERIEL │
|
||||
└─────┬─────┘
|
||||
│
|
||||
┌─────▼─────────┐
|
||||
│ RESERVATION │
|
||||
└───────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📋 Tables principales
|
||||
|
||||
### **1. Table `clients`**
|
||||
|
||||
```sql
|
||||
CREATE TABLE clients (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
nom VARCHAR(100) NOT NULL,
|
||||
prenom VARCHAR(100),
|
||||
entreprise VARCHAR(200),
|
||||
email VARCHAR(100) UNIQUE NOT NULL,
|
||||
telephone VARCHAR(20),
|
||||
adresse VARCHAR(200),
|
||||
code_postal VARCHAR(10),
|
||||
ville VARCHAR(100),
|
||||
type VARCHAR(20) NOT NULL, -- PARTICULIER, PROFESSIONNEL
|
||||
siret VARCHAR(14),
|
||||
numero_tva VARCHAR(15),
|
||||
actif BOOLEAN DEFAULT TRUE,
|
||||
date_creation TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
date_modification TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX idx_clients_email ON clients(email);
|
||||
CREATE INDEX idx_clients_type ON clients(type);
|
||||
```
|
||||
|
||||
### **2. Table `chantiers`**
|
||||
|
||||
```sql
|
||||
CREATE TABLE chantiers (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
nom VARCHAR(200) NOT NULL,
|
||||
code VARCHAR(50) UNIQUE NOT NULL,
|
||||
description TEXT,
|
||||
adresse VARCHAR(200),
|
||||
code_postal VARCHAR(10),
|
||||
ville VARCHAR(100),
|
||||
client_id UUID NOT NULL REFERENCES clients(id),
|
||||
statut VARCHAR(20) NOT NULL, -- PLANIFIE, EN_COURS, TERMINE, ANNULE, SUSPENDU
|
||||
date_debut DATE,
|
||||
date_fin_prevue DATE,
|
||||
date_fin_reelle DATE,
|
||||
montant_prevu DECIMAL(12,2),
|
||||
montant_reel DECIMAL(12,2),
|
||||
surface_m2 DECIMAL(10,2),
|
||||
actif BOOLEAN DEFAULT TRUE,
|
||||
date_creation TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
date_modification TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX idx_chantiers_client ON chantiers(client_id);
|
||||
CREATE INDEX idx_chantiers_statut ON chantiers(statut);
|
||||
CREATE INDEX idx_chantiers_code ON chantiers(code);
|
||||
```
|
||||
|
||||
### **3. Table `materiels`**
|
||||
|
||||
```sql
|
||||
CREATE TABLE materiels (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
nom VARCHAR(100) NOT NULL,
|
||||
marque VARCHAR(100),
|
||||
modele VARCHAR(100),
|
||||
numero_serie VARCHAR(100) UNIQUE,
|
||||
type VARCHAR(50) NOT NULL, -- VEHICULE, OUTIL_ELECTRIQUE, etc.
|
||||
description TEXT,
|
||||
date_achat DATE,
|
||||
valeur_achat DECIMAL(10,2),
|
||||
valeur_actuelle DECIMAL(10,2),
|
||||
statut VARCHAR(20) NOT NULL DEFAULT 'DISPONIBLE',
|
||||
localisation VARCHAR(200),
|
||||
proprietaire VARCHAR(200),
|
||||
cout_utilisation DECIMAL(10,2),
|
||||
quantite_stock DECIMAL(10,3) DEFAULT 0,
|
||||
seuil_minimum DECIMAL(10,3) DEFAULT 0,
|
||||
unite VARCHAR(20),
|
||||
actif BOOLEAN DEFAULT TRUE,
|
||||
date_creation TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
date_modification TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX idx_materiels_type ON materiels(type);
|
||||
CREATE INDEX idx_materiels_statut ON materiels(statut);
|
||||
CREATE INDEX idx_materiels_numero_serie ON materiels(numero_serie);
|
||||
```
|
||||
|
||||
### **4. Table `reservations_materiel`**
|
||||
|
||||
```sql
|
||||
CREATE TABLE reservations_materiel (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
materiel_id UUID NOT NULL REFERENCES materiels(id),
|
||||
chantier_id UUID NOT NULL REFERENCES chantiers(id),
|
||||
date_debut DATE NOT NULL,
|
||||
date_fin DATE NOT NULL,
|
||||
statut VARCHAR(20) NOT NULL DEFAULT 'PLANIFIEE',
|
||||
quantite DECIMAL(10,3),
|
||||
priorite VARCHAR(20),
|
||||
commentaire TEXT,
|
||||
date_creation TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
date_modification TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX idx_reservations_materiel ON reservations_materiel(materiel_id);
|
||||
CREATE INDEX idx_reservations_chantier ON reservations_materiel(chantier_id);
|
||||
CREATE INDEX idx_reservations_dates ON reservations_materiel(date_debut, date_fin);
|
||||
```
|
||||
|
||||
### **5. Table `employes`**
|
||||
|
||||
```sql
|
||||
CREATE TABLE employes (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
nom VARCHAR(100) NOT NULL,
|
||||
prenom VARCHAR(100) NOT NULL,
|
||||
email VARCHAR(100) UNIQUE,
|
||||
telephone VARCHAR(20),
|
||||
fonction VARCHAR(50), -- CHEF_CHANTIER, MACON, ELECTRICIEN, etc.
|
||||
statut VARCHAR(20) DEFAULT 'ACTIF',
|
||||
date_embauche DATE,
|
||||
taux_horaire DECIMAL(10,2),
|
||||
equipe_id UUID REFERENCES equipes(id),
|
||||
actif BOOLEAN DEFAULT TRUE,
|
||||
date_creation TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
date_modification TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX idx_employes_fonction ON employes(fonction);
|
||||
CREATE INDEX idx_employes_statut ON employes(statut);
|
||||
CREATE INDEX idx_employes_equipe ON employes(equipe_id);
|
||||
```
|
||||
|
||||
### **6. Table `devis`**
|
||||
|
||||
```sql
|
||||
CREATE TABLE devis (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
numero VARCHAR(50) UNIQUE NOT NULL,
|
||||
client_id UUID NOT NULL REFERENCES clients(id),
|
||||
chantier_id UUID REFERENCES chantiers(id),
|
||||
date_emission DATE NOT NULL,
|
||||
date_validite DATE,
|
||||
statut VARCHAR(20) NOT NULL DEFAULT 'BROUILLON',
|
||||
montant_ht DECIMAL(10,2) DEFAULT 0,
|
||||
montant_tva DECIMAL(10,2) DEFAULT 0,
|
||||
montant_ttc DECIMAL(10,2) DEFAULT 0,
|
||||
taux_tva DECIMAL(5,2) DEFAULT 20.00,
|
||||
commentaire TEXT,
|
||||
date_creation TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
date_modification TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX idx_devis_client ON devis(client_id);
|
||||
CREATE INDEX idx_devis_chantier ON devis(chantier_id);
|
||||
CREATE INDEX idx_devis_numero ON devis(numero);
|
||||
CREATE INDEX idx_devis_statut ON devis(statut);
|
||||
```
|
||||
|
||||
### **7. Table `users`**
|
||||
|
||||
```sql
|
||||
CREATE TABLE users (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
keycloak_id VARCHAR(100) UNIQUE,
|
||||
username VARCHAR(100) UNIQUE NOT NULL,
|
||||
email VARCHAR(100) UNIQUE NOT NULL,
|
||||
nom VARCHAR(100),
|
||||
prenom VARCHAR(100),
|
||||
role VARCHAR(50), -- ADMIN, MANAGER, CHEF_CHANTIER, etc.
|
||||
status VARCHAR(20) DEFAULT 'ACTIVE',
|
||||
employe_id UUID REFERENCES employes(id),
|
||||
date_creation TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
date_modification TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX idx_users_keycloak ON users(keycloak_id);
|
||||
CREATE INDEX idx_users_username ON users(username);
|
||||
CREATE INDEX idx_users_email ON users(email);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Migrations
|
||||
|
||||
### **Flyway (optionnel)**
|
||||
|
||||
Structure des migrations :
|
||||
|
||||
```
|
||||
src/main/resources/db/migration/
|
||||
├── V1__create_clients_table.sql
|
||||
├── V2__create_chantiers_table.sql
|
||||
├── V3__create_materiels_table.sql
|
||||
├── V4__create_reservations_table.sql
|
||||
└── V5__create_indexes.sql
|
||||
```
|
||||
|
||||
### **Commandes**
|
||||
|
||||
```bash
|
||||
# Appliquer les migrations
|
||||
./mvnw flyway:migrate
|
||||
|
||||
# Voir l'état des migrations
|
||||
./mvnw flyway:info
|
||||
|
||||
# Nettoyer la base (ATTENTION : supprime toutes les données)
|
||||
./mvnw flyway:clean
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Indexation
|
||||
|
||||
### **Index recommandés**
|
||||
|
||||
```sql
|
||||
-- Recherche par email
|
||||
CREATE INDEX idx_clients_email ON clients(email);
|
||||
|
||||
-- Recherche par statut
|
||||
CREATE INDEX idx_chantiers_statut ON chantiers(statut);
|
||||
CREATE INDEX idx_materiels_statut ON materiels(statut);
|
||||
|
||||
-- Recherche par dates
|
||||
CREATE INDEX idx_reservations_dates ON reservations_materiel(date_debut, date_fin);
|
||||
|
||||
-- Recherche full-text (PostgreSQL)
|
||||
CREATE INDEX idx_chantiers_search ON chantiers USING gin(to_tsvector('french', nom || ' ' || COALESCE(description, '')));
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💾 Sauvegarde et restauration
|
||||
|
||||
### **Sauvegarde**
|
||||
|
||||
```bash
|
||||
# Sauvegarde complète
|
||||
pg_dump -U btpxpress -h localhost btpxpress_dev > backup_$(date +%Y%m%d).sql
|
||||
|
||||
# Sauvegarde avec compression
|
||||
pg_dump -U btpxpress -h localhost btpxpress_dev | gzip > backup_$(date +%Y%m%d).sql.gz
|
||||
```
|
||||
|
||||
### **Restauration**
|
||||
|
||||
```bash
|
||||
# Restauration
|
||||
psql -U btpxpress -h localhost btpxpress_dev < backup_20250930.sql
|
||||
|
||||
# Restauration depuis fichier compressé
|
||||
gunzip -c backup_20250930.sql.gz | psql -U btpxpress -h localhost btpxpress_dev
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Statistiques
|
||||
|
||||
### **Nombre de tables par concept**
|
||||
|
||||
| Concept | Tables | Importance |
|
||||
|---------|--------|------------|
|
||||
| CHANTIER | 3 | ⭐⭐⭐⭐⭐ |
|
||||
| MATERIEL | 12 | ⭐⭐⭐⭐⭐ |
|
||||
| CLIENT | 1 | ⭐⭐⭐⭐ |
|
||||
| EMPLOYE | 6 | ⭐⭐⭐⭐ |
|
||||
| DEVIS | 2 | ⭐⭐⭐⭐ |
|
||||
| PLANNING | 7 | ⭐⭐⭐⭐ |
|
||||
| **TOTAL** | **95+** | - |
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Requêtes utiles
|
||||
|
||||
### **Statistiques chantiers**
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
statut,
|
||||
COUNT(*) as nombre,
|
||||
SUM(montant_prevu) as montant_total
|
||||
FROM chantiers
|
||||
WHERE actif = TRUE
|
||||
GROUP BY statut;
|
||||
```
|
||||
|
||||
### **Matériel en stock faible**
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
nom,
|
||||
quantite_stock,
|
||||
seuil_minimum,
|
||||
(quantite_stock - seuil_minimum) as ecart
|
||||
FROM materiels
|
||||
WHERE quantite_stock < seuil_minimum
|
||||
AND actif = TRUE
|
||||
ORDER BY ecart ASC;
|
||||
```
|
||||
|
||||
### **Réservations en conflit**
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
r1.id as reservation1,
|
||||
r2.id as reservation2,
|
||||
m.nom as materiel,
|
||||
r1.date_debut,
|
||||
r1.date_fin
|
||||
FROM reservations_materiel r1
|
||||
JOIN reservations_materiel r2 ON r1.materiel_id = r2.materiel_id
|
||||
JOIN materiels m ON r1.materiel_id = m.id
|
||||
WHERE r1.id < r2.id
|
||||
AND r1.date_debut <= r2.date_fin
|
||||
AND r1.date_fin >= r2.date_debut;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour**: 2025-09-30
|
||||
**Version**: 1.0
|
||||
**Auteur**: Équipe BTPXpress
|
||||
|
||||
Reference in New Issue
Block a user