Same rename applied to V1 must propagate to V2-V16 which referenced old singular table names (compte_comptable, suggestion, etc.)
280 lines
13 KiB
SQL
280 lines
13 KiB
SQL
-- =============================================================================
|
||
-- V11 — Workflow de souscription/onboarding UnionFlow
|
||
-- =============================================================================
|
||
-- Auteur : UnionFlow Team
|
||
-- Date : 2026-03-30
|
||
-- Objectif:
|
||
-- 0. Renommer les tables singulières créées par V1 vers les noms pluriels attendus
|
||
-- par les entités JPA (FormuleAbonnement → formules_abonnement, etc.)
|
||
-- 1. Ajouter les colonnes manquantes à formules_abonnement (entité refactorisée)
|
||
-- 2. Ajouter la colonne `plage` à formules_abonnement (PETITE/MOYENNE/GRANDE/TRES_GRANDE)
|
||
-- 3. Supprimer le code unique sur `code` seul (nouvelle contrainte sur code+plage)
|
||
-- 4. Migrer les anciennes valeurs TypeFormule (STARTER→BASIC, CRYSTAL supprimé)
|
||
-- 5. Vider et re-seeder avec la matrice tarifaire 4×3 (12 formules)
|
||
-- 6. Ajouter les colonnes du workflow de validation à souscriptions_organisation
|
||
-- 7. Ajouter EN_ATTENTE au statut (déjà en DB comme VARCHAR, pas de contrainte CHECK)
|
||
-- =============================================================================
|
||
|
||
-- -----------------------------------------------------------------------------
|
||
-- 0. Renommer les tables singulières → plurielles (alignement entités JPA)
|
||
-- -----------------------------------------------------------------------------
|
||
|
||
-- formules_abonnement → formules_abonnement (FormuleAbonnement entity @Table)
|
||
DO $$
|
||
BEGIN
|
||
IF EXISTS (SELECT 1 FROM pg_tables WHERE schemaname = 'public' AND tablename = 'formules_abonnement')
|
||
AND NOT EXISTS (SELECT 1 FROM pg_tables WHERE schemaname = 'public' AND tablename = 'formules_abonnement') THEN
|
||
ALTER TABLE formules_abonnement RENAME TO formules_abonnement;
|
||
END IF;
|
||
END $$;
|
||
|
||
-- souscriptions_organisation → souscriptions_organisation (SouscriptionOrganisation entity @Table)
|
||
DO $$
|
||
BEGIN
|
||
IF EXISTS (SELECT 1 FROM pg_tables WHERE schemaname = 'public' AND tablename = 'souscriptions_organisation')
|
||
AND NOT EXISTS (SELECT 1 FROM pg_tables WHERE schemaname = 'public' AND tablename = 'souscriptions_organisation') THEN
|
||
ALTER TABLE souscriptions_organisation RENAME TO souscriptions_organisation;
|
||
END IF;
|
||
END $$;
|
||
|
||
-- Mise à jour des noms de contraintes FK après le renommage
|
||
-- (PostgreSQL met à jour automatiquement les FK qui référencent la table renommée)
|
||
|
||
-- -----------------------------------------------------------------------------
|
||
-- 0b. Ajouter les colonnes manquantes à formules_abonnement (entité refactorisée)
|
||
-- -----------------------------------------------------------------------------
|
||
|
||
-- Colonne libelle (libellé de la formule — nullable temporairement, NOT NULL après seed)
|
||
ALTER TABLE formules_abonnement ADD COLUMN IF NOT EXISTS libelle VARCHAR(100);
|
||
|
||
-- Colonne plage (taille organisation cible)
|
||
ALTER TABLE formules_abonnement ADD COLUMN IF NOT EXISTS plage VARCHAR(20);
|
||
|
||
-- Nombre max de membres (NULL = illimité)
|
||
ALTER TABLE formules_abonnement ADD COLUMN IF NOT EXISTS max_membres INTEGER;
|
||
|
||
-- Stockage max en Mo (défaut 1 Go)
|
||
ALTER TABLE formules_abonnement ADD COLUMN IF NOT EXISTS max_stockage_mo INTEGER DEFAULT 1024;
|
||
|
||
-- Ordre d'affichage dans le catalogue
|
||
ALTER TABLE formules_abonnement ADD COLUMN IF NOT EXISTS ordre_affichage INTEGER DEFAULT 0;
|
||
|
||
-- La colonne `nom` de V1 n'est pas dans l'entité JPA — rendre nullable pour compatibilité
|
||
ALTER TABLE formules_abonnement ALTER COLUMN nom DROP NOT NULL;
|
||
|
||
-- -----------------------------------------------------------------------------
|
||
-- 0c. Supprimer les contraintes CHECK Hibernate obsolètes
|
||
-- -----------------------------------------------------------------------------
|
||
|
||
-- Hibernate génère automatiquement des CHECK constraints pour les enums @Enumerated(STRING).
|
||
-- Les valeurs ont changé (STARTER→BASIC, CRYSTAL supprimé) : on supprime ces contraintes
|
||
-- avant toute modification de données.
|
||
ALTER TABLE formules_abonnement DROP CONSTRAINT IF EXISTS formules_abonnement_code_check;
|
||
ALTER TABLE souscriptions_organisation DROP CONSTRAINT IF EXISTS souscriptions_organisation_statut_check;
|
||
ALTER TABLE souscriptions_organisation DROP CONSTRAINT IF EXISTS souscriptions_organisation_type_periode_check;
|
||
ALTER TABLE souscriptions_organisation DROP CONSTRAINT IF EXISTS souscriptions_organisation_statut_validation_check;
|
||
|
||
-- -----------------------------------------------------------------------------
|
||
-- 1. Préparer formules_abonnement
|
||
-- -----------------------------------------------------------------------------
|
||
|
||
-- Ajouter la colonne plage si elle n'existe pas encore
|
||
ALTER TABLE formules_abonnement ADD COLUMN IF NOT EXISTS plage VARCHAR(20);
|
||
|
||
-- Supprimer toutes les contraintes unicité sur code seul (V1 ou Hibernate)
|
||
DO $$
|
||
DECLARE r RECORD;
|
||
BEGIN
|
||
FOR r IN
|
||
SELECT conname FROM pg_constraint
|
||
WHERE conrelid = 'formules_abonnement'::regclass
|
||
AND contype = 'u'
|
||
AND conname NOT IN ('idx_formule_code_plage')
|
||
AND array_length(conkey, 1) = 1
|
||
AND conkey[1] = (
|
||
SELECT attnum FROM pg_attribute
|
||
WHERE attrelid = 'formules_abonnement'::regclass AND attname = 'code'
|
||
)
|
||
LOOP
|
||
EXECUTE 'ALTER TABLE formules_abonnement DROP CONSTRAINT ' || quote_ident(r.conname);
|
||
END LOOP;
|
||
END $$;
|
||
|
||
-- Supprimer les index uniques sur code seul s'ils existent
|
||
DROP INDEX IF EXISTS idx_formule_code;
|
||
DROP INDEX IF EXISTS formule_abonnement_code_key;
|
||
|
||
-- -----------------------------------------------------------------------------
|
||
-- 2. Migrer les anciennes données TypeFormule
|
||
-- -----------------------------------------------------------------------------
|
||
|
||
UPDATE formules_abonnement SET code = 'BASIC' WHERE code = 'STARTER';
|
||
DELETE FROM formules_abonnement WHERE code = 'CRYSTAL';
|
||
|
||
-- -----------------------------------------------------------------------------
|
||
-- 3. Vider et re-seeder avec la nouvelle matrice 4 plages × 3 formules
|
||
-- -----------------------------------------------------------------------------
|
||
|
||
DELETE FROM formules_abonnement;
|
||
|
||
INSERT INTO formules_abonnement (
|
||
id, version, actif, cree_par, modifie_par, date_creation, date_modification,
|
||
code, libelle, description, plage, max_membres, max_stockage_mo,
|
||
prix_mensuel, prix_annuel, ordre_affichage
|
||
) VALUES
|
||
|
||
-- ── PETITE (1–100 membres) ──────────────────────────────────────────────────
|
||
(gen_random_uuid(), 0, true, 'SYSTEM', 'SYSTEM', NOW(), NOW(),
|
||
'BASIC', 'Basic — Petites structures',
|
||
'Idéal pour les petites associations de moins de 100 membres',
|
||
'PETITE', 100, 1024, 3000, 28800, 1),
|
||
|
||
(gen_random_uuid(), 0, true, 'SYSTEM', 'SYSTEM', NOW(), NOW(),
|
||
'STANDARD', 'Standard — Petites structures',
|
||
'Pour les associations actives de moins de 100 membres',
|
||
'PETITE', 100, 5120, 6000, 57600, 2),
|
||
|
||
(gen_random_uuid(), 0, true, 'SYSTEM', 'SYSTEM', NOW(), NOW(),
|
||
'PREMIUM', 'Premium — Petites structures',
|
||
'Fonctionnalités avancées pour petites structures ambitieuses',
|
||
'PETITE', 100, 10240, 10000, 96000, 3),
|
||
|
||
-- ── MOYENNE (101–500 membres) ────────────────────────────────────────────────
|
||
(gen_random_uuid(), 0, true, 'SYSTEM', 'SYSTEM', NOW(), NOW(),
|
||
'BASIC', 'Basic — Moyennes structures',
|
||
'Gestion complète pour moyennes structures',
|
||
'MOYENNE', 500, 2048, 8000, 76800, 4),
|
||
|
||
(gen_random_uuid(), 0, true, 'SYSTEM', 'SYSTEM', NOW(), NOW(),
|
||
'STANDARD', 'Standard — Moyennes structures',
|
||
'Fonctionnalités étendues pour organisations en croissance',
|
||
'MOYENNE', 500, 10240, 15000, 144000, 5),
|
||
|
||
(gen_random_uuid(), 0, true, 'SYSTEM', 'SYSTEM', NOW(), NOW(),
|
||
'PREMIUM', 'Premium — Moyennes structures',
|
||
'Suite complète pour organisations actives',
|
||
'MOYENNE', 500, 20480, 25000, 240000, 6),
|
||
|
||
-- ── GRANDE (501–2 000 membres) ────────────────────────────────────────────────
|
||
(gen_random_uuid(), 0, true, 'SYSTEM', 'SYSTEM', NOW(), NOW(),
|
||
'BASIC', 'Basic — Grandes structures',
|
||
'Solution économique pour grandes organisations',
|
||
'GRANDE', 2000, 5120, 20000, 192000, 7),
|
||
|
||
(gen_random_uuid(), 0, true, 'SYSTEM', 'SYSTEM', NOW(), NOW(),
|
||
'STANDARD', 'Standard — Grandes structures',
|
||
'Gestion avancée pour grandes structures',
|
||
'GRANDE', 2000, 20480, 35000, 336000, 8),
|
||
|
||
(gen_random_uuid(), 0, true, 'SYSTEM', 'SYSTEM', NOW(), NOW(),
|
||
'PREMIUM', 'Premium — Grandes structures',
|
||
'Fonctionnalités entreprise pour grandes organisations',
|
||
'GRANDE', 2000, 51200, 60000, 576000, 9),
|
||
|
||
-- ── TRES_GRANDE (2 000+ membres) ─────────────────────────────────────────────
|
||
(gen_random_uuid(), 0, true, 'SYSTEM', 'SYSTEM', NOW(), NOW(),
|
||
'BASIC', 'Basic — Très grandes structures',
|
||
'Gestion de base pour très grandes organisations',
|
||
'TRES_GRANDE', NULL, 10240, 50000, 480000, 10),
|
||
|
||
(gen_random_uuid(), 0, true, 'SYSTEM', 'SYSTEM', NOW(), NOW(),
|
||
'STANDARD', 'Standard — Très grandes structures',
|
||
'Suite complète pour très grandes organisations',
|
||
'TRES_GRANDE', NULL, 51200, 80000, 768000, 11),
|
||
|
||
(gen_random_uuid(), 0, true, 'SYSTEM', 'SYSTEM', NOW(), NOW(),
|
||
'PREMIUM', 'Premium — Très grandes structures',
|
||
'Solution enterprise multi-sites avec analytics avancé',
|
||
'TRES_GRANDE', NULL, 102400, 120000, 1152000, 12);
|
||
|
||
|
||
-- Appliquer NOT NULL sur plage après le seed
|
||
DO $$
|
||
BEGIN
|
||
-- PostgreSQL ne supporte pas ADD COLUMN ... NOT NULL ... en une seule commande
|
||
-- quand la table est déjà peuplée. On pose la contrainte séparément.
|
||
ALTER TABLE formules_abonnement ALTER COLUMN plage SET NOT NULL;
|
||
EXCEPTION
|
||
WHEN others THEN
|
||
RAISE NOTICE 'Contrainte NOT NULL sur plage déjà présente ou erreur: %', SQLERRM;
|
||
END $$;
|
||
|
||
-- Créer l'index unique sur la combinaison code+plage
|
||
CREATE UNIQUE INDEX IF NOT EXISTS idx_formule_code_plage
|
||
ON formules_abonnement (code, plage);
|
||
|
||
CREATE INDEX IF NOT EXISTS idx_formule_plage
|
||
ON formules_abonnement (plage);
|
||
|
||
|
||
-- -----------------------------------------------------------------------------
|
||
-- 4. Colonnes workflow de validation dans souscriptions_organisation
|
||
-- -----------------------------------------------------------------------------
|
||
|
||
ALTER TABLE souscriptions_organisation
|
||
ADD COLUMN IF NOT EXISTS plage VARCHAR(20);
|
||
|
||
ALTER TABLE souscriptions_organisation
|
||
ADD COLUMN IF NOT EXISTS type_organisation VARCHAR(30);
|
||
|
||
ALTER TABLE souscriptions_organisation
|
||
ADD COLUMN IF NOT EXISTS coefficient_applique NUMERIC(4, 2);
|
||
|
||
ALTER TABLE souscriptions_organisation
|
||
ADD COLUMN IF NOT EXISTS statut_validation VARCHAR(40);
|
||
|
||
ALTER TABLE souscriptions_organisation
|
||
ADD COLUMN IF NOT EXISTS montant_total NUMERIC(12, 2);
|
||
|
||
ALTER TABLE souscriptions_organisation
|
||
ADD COLUMN IF NOT EXISTS date_validation DATE;
|
||
|
||
ALTER TABLE souscriptions_organisation
|
||
ADD COLUMN IF NOT EXISTS validated_by_id UUID;
|
||
|
||
ALTER TABLE souscriptions_organisation
|
||
ADD COLUMN IF NOT EXISTS commentaire_rejet VARCHAR(500);
|
||
|
||
ALTER TABLE souscriptions_organisation
|
||
ADD COLUMN IF NOT EXISTS mot_de_passe_temporaire VARCHAR(100);
|
||
|
||
-- Backfill des lignes existantes avant d'ajouter les contraintes NOT NULL
|
||
UPDATE souscriptions_organisation
|
||
SET plage = 'PETITE',
|
||
type_organisation = 'ASSOCIATION',
|
||
coefficient_applique = 1.0,
|
||
statut_validation = 'VALIDEE'
|
||
WHERE plage IS NULL;
|
||
|
||
-- Appliquer NOT NULL sur statut_validation uniquement (les autres sont optionnels)
|
||
DO $$
|
||
BEGIN
|
||
ALTER TABLE souscriptions_organisation
|
||
ALTER COLUMN statut_validation SET NOT NULL;
|
||
EXCEPTION
|
||
WHEN others THEN
|
||
RAISE NOTICE 'Contrainte NOT NULL sur statut_validation: %', SQLERRM;
|
||
END $$;
|
||
|
||
-- Valeur par défaut pour les nouvelles lignes
|
||
ALTER TABLE souscriptions_organisation
|
||
ALTER COLUMN statut_validation SET DEFAULT 'EN_ATTENTE_PAIEMENT';
|
||
|
||
-- Index pour les requêtes SuperAdmin sur le workflow
|
||
CREATE INDEX IF NOT EXISTS idx_souscription_statut_validation
|
||
ON souscriptions_organisation (statut_validation);
|
||
|
||
CREATE INDEX IF NOT EXISTS idx_souscription_plage
|
||
ON souscriptions_organisation (plage);
|
||
|
||
-- Mise à jour du statut global pour les souscriptions existantes actives
|
||
-- (l'ancienne valeur ACTIVE reste cohérente avec VALIDEE côté validation)
|
||
UPDATE souscriptions_organisation
|
||
SET statut = 'ACTIVE'
|
||
WHERE statut IS NULL OR statut NOT IN ('ACTIVE', 'EXPIREE', 'SUSPENDUE', 'RESILIEE', 'EN_ATTENTE');
|
||
|
||
|
||
-- =============================================================================
|
||
-- Fin de V11
|
||
-- =============================================================================
|