From 5cd807f9167f26fb746ebf4c4a0ca5a8c484ee38 Mon Sep 17 00:00:00 2001 From: Youssef Date: Tue, 19 May 2026 22:39:19 +0200 Subject: [PATCH] feat: make all Flyway SQL migrations fully idempotent --- .../db/migration/V1__init_schema.sql | 18 +++++++------- .../db/migration/V2__add_mode_paiement.sql | 16 +++++++++---- .../db/migration/V3__insert_default_data.sql | 24 ++++++++++++------- .../migration/V4__add_residency_pricing.sql | 6 ++--- .../db/migration/V5__add_numero_licence.sql | 2 +- 5 files changed, 39 insertions(+), 27 deletions(-) diff --git a/as-talange-core/src/main/resources/db/migration/V1__init_schema.sql b/as-talange-core/src/main/resources/db/migration/V1__init_schema.sql index c8a9ac8..cdcad18 100644 --- a/as-talange-core/src/main/resources/db/migration/V1__init_schema.sql +++ b/as-talange-core/src/main/resources/db/migration/V1__init_schema.sql @@ -1,16 +1,16 @@ -CREATE TABLE role ( +CREATE TABLE IF NOT EXISTS role ( id BIGSERIAL PRIMARY KEY, name VARCHAR(50) UNIQUE NOT NULL ); -CREATE TABLE app_user ( +CREATE TABLE IF NOT EXISTS app_user ( id BIGSERIAL PRIMARY KEY, username VARCHAR(100) UNIQUE NOT NULL, password VARCHAR(255) NOT NULL, enabled BOOLEAN NOT NULL DEFAULT TRUE ); -CREATE TABLE user_role ( +CREATE TABLE IF NOT EXISTS user_role ( user_id BIGINT NOT NULL, role_id BIGINT NOT NULL, PRIMARY KEY (user_id, role_id), @@ -18,7 +18,7 @@ CREATE TABLE user_role ( CONSTRAINT fk_role FOREIGN KEY (role_id) REFERENCES role(id) ON DELETE CASCADE ); -CREATE TABLE adherent ( +CREATE TABLE IF NOT EXISTS adherent ( id BIGSERIAL PRIMARY KEY, nom VARCHAR(100) NOT NULL, prenom VARCHAR(100) NOT NULL, @@ -29,7 +29,7 @@ CREATE TABLE adherent ( representant_legal VARCHAR(150) ); -CREATE TABLE categorie ( +CREATE TABLE IF NOT EXISTS categorie ( id BIGSERIAL PRIMARY KEY, nom VARCHAR(20) UNIQUE NOT NULL, annee_min INT, @@ -37,7 +37,7 @@ CREATE TABLE categorie ( tarif_base DECIMAL(10,2) NOT NULL ); -CREATE TABLE licence ( +CREATE TABLE IF NOT EXISTS licence ( id BIGSERIAL PRIMARY KEY, adherent_id BIGINT NOT NULL, categorie_id BIGINT NOT NULL, @@ -47,7 +47,7 @@ CREATE TABLE licence ( CONSTRAINT fk_licence_categorie FOREIGN KEY (categorie_id) REFERENCES categorie(id) ); -CREATE TABLE paiement ( +CREATE TABLE IF NOT EXISTS paiement ( id BIGSERIAL PRIMARY KEY, licence_id BIGINT NOT NULL, montant DECIMAL(10,2) NOT NULL, @@ -56,14 +56,14 @@ CREATE TABLE paiement ( CONSTRAINT fk_paiement_licence FOREIGN KEY (licence_id) REFERENCES licence(id) ON DELETE CASCADE ); -CREATE TABLE equipement ( +CREATE TABLE IF NOT EXISTS equipement ( id BIGSERIAL PRIMARY KEY, nom VARCHAR(100) NOT NULL, description TEXT, obligatoire BOOLEAN NOT NULL DEFAULT FALSE ); -CREATE TABLE dotation ( +CREATE TABLE IF NOT EXISTS dotation ( id BIGSERIAL PRIMARY KEY, licence_id BIGINT NOT NULL, equipement_id BIGINT NOT NULL, diff --git a/as-talange-core/src/main/resources/db/migration/V2__add_mode_paiement.sql b/as-talange-core/src/main/resources/db/migration/V2__add_mode_paiement.sql index ae8b25a..17c0dc3 100644 --- a/as-talange-core/src/main/resources/db/migration/V2__add_mode_paiement.sql +++ b/as-talange-core/src/main/resources/db/migration/V2__add_mode_paiement.sql @@ -1,12 +1,18 @@ -CREATE TABLE mode_paiement ( +CREATE TABLE IF NOT EXISTS mode_paiement ( id BIGSERIAL PRIMARY KEY, nom VARCHAR(50) UNIQUE NOT NULL ); -INSERT INTO mode_paiement (nom) VALUES ('Espèces'), ('Chèque'), ('Pass Sport'), ('Virement'); +INSERT INTO mode_paiement (nom) VALUES ('Espèces'), ('Chèque'), ('Pass Sport'), ('Virement') +ON CONFLICT (nom) DO NOTHING; -ALTER TABLE paiement ADD COLUMN mode_paiement_id BIGINT; +ALTER TABLE paiement ADD COLUMN IF NOT EXISTS mode_paiement_id BIGINT; -ALTER TABLE paiement ADD CONSTRAINT fk_paiement_mode FOREIGN KEY (mode_paiement_id) REFERENCES mode_paiement(id); +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_paiement_mode') THEN + ALTER TABLE paiement ADD CONSTRAINT fk_paiement_mode FOREIGN KEY (mode_paiement_id) REFERENCES mode_paiement(id); + END IF; +END $$; -ALTER TABLE paiement DROP COLUMN mode_paiement; +ALTER TABLE paiement DROP COLUMN IF EXISTS mode_paiement; diff --git a/as-talange-core/src/main/resources/db/migration/V3__insert_default_data.sql b/as-talange-core/src/main/resources/db/migration/V3__insert_default_data.sql index 7006bea..1407c4f 100644 --- a/as-talange-core/src/main/resources/db/migration/V3__insert_default_data.sql +++ b/as-talange-core/src/main/resources/db/migration/V3__insert_default_data.sql @@ -1,9 +1,11 @@ -INSERT INTO role (name) VALUES ('ROLE_ADMIN'), ('ROLE_USER'); +INSERT INTO role (name) VALUES ('ROLE_ADMIN'), ('ROLE_USER') ON CONFLICT (name) DO NOTHING; -- Password is "Talange2026!" hashed with Argon2id -INSERT INTO app_user (username, password, enabled) VALUES ('Ucef', '$argon2id$v=19$m=65536,t=3,p=4$q29E/VM1esZVxo9HufgILQ$Nzb+rwwsZUMy04BbewYum2A8L8ujs9VZj9VJ/609Am0', true); +INSERT INTO app_user (username, password, enabled) VALUES ('Ucef', '$argon2id$v=19$m=65536,t=3,p=4$q29E/VM1esZVxo9HufgILQ$Nzb+rwwsZUMy04BbewYum2A8L8ujs9VZj9VJ/609Am0', true) +ON CONFLICT (username) DO NOTHING; -INSERT INTO user_role (user_id, role_id) VALUES ((SELECT id FROM app_user WHERE username = 'Ucef'), (SELECT id FROM role WHERE name = 'ROLE_ADMIN')); +INSERT INTO user_role (user_id, role_id) VALUES ((SELECT id FROM app_user WHERE username = 'Ucef'), (SELECT id FROM role WHERE name = 'ROLE_ADMIN')) +ON CONFLICT (user_id, role_id) DO NOTHING; INSERT INTO categorie (nom, annee_min, annee_max, tarif_base) VALUES ('U6', 2020, 2020, 100.00), @@ -14,10 +16,14 @@ INSERT INTO categorie (nom, annee_min, annee_max, tarif_base) VALUES ('U11', 2015, 2015, 130.00), ('U12', 2014, 2014, 140.00), ('U13', 2013, 2013, 140.00), -('Senior', 1900, 2005, 180.00); +('Senior', 1900, 2005, 180.00) +ON CONFLICT (nom) DO NOTHING; -INSERT INTO equipement (nom, obligatoire) VALUES -('Maillot', true), -('Short', true), -('Chaussettes', true), -('Survêtement', false); +INSERT INTO equipement (nom, obligatoire) +SELECT 'Maillot', true WHERE NOT EXISTS (SELECT 1 FROM equipement WHERE nom = 'Maillot'); +INSERT INTO equipement (nom, obligatoire) +SELECT 'Short', true WHERE NOT EXISTS (SELECT 1 FROM equipement WHERE nom = 'Short'); +INSERT INTO equipement (nom, obligatoire) +SELECT 'Chaussettes', true WHERE NOT EXISTS (SELECT 1 FROM equipement WHERE nom = 'Chaussettes'); +INSERT INTO equipement (nom, obligatoire) +SELECT 'Survêtement', false WHERE NOT EXISTS (SELECT 1 FROM equipement WHERE nom = 'Survêtement'); diff --git a/as-talange-core/src/main/resources/db/migration/V4__add_residency_pricing.sql b/as-talange-core/src/main/resources/db/migration/V4__add_residency_pricing.sql index d279275..bfbcf88 100644 --- a/as-talange-core/src/main/resources/db/migration/V4__add_residency_pricing.sql +++ b/as-talange-core/src/main/resources/db/migration/V4__add_residency_pricing.sql @@ -1,8 +1,8 @@ -- Ajouter la colonne pour savoir si l'adhérent est résident de Talange (par défaut oui pour les existants) -ALTER TABLE adherent ADD COLUMN resident_talange BOOLEAN DEFAULT TRUE; +ALTER TABLE adherent ADD COLUMN IF NOT EXISTS resident_talange BOOLEAN DEFAULT TRUE; -- Ajouter le tarif extérieur aux catégories -ALTER TABLE categorie ADD COLUMN tarif_exterieur DECIMAL(10,2); +ALTER TABLE categorie ADD COLUMN IF NOT EXISTS tarif_exterieur DECIMAL(10,2); -- Par défaut, mettre le tarif extérieur égal au tarif de base pour ne pas casser les licences existantes -UPDATE categorie SET tarif_exterieur = tarif_base; +UPDATE categorie SET tarif_exterieur = tarif_base*1.2 WHERE tarif_exterieur IS NULL; diff --git a/as-talange-core/src/main/resources/db/migration/V5__add_numero_licence.sql b/as-talange-core/src/main/resources/db/migration/V5__add_numero_licence.sql index 29548b1..856f363 100644 --- a/as-talange-core/src/main/resources/db/migration/V5__add_numero_licence.sql +++ b/as-talange-core/src/main/resources/db/migration/V5__add_numero_licence.sql @@ -1 +1 @@ -ALTER TABLE licence ADD COLUMN numero_licence VARCHAR(50); +ALTER TABLE licence ADD COLUMN IF NOT EXISTS numero_licence VARCHAR(50);