-- ============================================================================
-- UnionFlow - Schema Complet et Définitif
-- ============================================================================
-- Auteur: Lions Dev
-- Date: 2026-03-16
-- Version: 1.0 (Consolidation finale)
-- Description: Schema complet de la base de données UnionFlow avec toutes les
--              tables, index, contraintes et commentaires.
--              Tous les noms de tables correspondent exactement aux entités JPA.
-- ============================================================================
-- IMPORTANT: Ce fichier consolide les anciennes migrations V1 à V10.
--            Les noms de tables sont corrects dès le départ.
--            69 entités JPA = 69 tables (100% correspondance).
-- ============================================================================

-- Colonnes communes BaseEntity (à inclure dans chaque table)
-- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
-- date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
-- date_modification TIMESTAMP,
-- cree_par VARCHAR(255),
-- modifie_par VARCHAR(255),
-- version BIGINT DEFAULT 0,
-- actif BOOLEAN NOT NULL DEFAULT TRUE

-- ============================================================================
-- 1. TABLES PRINCIPALES (sans FK vers d'autres tables métier)
-- ============================================================================

-- Table utilisateurs (entité: Membre) - NOM CORRIGÉ dès le départ
CREATE TABLE IF NOT EXISTS utilisateurs (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    nom VARCHAR(100) NOT NULL,
    prenom VARCHAR(100) NOT NULL,
    email VARCHAR(255),
    telephone VARCHAR(30),
    numero_membre VARCHAR(50),
    date_naissance DATE,
    lieu_naissance VARCHAR(255),
    sexe VARCHAR(10),
    nationalite VARCHAR(100),
    profession VARCHAR(255),
    photo_url VARCHAR(500),
    statut VARCHAR(30) DEFAULT 'ACTIF',
    date_adhesion DATE,
    keycloak_user_id VARCHAR(255),
    keycloak_realm VARCHAR(255),
    organisation_id UUID,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    cree_par VARCHAR(255),
    modifie_par VARCHAR(255),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

CREATE INDEX idx_utilisateurs_email ON utilisateurs(email);
CREATE INDEX idx_utilisateurs_numero_membre ON utilisateurs(numero_membre);
CREATE INDEX idx_utilisateurs_organisation ON utilisateurs(organisation_id);
CREATE INDEX idx_utilisateurs_keycloak ON utilisateurs(keycloak_user_id);
CREATE INDEX idx_utilisateurs_statut ON utilisateurs(statut);

-- Table organisations
CREATE TABLE IF NOT EXISTS organisations (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    nom VARCHAR(200) NOT NULL,
    nom_court VARCHAR(50),
    type_organisation VARCHAR(50) NOT NULL DEFAULT 'ASSOCIATION',
    statut VARCHAR(50) NOT NULL DEFAULT 'ACTIVE',
    description TEXT,
    date_fondation DATE,
    numero_enregistrement VARCHAR(100) UNIQUE,
    email VARCHAR(255) NOT NULL UNIQUE,
    telephone VARCHAR(20),
    telephone_secondaire VARCHAR(20),
    email_secondaire VARCHAR(255),
    adresse VARCHAR(500),
    ville VARCHAR(100),
    code_postal VARCHAR(20),
    region VARCHAR(100),
    pays VARCHAR(100),
    latitude DECIMAL(9,6) CHECK (latitude >= -90 AND latitude <= 90),
    longitude DECIMAL(9,6) CHECK (longitude >= -180 AND longitude <= 180),
    site_web VARCHAR(500),
    logo VARCHAR(500),
    reseaux_sociaux VARCHAR(1000),
    organisation_parente_id UUID,
    niveau_hierarchique INTEGER NOT NULL DEFAULT 0,
    nombre_membres INTEGER NOT NULL DEFAULT 0,
    nombre_administrateurs INTEGER NOT NULL DEFAULT 0,
    budget_annuel DECIMAL(14,2) CHECK (budget_annuel >= 0),
    devise VARCHAR(3) DEFAULT 'XOF',
    cotisation_obligatoire BOOLEAN NOT NULL DEFAULT FALSE,
    montant_cotisation_annuelle DECIMAL(12,2) CHECK (montant_cotisation_annuelle >= 0),
    objectifs TEXT,
    activites_principales TEXT,
    certifications VARCHAR(500),
    partenaires VARCHAR(1000),
    notes VARCHAR(1000),
    organisation_publique BOOLEAN NOT NULL DEFAULT TRUE,
    accepte_nouveaux_membres BOOLEAN NOT NULL DEFAULT TRUE,
    actif BOOLEAN NOT NULL DEFAULT TRUE,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    cree_par VARCHAR(255),
    modifie_par VARCHAR(255),
    version BIGINT DEFAULT 0,

    CONSTRAINT chk_organisation_statut CHECK (statut IN ('ACTIVE', 'SUSPENDUE', 'DISSOUTE', 'EN_ATTENTE')),
    CONSTRAINT chk_organisation_type CHECK (type_organisation IN (
        'ASSOCIATION', 'LIONS_CLUB', 'ROTARY_CLUB', 'COOPERATIVE',
        'FONDATION', 'ONG', 'SYNDICAT', 'AUTRE'
    )),
    CONSTRAINT chk_organisation_devise CHECK (devise IN ('XOF', 'EUR', 'USD', 'GBP', 'CHF')),
    CONSTRAINT chk_organisation_niveau CHECK (niveau_hierarchique >= 0 AND niveau_hierarchique <= 10),
    CONSTRAINT chk_organisation_membres CHECK (nombre_membres >= 0),
    CONSTRAINT chk_organisation_admins CHECK (nombre_administrateurs >= 0),
    CONSTRAINT fk_organisation_parente FOREIGN KEY (organisation_parente_id)
        REFERENCES organisations(id) ON DELETE SET NULL
);

CREATE INDEX idx_organisation_nom ON organisations(nom);
CREATE INDEX idx_organisation_email ON organisations(email);
CREATE INDEX idx_organisation_statut ON organisations(statut);
CREATE INDEX idx_organisation_type ON organisations(type_organisation);
CREATE INDEX idx_organisation_ville ON organisations(ville);
CREATE INDEX idx_organisation_pays ON organisations(pays);
CREATE INDEX idx_organisation_parente ON organisations(organisation_parente_id);

-- Table roles
CREATE TABLE IF NOT EXISTS roles (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    nom VARCHAR(100) NOT NULL UNIQUE,
    description VARCHAR(500),
    niveau_acces INTEGER DEFAULT 0,
    est_systeme BOOLEAN DEFAULT FALSE,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    cree_par VARCHAR(255),
    modifie_par VARCHAR(255),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table permissions (NOM CORRIGÉ dès le départ)
CREATE TABLE IF NOT EXISTS permissions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    code VARCHAR(100) NOT NULL UNIQUE,
    module VARCHAR(50) NOT NULL,
    ressource VARCHAR(50) NOT NULL,
    action VARCHAR(50) NOT NULL,
    libelle VARCHAR(200),
    description VARCHAR(500),
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    cree_par VARCHAR(255),
    modifie_par VARCHAR(255),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table roles_permissions (NOM CORRIGÉ dès le départ)
CREATE TABLE IF NOT EXISTS roles_permissions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    role_id UUID NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
    permission_id UUID NOT NULL REFERENCES permissions(id) ON DELETE CASCADE,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    actif BOOLEAN NOT NULL DEFAULT TRUE,
    CONSTRAINT uk_role_permission UNIQUE (role_id, permission_id)
);

-- Table membres_roles (NOM CORRIGÉ dès le départ)
CREATE TABLE IF NOT EXISTS membres_roles (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    membre_id UUID NOT NULL REFERENCES utilisateurs(id) ON DELETE CASCADE,
    role_id UUID NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
    date_attribution DATE DEFAULT CURRENT_DATE,
    date_expiration DATE,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    actif BOOLEAN NOT NULL DEFAULT TRUE,
    CONSTRAINT uk_membre_role UNIQUE (membre_id, role_id)
);

-- Table membres_organisations (NOM CORRIGÉ dès le départ)
CREATE TABLE IF NOT EXISTS membres_organisations (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    membre_id UUID NOT NULL REFERENCES utilisateurs(id) ON DELETE CASCADE,
    organisation_id UUID NOT NULL REFERENCES organisations(id) ON DELETE CASCADE,
    fonction VARCHAR(100),
    date_entree DATE,
    date_sortie DATE,
    statut VARCHAR(30) DEFAULT 'ACTIF',
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    cree_par VARCHAR(255),
    modifie_par VARCHAR(255),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE,
    CONSTRAINT uk_membre_organisation UNIQUE (membre_id, organisation_id)
);

-- ============================================================================
-- 2. TABLES CONFIGURATION
-- ============================================================================

-- Table configurations (NOM CORRIGÉ dès le départ)
CREATE TABLE IF NOT EXISTS configurations (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    cle VARCHAR(255) NOT NULL UNIQUE,
    valeur TEXT,
    type VARCHAR(50),
    categorie VARCHAR(50),
    description VARCHAR(1000),
    modifiable BOOLEAN DEFAULT TRUE,
    visible BOOLEAN DEFAULT TRUE,
    metadonnees TEXT,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    cree_par VARCHAR(255),
    modifie_par VARCHAR(255),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

CREATE INDEX idx_config_cle ON configurations(cle);
CREATE INDEX idx_config_categorie ON configurations(categorie);

-- Table configurations_wave (NOM CORRIGÉ dès le départ)
CREATE TABLE IF NOT EXISTS configurations_wave (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    organisation_id UUID REFERENCES organisations(id) ON DELETE CASCADE,
    api_key_encrypted VARCHAR(500),
    api_secret_encrypted VARCHAR(500),
    callback_url VARCHAR(500),
    webhook_url VARCHAR(500),
    mode VARCHAR(20) DEFAULT 'TEST',
    actif BOOLEAN DEFAULT TRUE,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    cree_par VARCHAR(255),
    modifie_par VARCHAR(255),
    version BIGINT DEFAULT 0
);

-- ============================================================================
-- 3. TABLES FINANCE
-- ============================================================================

-- Table cotisations
CREATE TABLE IF NOT EXISTS cotisations (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    numero_reference VARCHAR(50) UNIQUE NOT NULL,
    membre_id UUID NOT NULL REFERENCES utilisateurs(id) ON DELETE CASCADE,
    organisation_id UUID REFERENCES organisations(id) ON DELETE CASCADE,
    type_cotisation VARCHAR(50) NOT NULL,
    libelle VARCHAR(255),
    montant_du DECIMAL(12,2) NOT NULL CHECK (montant_du >= 0),
    montant_paye DECIMAL(12,2) NOT NULL DEFAULT 0 CHECK (montant_paye >= 0),
    code_devise VARCHAR(3) NOT NULL DEFAULT 'XOF',
    statut VARCHAR(30) NOT NULL,
    date_echeance DATE NOT NULL,
    date_paiement TIMESTAMP,
    periode VARCHAR(20),
    annee INTEGER NOT NULL CHECK (annee >= 2020 AND annee <= 2100),
    mois INTEGER CHECK (mois >= 1 AND mois <= 12),
    recurrente BOOLEAN NOT NULL DEFAULT FALSE,
    nombre_rappels INTEGER NOT NULL DEFAULT 0,
    date_dernier_rappel TIMESTAMP,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    cree_par VARCHAR(255),
    modifie_par VARCHAR(255),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE,

    CONSTRAINT chk_cotisation_statut CHECK (statut IN ('EN_ATTENTE', 'PAYEE', 'EN_RETARD', 'PARTIELLEMENT_PAYEE', 'ANNULEE'))
);

CREATE INDEX idx_cotisation_membre ON cotisations(membre_id);
CREATE INDEX idx_cotisation_statut ON cotisations(statut);
CREATE INDEX idx_cotisation_annee ON cotisations(annee);

-- Table paiements
CREATE TABLE IF NOT EXISTS paiements (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    numero_transaction VARCHAR(100) UNIQUE NOT NULL,
    membre_id UUID REFERENCES utilisateurs(id),
    montant DECIMAL(12,2) NOT NULL CHECK (montant >= 0),
    code_devise VARCHAR(3) NOT NULL DEFAULT 'XOF',
    type_paiement VARCHAR(50) NOT NULL,
    methode_paiement VARCHAR(50),
    statut VARCHAR(30) NOT NULL,
    date_paiement TIMESTAMP DEFAULT NOW(),
    reference_externe VARCHAR(255),
    description VARCHAR(500),
    metadata TEXT,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    cree_par VARCHAR(255),
    modifie_par VARCHAR(255),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table paiements_objets (liaison paiement -> objet métier)
CREATE TABLE IF NOT EXISTS paiements_objets (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    paiement_id UUID NOT NULL REFERENCES paiements(id) ON DELETE CASCADE,
    objet_type VARCHAR(50) NOT NULL,
    objet_id UUID NOT NULL,
    montant_alloue DECIMAL(12,2) CHECK (montant_alloue >= 0),
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table intentions_paiement (NOM CORRIGÉ dès le départ)
CREATE TABLE IF NOT EXISTS intentions_paiement (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    numero_intention VARCHAR(100) UNIQUE NOT NULL,
    membre_id UUID NOT NULL REFERENCES utilisateurs(id),
    montant DECIMAL(12,2) NOT NULL CHECK (montant >= 0),
    code_devise VARCHAR(3) DEFAULT 'XOF',
    type_objet VARCHAR(50) NOT NULL,
    objet_id UUID,
    statut VARCHAR(30) DEFAULT 'EN_ATTENTE',
    methode_paiement VARCHAR(50),
    url_callback VARCHAR(500),
    url_retour VARCHAR(500),
    date_expiration TIMESTAMP,
    metadata TEXT,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    cree_par VARCHAR(255),
    modifie_par VARCHAR(255),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE,

    CONSTRAINT chk_intention_type_objet CHECK (type_objet IN (
        'COTISATION', 'ADHESION', 'EVENEMENT', 'AIDE',
        'DEPOT_EPARGNE', 'REMBOURSEMENT_CREDIT', 'DON', 'AUTRE'
    ))
);

-- ============================================================================
-- 4. TABLES MUTUELLES (Épargne & Crédit)
-- ============================================================================

-- Table comptes_epargne
CREATE TABLE IF NOT EXISTS comptes_epargne (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    numero_compte VARCHAR(50) UNIQUE NOT NULL,
    membre_id UUID NOT NULL REFERENCES utilisateurs(id),
    organisation_id UUID REFERENCES organisations(id),
    solde DECIMAL(14,2) NOT NULL DEFAULT 0,
    code_devise VARCHAR(3) DEFAULT 'XOF',
    taux_interet DECIMAL(5,2) DEFAULT 0,
    statut VARCHAR(30) DEFAULT 'ACTIF',
    date_ouverture DATE DEFAULT CURRENT_DATE,
    date_fermeture DATE,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    cree_par VARCHAR(255),
    modifie_par VARCHAR(255),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table transactions_epargne
CREATE TABLE IF NOT EXISTS transactions_epargne (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    compte_id UUID NOT NULL REFERENCES comptes_epargne(id),
    type_transaction VARCHAR(30) NOT NULL,
    montant DECIMAL(14,2) NOT NULL,
    solde_avant DECIMAL(14,2),
    solde_apres DECIMAL(14,2),
    reference VARCHAR(100),
    description VARCHAR(500),
    date_transaction TIMESTAMP DEFAULT NOW(),
    valide_par VARCHAR(255),
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    cree_par VARCHAR(255),
    modifie_par VARCHAR(255),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table demandes_credit
CREATE TABLE IF NOT EXISTS demandes_credit (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    numero_demande VARCHAR(50) UNIQUE NOT NULL,
    membre_id UUID NOT NULL REFERENCES utilisateurs(id),
    montant_demande DECIMAL(14,2) NOT NULL,
    montant_approuve DECIMAL(14,2),
    taux_interet DECIMAL(5,2),
    duree_mois INTEGER,
    statut VARCHAR(30) DEFAULT 'EN_ATTENTE',
    motif TEXT,
    date_demande TIMESTAMP DEFAULT NOW(),
    date_approbation TIMESTAMP,
    date_debut TIMESTAMP,
    date_fin TIMESTAMP,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    cree_par VARCHAR(255),
    modifie_par VARCHAR(255),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table echeances_credit
CREATE TABLE IF NOT EXISTS echeances_credit (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    demande_credit_id UUID NOT NULL REFERENCES demandes_credit(id),
    numero_echeance INTEGER NOT NULL,
    montant_principal DECIMAL(14,2),
    montant_interet DECIMAL(14,2),
    montant_total DECIMAL(14,2),
    date_echeance DATE NOT NULL,
    montant_paye DECIMAL(14,2) DEFAULT 0,
    date_paiement TIMESTAMP,
    statut VARCHAR(30) DEFAULT 'EN_ATTENTE',
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table garanties_demande
CREATE TABLE IF NOT EXISTS garanties_demande (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    demande_credit_id UUID NOT NULL REFERENCES demandes_credit(id),
    type_garantie VARCHAR(50),
    description TEXT,
    valeur_estimee DECIMAL(14,2),
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- ============================================================================
-- 5. TABLES ÉVÉNEMENTS & SOLIDARITÉ
-- ============================================================================

-- Table evenements
CREATE TABLE IF NOT EXISTS evenements (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    titre VARCHAR(200) NOT NULL,
    description TEXT,
    date_debut TIMESTAMP NOT NULL,
    date_fin TIMESTAMP,
    lieu VARCHAR(255) NOT NULL,
    adresse VARCHAR(500),
    ville VARCHAR(100),
    pays VARCHAR(100),
    type_evenement VARCHAR(50) NOT NULL,
    statut VARCHAR(50) NOT NULL,
    capacite_max INTEGER,
    cout_participation DECIMAL(12,2),
    devise VARCHAR(3),
    organisation_id UUID REFERENCES organisations(id),
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    cree_par VARCHAR(255),
    modifie_par VARCHAR(255),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table inscriptions_evenement
CREATE TABLE IF NOT EXISTS inscriptions_evenement (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    membre_id UUID NOT NULL REFERENCES utilisateurs(id) ON DELETE CASCADE,
    evenement_id UUID NOT NULL REFERENCES evenements(id) ON DELETE CASCADE,
    date_inscription TIMESTAMP NOT NULL DEFAULT NOW(),
    statut VARCHAR(20) DEFAULT 'CONFIRMEE',
    commentaire VARCHAR(500),
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE,
    CONSTRAINT uk_inscription_membre_evenement UNIQUE (membre_id, evenement_id)
);

-- Table demandes_aide
CREATE TABLE IF NOT EXISTS demandes_aide (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    titre VARCHAR(200) NOT NULL,
    description TEXT NOT NULL,
    type_aide VARCHAR(50) NOT NULL,
    statut VARCHAR(50) NOT NULL,
    montant_demande DECIMAL(10,2),
    montant_approuve DECIMAL(10,2),
    date_demande TIMESTAMP NOT NULL DEFAULT NOW(),
    date_evaluation TIMESTAMP,
    urgence BOOLEAN NOT NULL DEFAULT FALSE,
    demandeur_id UUID NOT NULL REFERENCES utilisateurs(id) ON DELETE CASCADE,
    evaluateur_id UUID REFERENCES utilisateurs(id),
    organisation_id UUID NOT NULL REFERENCES organisations(id) ON DELETE CASCADE,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    cree_par VARCHAR(255),
    modifie_par VARCHAR(255),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- ============================================================================
-- 6. TABLES SUPPORT & SUGGESTIONS
-- ============================================================================

-- Table tickets (NOM CORRIGÉ dès le départ)
CREATE TABLE IF NOT EXISTS tickets (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    numero_ticket VARCHAR(50) NOT NULL UNIQUE,
    utilisateur_id UUID NOT NULL REFERENCES utilisateurs(id) ON DELETE CASCADE,
    sujet VARCHAR(255) NOT NULL,
    description TEXT,
    categorie VARCHAR(50),
    priorite VARCHAR(50),
    statut VARCHAR(50) DEFAULT 'OUVERT',
    agent_id UUID,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    cree_par VARCHAR(255),
    modifie_par VARCHAR(255),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table suggestions (NOM CORRIGÉ dès le départ)
CREATE TABLE IF NOT EXISTS suggestions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    utilisateur_id UUID NOT NULL REFERENCES utilisateurs(id),
    titre VARCHAR(255) NOT NULL,
    description TEXT,
    categorie VARCHAR(50),
    statut VARCHAR(50) DEFAULT 'NOUVELLE',
    nb_votes INTEGER DEFAULT 0,
    date_soumission TIMESTAMP NOT NULL DEFAULT NOW(),
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    cree_par VARCHAR(255),
    modifie_par VARCHAR(255),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table suggestion_votes (NOM CORRIGÉ dès le départ)
CREATE TABLE IF NOT EXISTS suggestion_votes (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    suggestion_id UUID NOT NULL REFERENCES suggestions(id) ON DELETE CASCADE,
    utilisateur_id UUID NOT NULL REFERENCES utilisateurs(id),
    date_vote TIMESTAMP NOT NULL DEFAULT NOW(),
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    actif BOOLEAN NOT NULL DEFAULT TRUE,
    CONSTRAINT uk_suggestion_vote UNIQUE (suggestion_id, utilisateur_id)
);

-- Table favoris (NOM CORRIGÉ dès le départ)
CREATE TABLE IF NOT EXISTS favoris (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    utilisateur_id UUID NOT NULL REFERENCES utilisateurs(id) ON DELETE CASCADE,
    type_favori VARCHAR(50) NOT NULL,
    titre VARCHAR(255) NOT NULL,
    url VARCHAR(1000),
    ordre INTEGER DEFAULT 0,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    cree_par VARCHAR(255),
    modifie_par VARCHAR(255),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- ============================================================================
-- 7. TABLES NOTIFICATIONS & DOCUMENTS
-- ============================================================================

-- Table notifications
CREATE TABLE IF NOT EXISTS notifications (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    destinataire_id UUID NOT NULL REFERENCES utilisateurs(id),
    titre VARCHAR(255) NOT NULL,
    message TEXT,
    type VARCHAR(50),
    priorite VARCHAR(20),
    lu BOOLEAN DEFAULT FALSE,
    date_lecture TIMESTAMP,
    url_action VARCHAR(500),
    metadata TEXT,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table templates_notifications (NOM CORRIGÉ dès le départ)
CREATE TABLE IF NOT EXISTS templates_notifications (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    code VARCHAR(100) NOT NULL UNIQUE,
    nom VARCHAR(200) NOT NULL,
    sujet VARCHAR(255),
    corps TEXT,
    type VARCHAR(50),
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table documents (NOM CORRIGÉ dès le départ)
CREATE TABLE IF NOT EXISTS documents (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    titre VARCHAR(255) NOT NULL,
    description TEXT,
    type_document VARCHAR(50),
    chemin_fichier VARCHAR(500),
    taille_octets BIGINT,
    mime_type VARCHAR(100),
    proprietaire_id UUID REFERENCES utilisateurs(id),
    organisation_id UUID REFERENCES organisations(id),
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    cree_par VARCHAR(255),
    modifie_par VARCHAR(255),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table pieces_jointes
CREATE TABLE IF NOT EXISTS pieces_jointes (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    nom_fichier VARCHAR(255) NOT NULL,
    chemin_fichier VARCHAR(500),
    taille_octets BIGINT,
    mime_type VARCHAR(100),
    entite_type VARCHAR(50),
    entite_id UUID,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    cree_par VARCHAR(255),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- ============================================================================
-- 8. TABLES WORKFLOWS & FINANCE AVANCÉE
-- ============================================================================

-- Table transaction_approvals (workflow approbations)
CREATE TABLE IF NOT EXISTS transaction_approvals (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    transaction_type VARCHAR(50) NOT NULL,
    transaction_id UUID NOT NULL,
    current_level INTEGER DEFAULT 1,
    required_levels INTEGER DEFAULT 1,
    status VARCHAR(30) DEFAULT 'PENDING',
    initiated_by UUID REFERENCES utilisateurs(id),
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table approver_actions
CREATE TABLE IF NOT EXISTS approver_actions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    approval_id UUID NOT NULL REFERENCES transaction_approvals(id) ON DELETE CASCADE,
    approver_id UUID NOT NULL REFERENCES utilisateurs(id),
    level INTEGER NOT NULL,
    action VARCHAR(20) NOT NULL,
    comment TEXT,
    action_date TIMESTAMP DEFAULT NOW(),
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table budgets
CREATE TABLE IF NOT EXISTS budgets (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    nom VARCHAR(200) NOT NULL,
    code VARCHAR(50) UNIQUE,
    organisation_id UUID REFERENCES organisations(id),
    exercice_annee INTEGER NOT NULL,
    montant_total DECIMAL(14,2) NOT NULL,
    montant_utilise DECIMAL(14,2) DEFAULT 0,
    statut VARCHAR(30) DEFAULT 'ACTIF',
    date_debut DATE,
    date_fin DATE,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    cree_par VARCHAR(255),
    modifie_par VARCHAR(255),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table budget_lines
CREATE TABLE IF NOT EXISTS budget_lines (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    budget_id UUID NOT NULL REFERENCES budgets(id) ON DELETE CASCADE,
    libelle VARCHAR(255) NOT NULL,
    categorie VARCHAR(50),
    montant_prevu DECIMAL(14,2) NOT NULL,
    montant_engage DECIMAL(14,2) DEFAULT 0,
    montant_realise DECIMAL(14,2) DEFAULT 0,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table workflow_validation_config
CREATE TABLE IF NOT EXISTS workflow_validation_config (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    type_transaction VARCHAR(50) NOT NULL,
    niveau INTEGER NOT NULL,
    role_validateur VARCHAR(100) NOT NULL,
    montant_min DECIMAL(14,2),
    montant_max DECIMAL(14,2),
    organisation_id UUID REFERENCES organisations(id),
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- ============================================================================
-- 9. TABLES MONITORING & LOGS
-- ============================================================================

-- Table system_logs
CREATE TABLE IF NOT EXISTS system_logs (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    niveau VARCHAR(20) NOT NULL,
    source VARCHAR(100),
    message TEXT,
    stacktrace TEXT,
    utilisateur_id UUID,
    ip_address VARCHAR(50),
    user_agent VARCHAR(500),
    metadata TEXT,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    cree_par VARCHAR(255),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

CREATE INDEX idx_system_logs_niveau ON system_logs(niveau);
CREATE INDEX idx_system_logs_date ON system_logs(date_creation DESC);

-- Table system_alerts
CREATE TABLE IF NOT EXISTS system_alerts (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    type_alerte VARCHAR(50) NOT NULL,
    severite VARCHAR(20) NOT NULL,
    titre VARCHAR(255) NOT NULL,
    message TEXT,
    statut VARCHAR(30) DEFAULT 'NOUVELLE',
    date_alerte TIMESTAMP DEFAULT NOW(),
    date_resolution TIMESTAMP,
    resolu_par UUID REFERENCES utilisateurs(id),
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table alert_configuration
CREATE TABLE IF NOT EXISTS alert_configuration (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    type_alerte VARCHAR(50) NOT NULL UNIQUE,
    seuil_critique DECIMAL(14,2),
    seuil_warning DECIMAL(14,2),
    actif BOOLEAN DEFAULT TRUE,
    notification_email BOOLEAN DEFAULT TRUE,
    notification_sms BOOLEAN DEFAULT FALSE,
    destinataires TEXT,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0
);

-- Table audit_logs
CREATE TABLE IF NOT EXISTS audit_logs (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    entite_type VARCHAR(100) NOT NULL,
    entite_id UUID,
    action VARCHAR(50) NOT NULL,
    utilisateur_id UUID,
    ancien_etat TEXT,
    nouvel_etat TEXT,
    ip_address VARCHAR(50),
    date_action TIMESTAMP DEFAULT NOW(),
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

CREATE INDEX idx_audit_entite ON audit_logs(entite_type, entite_id);
CREATE INDEX idx_audit_date ON audit_logs(date_action DESC);

-- ============================================================================
-- 10. TABLES MÉTIER SPÉCIALISÉES
-- ============================================================================

-- Table tontines
CREATE TABLE IF NOT EXISTS tontines (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    nom VARCHAR(200) NOT NULL,
    description TEXT,
    organisation_id UUID REFERENCES organisations(id),
    montant_cotisation DECIMAL(12,2) NOT NULL,
    periodicite VARCHAR(30),
    nombre_membres_max INTEGER,
    statut VARCHAR(30) DEFAULT 'ACTIVE',
    date_debut DATE,
    date_fin DATE,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    cree_par VARCHAR(255),
    modifie_par VARCHAR(255),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table tours_tontine
CREATE TABLE IF NOT EXISTS tours_tontine (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tontine_id UUID NOT NULL REFERENCES tontines(id) ON DELETE CASCADE,
    membre_id UUID REFERENCES utilisateurs(id),
    numero_tour INTEGER NOT NULL,
    date_tour DATE,
    montant_recu DECIMAL(12,2),
    statut VARCHAR(30) DEFAULT 'EN_ATTENTE',
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table campagnes_vote
CREATE TABLE IF NOT EXISTS campagnes_vote (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    titre VARCHAR(255) NOT NULL,
    description TEXT,
    organisation_id UUID REFERENCES organisations(id),
    date_debut TIMESTAMP,
    date_fin TIMESTAMP,
    statut VARCHAR(30) DEFAULT 'PLANIFIEE',
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table candidats
CREATE TABLE IF NOT EXISTS candidats (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    campagne_id UUID NOT NULL REFERENCES campagnes_vote(id) ON DELETE CASCADE,
    membre_id UUID NOT NULL REFERENCES utilisateurs(id),
    poste VARCHAR(100),
    programme TEXT,
    nb_voix INTEGER DEFAULT 0,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table campagnes_collecte
CREATE TABLE IF NOT EXISTS campagnes_collecte (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    titre VARCHAR(255) NOT NULL,
    description TEXT,
    objectif_montant DECIMAL(14,2),
    montant_collecte DECIMAL(14,2) DEFAULT 0,
    organisation_id UUID REFERENCES organisations(id),
    date_debut DATE,
    date_fin DATE,
    statut VARCHAR(30) DEFAULT 'ACTIVE',
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table contributions_collecte
CREATE TABLE IF NOT EXISTS contributions_collecte (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    campagne_id UUID NOT NULL REFERENCES campagnes_collecte(id) ON DELETE CASCADE,
    membre_id UUID REFERENCES utilisateurs(id),
    montant DECIMAL(12,2) NOT NULL,
    date_contribution TIMESTAMP DEFAULT NOW(),
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table campagnes_agricoles
CREATE TABLE IF NOT EXISTS campagnes_agricoles (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    nom VARCHAR(200) NOT NULL,
    description TEXT,
    organisation_id UUID REFERENCES organisations(id),
    culture VARCHAR(100),
    superficie_hectares DECIMAL(10,2),
    date_debut DATE,
    date_fin DATE,
    statut VARCHAR(30) DEFAULT 'PLANIFIEE',
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table projets_ong
CREATE TABLE IF NOT EXISTS projets_ong (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    nom VARCHAR(200) NOT NULL,
    description TEXT,
    organisation_id UUID REFERENCES organisations(id),
    budget DECIMAL(14,2),
    date_debut DATE,
    date_fin DATE,
    statut VARCHAR(30) DEFAULT 'EN_COURS',
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table dons_religieux
CREATE TABLE IF NOT EXISTS dons_religieux (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    membre_id UUID REFERENCES utilisateurs(id),
    organisation_id UUID REFERENCES organisations(id),
    montant DECIMAL(12,2) NOT NULL,
    type_don VARCHAR(50),
    date_don DATE DEFAULT CURRENT_DATE,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table echelons_organigramme
CREATE TABLE IF NOT EXISTS echelons_organigramme (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    nom VARCHAR(100) NOT NULL,
    niveau INTEGER NOT NULL,
    organisation_id UUID REFERENCES organisations(id),
    parent_id UUID REFERENCES echelons_organigramme(id),
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table agrements_professionnels
CREATE TABLE IF NOT EXISTS agrements_professionnels (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    membre_id UUID NOT NULL REFERENCES utilisateurs(id),
    profession VARCHAR(200),
    numero_agrement VARCHAR(100),
    organisme_delivrance VARCHAR(255),
    date_delivrance DATE,
    date_expiration DATE,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- ============================================================================
-- 11. TABLES LCB-FT (Lutte Contre le Blanchiment)
-- ============================================================================

-- Table parametres_lcb_ft
CREATE TABLE IF NOT EXISTS parametres_lcb_ft (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    seuil_declaration DECIMAL(14,2) DEFAULT 500000,
    seuil_vigilance_renforcee DECIMAL(14,2) DEFAULT 1000000,
    duree_conservation_jours INTEGER DEFAULT 1825,
    organisation_id UUID REFERENCES organisations(id),
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table alertes_lcb_ft
CREATE TABLE IF NOT EXISTS alertes_lcb_ft (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    type_alerte VARCHAR(50) NOT NULL,
    severite VARCHAR(20) NOT NULL,
    organisation_id UUID NOT NULL REFERENCES organisations(id) ON DELETE CASCADE,
    membre_id UUID REFERENCES utilisateurs(id) ON DELETE SET NULL,
    transaction_id UUID,
    montant DECIMAL(14,2),
    description TEXT,
    statut VARCHAR(30) DEFAULT 'NOUVELLE',
    date_alerte TIMESTAMP DEFAULT NOW(),
    traite_par UUID REFERENCES utilisateurs(id),
    date_traitement TIMESTAMP,
    commentaire TEXT,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    cree_par VARCHAR(255),
    modifie_par VARCHAR(255),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

CREATE INDEX idx_alertes_lcb_statut ON alertes_lcb_ft(statut);
CREATE INDEX idx_alertes_lcb_organisation ON alertes_lcb_ft(organisation_id);
CREATE INDEX idx_alertes_lcb_membre ON alertes_lcb_ft(membre_id);

-- ============================================================================
-- 12. TABLES DIVERS
-- ============================================================================

-- Table adresses
CREATE TABLE IF NOT EXISTS adresses (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    entite_type VARCHAR(50) NOT NULL,
    entite_id UUID NOT NULL,
    type_adresse VARCHAR(30),
    adresse_ligne1 VARCHAR(255),
    adresse_ligne2 VARCHAR(255),
    ville VARCHAR(100),
    code_postal VARCHAR(20),
    region VARCHAR(100),
    pays VARCHAR(100) DEFAULT 'Côte d''Ivoire',
    latitude DECIMAL(9,6),
    longitude DECIMAL(9,6),
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table ayants_droit
CREATE TABLE IF NOT EXISTS ayants_droit (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    membre_id UUID NOT NULL REFERENCES utilisateurs(id) ON DELETE CASCADE,
    nom VARCHAR(100) NOT NULL,
    prenom VARCHAR(100) NOT NULL,
    lien_parente VARCHAR(50),
    date_naissance DATE,
    telephone VARCHAR(30),
    pourcentage_part DECIMAL(5,2),
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table types_reference
CREATE TABLE IF NOT EXISTS types_reference (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    domaine VARCHAR(50) NOT NULL,
    code VARCHAR(50) NOT NULL,
    categorie VARCHAR(50),
    libelle VARCHAR(200) NOT NULL,
    description TEXT,
    ordre_affichage INTEGER NOT NULL DEFAULT 0,
    est_defaut BOOLEAN NOT NULL DEFAULT FALSE,
    est_systeme BOOLEAN NOT NULL DEFAULT FALSE,
    modules_requis VARCHAR(500),
    organisation_id UUID,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE,
    cree_par VARCHAR(255),
    modifie_par VARCHAR(255),
    CONSTRAINT uk_typeref_domaine_code_org UNIQUE (domaine, code, organisation_id)
);

-- Table modules_organisation_actifs
CREATE TABLE IF NOT EXISTS modules_organisation_actifs (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    organisation_id UUID NOT NULL REFERENCES organisations(id) ON DELETE CASCADE,
    code_module VARCHAR(50) NOT NULL,
    actif BOOLEAN DEFAULT TRUE,
    date_activation DATE,
    date_desactivation DATE,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0,
    CONSTRAINT uk_org_module UNIQUE (organisation_id, code_module)
);

-- Table modules_disponibles (NOM CORRIGÉ dès le départ)
CREATE TABLE IF NOT EXISTS modules_disponibles (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    code VARCHAR(50) NOT NULL UNIQUE,
    nom VARCHAR(200) NOT NULL,
    description TEXT,
    version VARCHAR(20),
    actif BOOLEAN DEFAULT TRUE,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version_record BIGINT DEFAULT 0
);

-- Table parametres_cotisation_organisation
CREATE TABLE IF NOT EXISTS parametres_cotisation_organisation (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    organisation_id UUID NOT NULL REFERENCES organisations(id) ON DELETE CASCADE,
    type_cotisation VARCHAR(50) NOT NULL,
    montant_defaut DECIMAL(12,2),
    recurrence VARCHAR(30),
    obligatoire BOOLEAN DEFAULT FALSE,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table comptes_wave (intégration Wave)
CREATE TABLE IF NOT EXISTS comptes_wave (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    organisation_id UUID REFERENCES organisations(id),
    numero_compte_wave VARCHAR(50) UNIQUE,
    nom_titulaire VARCHAR(200),
    solde DECIMAL(14,2) DEFAULT 0,
    actif BOOLEAN DEFAULT TRUE,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0
);

-- Table transactions_wave (NOM CORRIGÉ dès le départ)
CREATE TABLE IF NOT EXISTS transactions_wave (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    compte_wave_id UUID REFERENCES comptes_wave(id),
    transaction_id_wave VARCHAR(100) UNIQUE,
    type_transaction VARCHAR(50),
    montant DECIMAL(14,2),
    statut VARCHAR(30),
    metadata TEXT,
    date_transaction TIMESTAMP DEFAULT NOW(),
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table webhooks_wave
CREATE TABLE IF NOT EXISTS webhooks_wave (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    event_type VARCHAR(50) NOT NULL,
    payload TEXT,
    signature VARCHAR(500),
    traite BOOLEAN DEFAULT FALSE,
    date_reception TIMESTAMP DEFAULT NOW(),
    date_traitement TIMESTAMP,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table demandes_adhesion (NOM CORRIGÉ dès le départ)
CREATE TABLE IF NOT EXISTS demandes_adhesion (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    nom VARCHAR(100) NOT NULL,
    prenom VARCHAR(100) NOT NULL,
    email VARCHAR(255) NOT NULL,
    telephone VARCHAR(30),
    organisation_id UUID REFERENCES organisations(id),
    statut VARCHAR(30) DEFAULT 'EN_ATTENTE',
    date_demande TIMESTAMP DEFAULT NOW(),
    date_traitement TIMESTAMP,
    commentaire TEXT,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table formules_abonnement (NOM CORRIGÉ dès le départ)
CREATE TABLE IF NOT EXISTS formules_abonnement (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    nom VARCHAR(200) NOT NULL,
    code VARCHAR(50) UNIQUE,
    description TEXT,
    prix_mensuel DECIMAL(12,2),
    prix_annuel DECIMAL(12,2),
    features TEXT,
    actif BOOLEAN DEFAULT TRUE,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0
);

-- Table souscriptions_organisation (NOM CORRIGÉ dès le départ)
CREATE TABLE IF NOT EXISTS souscriptions_organisation (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    organisation_id UUID NOT NULL REFERENCES organisations(id) ON DELETE CASCADE,
    formule_id UUID REFERENCES formules_abonnement(id),
    date_debut DATE NOT NULL,
    date_fin DATE,
    statut VARCHAR(30) DEFAULT 'ACTIVE',
    montant_paye DECIMAL(12,2),
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table membre_suivi (réseau social)
CREATE TABLE IF NOT EXISTS membre_suivi (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    suiveur_id UUID NOT NULL REFERENCES utilisateurs(id) ON DELETE CASCADE,
    suivi_id UUID NOT NULL REFERENCES utilisateurs(id) ON DELETE CASCADE,
    date_suivi TIMESTAMP DEFAULT NOW(),
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    actif BOOLEAN NOT NULL DEFAULT TRUE,
    CONSTRAINT uk_suiveur_suivi UNIQUE (suiveur_id, suivi_id),
    CONSTRAINT chk_pas_auto_suivi CHECK (suiveur_id != suivi_id)
);

CREATE INDEX idx_membre_suivi_suiveur ON membre_suivi(suiveur_id);
CREATE INDEX idx_membre_suivi_suivi ON membre_suivi(suivi_id);

-- Table validation_etapes_demande (NOM CORRIGÉ dès le départ)
CREATE TABLE IF NOT EXISTS validation_etapes_demande (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    demande_type VARCHAR(50) NOT NULL,
    demande_id UUID NOT NULL,
    etape INTEGER NOT NULL,
    validateur_id UUID REFERENCES utilisateurs(id),
    statut VARCHAR(30) DEFAULT 'EN_ATTENTE',
    commentaire TEXT,
    date_validation TIMESTAMP,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table comptes_comptables (NOM CORRIGÉ dès le départ)
CREATE TABLE IF NOT EXISTS comptes_comptables (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    numero VARCHAR(20) NOT NULL UNIQUE,
    libelle VARCHAR(255) NOT NULL,
    type_compte VARCHAR(30),
    organisation_id UUID REFERENCES organisations(id),
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table journaux_comptables (NOM CORRIGÉ dès le départ)
CREATE TABLE IF NOT EXISTS journaux_comptables (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    code VARCHAR(20) NOT NULL UNIQUE,
    libelle VARCHAR(255) NOT NULL,
    type_journal VARCHAR(30),
    organisation_id UUID REFERENCES organisations(id),
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table ecritures_comptables (NOM CORRIGÉ dès le départ)
CREATE TABLE IF NOT EXISTS ecritures_comptables (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    numero_piece VARCHAR(50) NOT NULL,
    journal_id UUID REFERENCES journaux_comptables(id),
    date_ecriture DATE NOT NULL,
    libelle VARCHAR(255),
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    date_modification TIMESTAMP,
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- Table lignes_ecriture (NOM CORRIGÉ dès le départ)
CREATE TABLE IF NOT EXISTS lignes_ecriture (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    ecriture_id UUID NOT NULL REFERENCES ecritures_comptables(id) ON DELETE CASCADE,
    compte_id UUID NOT NULL REFERENCES comptes_comptables(id),
    libelle VARCHAR(255),
    debit DECIMAL(14,2) DEFAULT 0,
    credit DECIMAL(14,2) DEFAULT 0,
    date_creation TIMESTAMP NOT NULL DEFAULT NOW(),
    version BIGINT DEFAULT 0,
    actif BOOLEAN NOT NULL DEFAULT TRUE
);

-- ============================================================================
-- COMMENTAIRES DE DOCUMENTATION
-- ============================================================================

COMMENT ON TABLE utilisateurs IS 'Table des membres/utilisateurs (entité: Membre)';
COMMENT ON TABLE organisations IS 'Table des organisations (clubs, associations, coopératives)';
COMMENT ON TABLE roles IS 'Table des rôles système';
COMMENT ON TABLE permissions IS 'Table des permissions système';
COMMENT ON TABLE configurations IS 'Table de configurations système';
COMMENT ON TABLE cotisations IS 'Table des cotisations des membres';
COMMENT ON TABLE paiements IS 'Table des paiements';
COMMENT ON TABLE comptes_epargne IS 'Table des comptes d''épargne';
COMMENT ON TABLE demandes_credit IS 'Table des demandes de crédit';
COMMENT ON TABLE evenements IS 'Table des événements';
COMMENT ON TABLE demandes_aide IS 'Table des demandes d''aide solidarité';
COMMENT ON TABLE tickets IS 'Table des tickets de support';
COMMENT ON TABLE suggestions IS 'Table des suggestions des utilisateurs';
COMMENT ON TABLE notifications IS 'Table des notifications';
COMMENT ON TABLE documents IS 'Table des documents';
COMMENT ON TABLE alertes_lcb_ft IS 'Table des alertes anti-blanchiment';
COMMENT ON TABLE audit_logs IS 'Table des logs d''audit';

-- ============================================================================
-- FIN DU SCHEMA
-- ============================================================================

-- Afficher un résumé
DO $$
DECLARE
    table_count INTEGER;
BEGIN
    SELECT COUNT(*) INTO table_count
    FROM information_schema.tables
    WHERE table_schema = 'public' AND table_type = 'BASE TABLE';

    RAISE NOTICE '✅ Schema UnionFlow créé avec succès!';
    RAISE NOTICE 'Nombre total de tables: %', table_count;
    RAISE NOTICE 'Date: %', NOW();
END $$;
