Aller au contenu

Modèle de données

Cette page décrit le modèle de données par schéma PostgreSQL. Les colonnes sont en snake_case avec type et notes de contrainte ; PK = clé primaire, FK = clé étrangère, UQ = unique, chk = contrainte check.

Colonne Type Notes
id_parametre BIGINT identity PK
cle VARCHAR(50) NOT NULL UQ uq_parametre_cle
valeur VARCHAR(255) NOT NULL Valeur courante
description TEXT Optionnel

Exemples : devise, taux_tva, seuil_stock_alerte.

Référentiel client unique. Chaque module référence client.client.

Colonne Type Notes
id_client BIGINT identity PK
nom VARCHAR(100) NOT NULL Nom de famille
prenoms VARCHAR(150) NOT NULL Prénoms
date_naissance DATE Date de naissance
lieu_naissance VARCHAR(100) Lieu de naissance
sexe VARCHAR(1) Sexe
nationalite VARCHAR(100) Nationalité
profession VARCHAR(150) Profession
photo TEXT Clé de stockage objet
tel_principal VARCHAR(30) NOT NULL Téléphone principal
tel_secondaire VARCHAR(30) Téléphone secondaire
email VARCHAR(150) Email
adresse VARCHAR(255) Adresse
ville VARCHAR(100) Ville
pays VARCHAR(100) Pays
date_enregistrement TIMESTAMP NOT NULL Date d’enregistrement
type_client VARCHAR(20) NOT NULL chk LOCATAIRE / PASSAGE / AUTRE
code VARCHAR(20) NOT NULL UQ, généré automatiquement GSG-CL-NNN
Colonne Type Notes
id_piece BIGINT identity PK
id_client BIGINT NOT NULL FK → client.client
type_piece VARCHAR(20) NOT NULL chk CNI / PASSEPORT / CARTE_SEJOUR / AUTRE
numero VARCHAR(50) NOT NULL Numéro du document
date_delivrance DATE Date de délivrance
date_expiration DATE Date d’expiration
autorite_delivrance VARCHAR(100) Autorité de délivrance
copie_num TEXT Clé objet du scan recto
copie_num_verso TEXT Clé objet du scan verso

UQ (type_piece, numero).

Colonne Type Notes
id_contact BIGINT identity PK
id_client BIGINT NOT NULL FK → client.client
nom VARCHAR(100) NOT NULL Nom
prenom VARCHAR(100) Prénom
lien VARCHAR(100) NOT NULL Lien de parenté
tel_principal VARCHAR(30) NOT NULL Téléphone principal
tel_secondaire VARCHAR(30)
adresse VARCHAR(255)
email VARCHAR(150)

Bâtiments, chambres, contrats de location, échéances de loyer, dépôts, courts séjours et abonnements.

Table Éléments clés
residence.categorie_charge id_categorie_charge PK, libelle, actif
residence.batiment id_batiment PK, code UQ, nom, adresse, actif
residence.logement id_logement PK, id_batiment FK, numero, nom, type (CHAMBRE/STUDIO), tarif, equipements, statut (DISPONIBLE/RESERVE/OCCUPE/EN_NETTOYAGE/EN_MAINTENANCE/INDISPONIBLE), etat
residence.contrat_location id_contrat PK, numero_contrat UQ, id_client FK, id_logement FK, date_debut, date_fin_prevue, duree_mois, type_location (MENSUEL/ANNUEL), montant_loyer, periodicite, statut (EN_ATTENTE/ACTIF/RESILIE/TERMINE), date_signature, date_resiliation, motif_resiliation
Table Éléments clés
residence.echeance_loyer id_echeance PK, id_contrat FK, mois (1-12), annee, montant, date_echeance, statut, id_paiement FK → finances.paiement; UQ (id_contrat, mois, annee)
residence.application_paiement_echeance id_application PK, id_paiement FK → finances.paiement, id_echeance FK → residence.echeance_loyer, montant_applique > 0
residence.caution id_caution PK, id_contrat FK UQ, montant, date_versement, payee, date_restitution, montant_restitue, retenue, motif_retenue, statut
residence.historique_caution id_histo PK, id_caution FK, evenement, date, montant, motif, id_utilisateur FK, id_paiement FK
residence.abonnement id_abonnement PK, id_client FK, id_logement FK, id_categorie_abonnement FK → abonnement.categorie_abonnement, service, type, montant, date_debut, date_fin, montant_paye, statut
Table Éléments clés
residence.sejour_court id_sejour PK, type_prestation (NUITEE/SIESTE), id_client FK, id_logement FK, date_heure_arrivee, date_heure_depart_prevue, date_heure_depart_reelle, tarif, montant_total, montant_paye, reste_a_payer, id_moyen_paiement FK → finances.moyen_paiement, statut
residence.reservation_logement id_reservation PK, id_client FK, id_logement FK, date_arrivee, date_depart, nombre_nuits, acompte, statut (EN_ATTENTE/CONFIRMEE/ANNULEE/REALISEE), notes
residence.charge_facturee id_charge PK, id_logement FK, id_categorie_charge FK, periode, compteur_numero, lecture_debut, lecture_fin, consommation, montant, montant_paye, reste_a_payer, statut
Table Éléments clés
residence.revision_loyer id_revision PK, id_contrat FK, ancien_montant, nouveau_montant > 0, date_effet, motif, id_utilisateur FK, date_revision
residence.etat_des_lieux_photo Photos ENTREE/SORTIE d’un contrat, clé de stockage objet, id_utilisateur FK
Objet Rôle
residence.generer_echeances(p_id_contrat, p_jusqua) Crée les échéances mensuelles d’un contrat
residence.reviser_loyer(...) Révision de loyer atomique avec trace et re-tarification des échéances futures
residence.encaisser_loyer(...) Paiement d’une échéance unique créant un finances.paiement
residence.encaisser_loyer_lot(...) Paiement en lot : financement du dépôt → arriérés → avance
residence.statuer_echeance_paiement() Trigger : recalcule le statut d’échéance depuis les applications
residence.suivi_loyer Suivi de loyer par échéance avec total payé, dernier paiement et encaisseur
residence.releve_client Relevé client avec lignes LOYER / CHARGE / FACTURE
residence.impayes_loyers Échéances en retard/partielles avec jours de retard
residence.occupation_batiment Taux d’occupation des bâtiments et CA loyers

