# πŸ—„οΈ 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