Catalogue produits, fournisseurs, mouvements de stock et ventes.

Table Éléments clés
market.categorie_produit id_categorie_produit PK, libelle, actif
market.fournisseur id_fournisseur PK, nom, contact, telephone, email, adresse, actif
market.produit id_produit PK, reference UQ, nom, id_categorie_produit FK, prix_achat, prix_vente, quantite_stock, seuil_alerte, id_fournisseur FK, date_entree, actif, image_url, code_barre (UQ partiel)
market.mouvement_stock id_mouvement PK, id_produit FK, type (ENTREE/SORTIE/AJUSTEMENT), quantite, date, motif, document_ref, id_utilisateur FK
market.vente id_vente PK, id_client FK nullable, date, remise, total, statut (EN_COURS/PAYEE/ANNULEE), id_utilisateur FK
market.ligne_vente id_ligne PK, id_vente FK, id_produit FK, quantite > 0, prix_unitaire, remise_ligne, total_ligne
Objet Rôle
market.solder_stock_mouvement() Trigger : met à jour produit.quantite_stock après chaque mouvement, rejette le stock négatif
market.reesolde_stock() Reconstruit tous les stocks produits depuis l’historique des mouvements
market.stock_alerte Produits avec stock ≤ seuil d’alerte
market.stock_historique Solde glissant par produit

Cycle de vie des commandes de pressing.

Table Éléments clés
pressing.commande_pressing id_commande PK, id_client FK, numero_commande UQ, date_depot, date_retrait_prevue, date_retrait_reelle, montant_total, acompte, reste_a_payer, statut (DEPOSE/EN_TRAITEMENT/PRET/RETIRE/ANNULEE)
pressing.ligne_commande_pressing id_ligne PK, id_commande FK, type_vetement, quantite > 0, prestation, tarif, total

Plats et commandes.

Table Éléments clés
restaurant.categorie_plat id_categorie_plat PK, libelle
restaurant.plat id_plat PK, nom, id_categorie_plat FK, prix, disponible, description, image_url
restaurant.commande_restaurant id_commande PK, id_client FK nullable, date, type (SUR_PLACE/A_EMPORTER/LIVRAISON), total, statut (EN_COURS/EN_PREPARATION/SERVIE/PAYEE/ANNULEE), id_utilisateur FK
restaurant.ligne_commande_restaurant id_ligne PK, id_commande FK, id_plat FK, quantite > 0, prix_unitaire, total

Réservations de salle de réception.

Table Éléments clés
salle_fete.reservation_fete id_reservation PK, id_client FK, date_evenement, heure_debut, duree > 0, type_manifestation, tarif, acompte, solde, statut (DISPONIBLE/RESERVEE/CONFIRMEE/REALISEE/ANNULEE), observations

Services et factures.

Table Éléments clés
facturation.prestation id_prestation PK, libelle, categorie, prix, description, id_activite FK, actif
facturation.facture id_facture PK, numero UQ, date, id_client FK, id_activite FK, remise, montant_total, montant_paye, reste, statut (PAYEE/PARTIELLE/IMPAYEE/ANNULEE), source_type (VENTE/COMMANDE_PRESSING/…), source_id, libelle
facturation.ligne_facture id_ligne PK, id_facture FK, libelle, quantite > 0, prix_unitaire, total

facturation.facture.source_type est polymorphe ; source_id est un BIGINT générique sans FK.

Paiements, dépenses, tiroirs-caisses, applications de paiement et consolidation.

Table Éléments clés
finances.activite id_activite PK, code UQ, libelle, actif
finances.moyen_paiement id_moyen PK, libelle, actif
finances.categorie_depense id_categorie_depense PK, libelle
Table Éléments clés
finances.paiement id_paiement PK, date, montant, id_moyen FK, id_activite FK, type (ENCAISSEMENT/DECAISSEMENT), motif, id_utilisateur FK, reference, id_caisse FK, id_periode_caisse FK
finances.depense id_depense PK, date, montant, id_categorie_depense FK, id_activite FK nullable, libelle, justificatif, id_utilisateur FK nullable, id_caisse FK, id_periode_caisse FK
Table Éléments clés
finances.application_paiement id_application PK, id_paiement FK, id_facture FK, montant_applique > 0
finances.caisse id_caisse PK, libelle, id_activite FK, actif
finances.tirage_caisse id_tirage PK, id_caisse FK, date, montant_compte, montant_attendu, ecart, id_utilisateur FK, note, date_tirage; UQ (id_caisse, date)
finances.periode_caisse id_periode PK, id_caisse FK, ouverture, fermeture, id_utilisateur_ouverture FK, id_utilisateur_fermeture FK; UQ partiel (id_caisse) où fermeture IS NULL
Objet Rôle
finances.solder_facture_application() Trigger : recalcule facture.montant_paye, reste, statut à l’application d’un paiement
finances.ca_par_activite Encaissements, décaissements, dépenses et net par activité (correctif de démultiplication)
finances.tableau_de_bord Tableau de bord financier et de facturation mensuel

Employés, présences et paie.

Table Éléments clés
rh.service_rh id_service PK, libelle
rh.employe id_employe PK, nom, prenom, telephone, fonction (chk liste restreinte), id_service FK, date_embauche, type_contrat, salaire_base, statut, autres_infos
rh.pointage id_pointage PK, id_employe FK, date, heure_arrivee, heure_depart, duree_travaillee, statut, heures_sup, note; UQ (id_employe, date)
rh.paie id_paie PK, id_employe FK, periode, salaire_base, total_elements, total_retenues, montant_a_payer, statut, id_paiement FK → finances.paiement UQ
rh.element_salaire id_element PK, id_paie FK, type (PRIME/AVANCE/RETENUE/HEURE_SUP/AUTRE), libelle, montant signé
Objet Rôle
rh.pointer_heure_arrivee() Trigger : remplit heure_arrivee et calcule duree_travaillee
rh.recalculer_paie(p_id_paie) Recalcule total_elements, total_retenues, montant_a_payer ; ignore PAYEE/ANNULEE
rh.recalculer_paie_elements() Trigger : recalcule le bulletin quand un élément change

Catalogue des catégories d’abonnement.

Table Éléments clés
abonnement.categorie_abonnement id_categorie_abonnement PK, code UQ, libelle, description, actif, date_creation, date_modification, prix_defaut

Catégories seedées : RESTAURANT, PRESSING, SALLE_FETE, INTERNET, TV.

Utilisateurs, rôles, permissions, jetons et métadonnées de sauvegarde. Voir la page sécurité pour le détail.

Table Rôle
admin.role Catalogue des rôles
admin.permission Catalogue des permissions atomiques
admin.role_permission Liens N:N rôle/permission
admin.utilisateur Comptes utilisateurs
admin.refresh_token Hachages de refresh tokens
admin.password_reset_token Hachages de jetons de réinitialisation
admin.sauvegarde Journal des sauvegardes
admin.sauvegarde_planification Planification de sauvegarde singleton

Voir la page sécurité pour le détail.

Table Rôle
audit.journal_audit Journal d’opérations en ajout seul
client.client
├── residence.contrat_location.id_client
├── residence.abonnement.id_client
├── residence.sejour_court.id_client
├── residence.reservation_logement.id_client
├── pressing.commande_pressing.id_client
├── salle_fete.reservation_fete.id_client
├── market.vente.id_client
├── restaurant.commande_restaurant.id_client
└── facturation.facture.id_client
finances.paiement
├── residence.echeance_loyer.id_paiement (legacy)
├── residence.application_paiement_echeance.id_paiement
├── residence.historique_caution.id_paiement
└── rh.paie.id_paiement
facturation.facture
├── finances.application_paiement.id_facture
└── finances.tableau_de_bord (dashboard)
admin.utilisateur
├── admin.role.id_role
├── finances.activite.id_activite_scope
├── finances.caisse.id_caisse
├── rh.employe.id_employe
└── client.client.id_client

Insérer un client, un contrat et une échéance de loyer

Section intitulée « Insérer un client, un contrat et une échéance de loyer »
-- 1. Créer le client
INSERT INTO client.client (nom, prenoms, tel_principal, type_client)
VALUES ('Kouassi', 'Yao Blé Jean', '0123456789', 'LOCATAIRE')
RETURNING id_client;
-- 2. Créer un contrat de location (en supposant que le logement 1 existe)
INSERT INTO residence.contrat_location (
numero_contrat, id_client, id_logement, date_debut, date_fin_prevue,
duree_mois, type_location, montant_loyer, periodicite, statut, date_signature
)
VALUES ('CTR-2026-001', 1, 1, '2026-09-01', '2027-08-31',
12, 'MENSUEL', 65000, 1, 'ACTIF', '2026-09-01')
RETURNING id_contrat;
-- 3. Générer les échéances mensuelles du contrat
SELECT residence.generer_echeances(1);
-- 1. Créer le paiement dans finances
INSERT INTO finances.paiement (
date, montant, id_moyen, id_activite, type, motif, id_utilisateur, reference
)
VALUES (
now(), 65000, 1,
(SELECT id_activite FROM finances.activite WHERE code = 'LOCATION_RESIDENTIEL'),
'ENCAISSEMENT', 'Loyer septembre 2026 CTR-2026-001', 1, 'LOYER-CTR-2026-001-9-2026'
)
RETURNING id_paiement;
-- 2. Lier le paiement à l'échéance de loyer
UPDATE residence.echeance_loyer
SET id_paiement = 1
WHERE id_echeance = 1;
-- Le trigger statuer_echeance_paiement met à jour statut en PAYE ou PARTIEL.
-- Loyer total encaissé vs attendu par bâtiment ce mois-ci
SELECT
b.code,
b.nom,
count(l.id_logement) AS logements,
count(*) FILTER (WHERE l.statut = 'OCCUPE') AS occupes,
sum(e.montant) FILTER (WHERE e.statut = 'PAYE') AS encaisse,
sum(e.montant) FILTER (WHERE e.statut IN ('A_VENIR', 'IMPAYE', 'PARTIEL')) AS attendu
FROM residence.batiment b
LEFT JOIN residence.logement l ON l.id_batiment = b.id_batiment
LEFT JOIN residence.contrat_location c
ON c.id_logement = l.id_logement AND c.statut = 'ACTIF'
LEFT JOIN residence.echeance_loyer e
ON e.id_contrat = c.id_contrat
AND e.mois = 9 AND e.annee = 2026
GROUP BY b.id_batiment, b.code, b.nom;
-- Après création d'un paiement, insérer une ligne d'application par facture.
INSERT INTO finances.application_paiement (id_paiement, id_facture, montant_applique)
VALUES (1, 42, 60000);
-- Le trigger finances.solder_facture_application met à jour :
-- facturation.facture.montant_paye, reste, statut
-- Enregistrer une livraison entrante de 50 unités du produit 1
INSERT INTO market.mouvement_stock (
id_produit, type, quantite, date, motif, document_ref, id_utilisateur
)
VALUES (1, 'ENTREE', 50, now(), 'Réception fournisseur', 'BL-2026-001', 1);
-- Enregistrer une vente qui décrémente le stock
INSERT INTO market.mouvement_stock (
id_produit, type, quantite, date, motif, document_ref, id_utilisateur
)
VALUES (1, 'SORTIE', 5, now(), 'Vente client', 'VTE-2026-001', 1);
-- Ajouter une prime à un bulletin
INSERT INTO rh.element_salaire (id_paie, type, libelle, montant)
VALUES (10, 'PRIME', 'Prime de performance', 15000);
-- Le trigger recalcule rh.paie.total_elements et montant_a_payer
-- automatiquement.
Anti-patron Approche correcte
UPDATE residence.contrat_location SET montant_loyer = 70000 Utiliser residence.reviser_loyer(...) pour que la révision soit tracée
INSERT INTO residence.echeance_loyer manuellement pour chaque mois Utiliser residence.generer_echeances(id_contrat)
UPDATE facturation.facture SET statut = 'PAYEE' directement Insérer un finances.paiement et une application_paiement ; laisser le trigger mettre à jour le statut
UPDATE rh.paie SET montant_a_payer = ... à la main Utiliser rh.element_salaire et laisser le trigger recalculer
DELETE FROM audit.journal_audit La table d’audit est en ajout seul ; la suppression viole R15