-- Migration: 070_fix_users_user_roles_uuid.sql -- Description: Finalisation de la migration UUID pour users et user_roles + Création federated_identities -- Context: Lab Environment (Destructive changes authorized) CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; CREATE EXTENSION IF NOT EXISTS "pgcrypto"; -- ================================================================= -- 1. NETTOYAGE ET MIGRATION TABLE USERS -- ================================================================= -- On commence par supprimer la PK 'users_pkey' en CASCADE. -- Cela va supprimer toutes les Foreign Keys (FK) qui pointaient vers l'ancien users.id (bigint). -- C'est la méthode "Clean Slate" pour le lab. ALTER TABLE users DROP CONSTRAINT IF EXISTS users_pkey CASCADE; -- Si la colonne id_uuid n'existe pas (cas où migration rejouée ou etat bizarre), on s'assure d'en avoir une DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'users' AND column_name = 'id_uuid') THEN ALTER TABLE users ADD COLUMN id_uuid UUID DEFAULT gen_random_uuid(); END IF; END $$; -- On s'assure que tout le monde a un UUID UPDATE users SET id_uuid = gen_random_uuid() WHERE id_uuid IS NULL; -- Suppression de l'ancien ID (BigInt) ALTER TABLE users DROP COLUMN IF EXISTS id; -- Renommage id_uuid -> id DO $$ BEGIN IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'users' AND column_name = 'id_uuid') THEN ALTER TABLE users RENAME COLUMN id_uuid TO id; END IF; END $$; -- Définition de la nouvelle Primary Key UUID ALTER TABLE users ADD PRIMARY KEY (id); -- ================================================================= -- 2. RÉPARATION DES TABLES ENFANTS (Int -> UUID) -- ================================================================= -- Pour ces tables, on supprime l'ancienne colonne user_id (int) et on la recrée en UUID. -- Comme c'est un lab sans data, on ne cherche pas à migrer la valeur int. DO $$ DECLARE tables_to_fix text[] := ARRAY[ 'email_verification_tokens', 'password_reset_tokens', 'sessions', 'user_sessions', 'track_plays', 'track_history', 'bitrate_adaptation_logs', 'playback_analytics' ]; tbl text; BEGIN FOREACH tbl IN ARRAY tables_to_fix LOOP IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = tbl) THEN -- Supprimer l'ancienne colonne (et ses contraintes résiduelles si cascade a raté) EXECUTE 'ALTER TABLE ' || quote_ident(tbl) || ' DROP COLUMN IF EXISTS user_id CASCADE'; -- Créer la nouvelle colonne EXECUTE 'ALTER TABLE ' || quote_ident(tbl) || ' ADD COLUMN user_id UUID NOT NULL'; -- Ajouter la FK EXECUTE 'ALTER TABLE ' || quote_ident(tbl) || ' ADD CONSTRAINT fk_' || tbl || '_users FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE'; RAISE NOTICE 'Table % : user_id migré en UUID', tbl; END IF; END LOOP; END $$; -- Cas spécifique : Rooms (creator_id ou owner_id selon versions) DO $$ BEGIN IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'rooms' AND column_name = 'creator_id') THEN ALTER TABLE rooms DROP COLUMN creator_id CASCADE; ALTER TABLE rooms ADD COLUMN creator_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE; END IF; IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'rooms' AND column_name = 'owner_id') THEN ALTER TABLE rooms DROP COLUMN owner_id CASCADE; ALTER TABLE rooms ADD COLUMN owner_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE; END IF; END $$; -- ================================================================= -- 3. MIGRATION TABLE USER_ROLES -- ================================================================= -- id (pk bigint -> uuid) -- assigned_by (bigint -> uuid) -- user_id (déjà uuid mais FK à vérifier) -- Drop PK ALTER TABLE user_roles DROP CONSTRAINT IF EXISTS user_roles_pkey CASCADE; -- Fix ID (PK) ALTER TABLE user_roles DROP COLUMN IF EXISTS id; ALTER TABLE user_roles ADD COLUMN id UUID PRIMARY KEY DEFAULT gen_random_uuid(); -- Fix Assigned By ALTER TABLE user_roles DROP COLUMN IF EXISTS assigned_by; ALTER TABLE user_roles ADD COLUMN assigned_by UUID REFERENCES users(id) ON DELETE SET NULL; -- Fix User ID (S'assurer que la FK pointe bien vers le nouvel ID UUID de users) -- Note: La colonne user_id est déjà UUID d'après le prompt, on recrée juste la FK pour être sûr. ALTER TABLE user_roles DROP CONSTRAINT IF EXISTS user_roles_user_id_fkey; -- nom standard probable ALTER TABLE user_roles ADD CONSTRAINT fk_user_roles_users FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; -- ================================================================= -- 4. CRÉATION TABLE FEDERATED_IDENTITIES -- ================================================================= -- Attendue par oauth_service.go CREATE TABLE IF NOT EXISTS federated_identities ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, provider TEXT NOT NULL, provider_id TEXT NOT NULL, email TEXT, display_name TEXT, avatar_url TEXT, access_token TEXT, refresh_token TEXT, expires_at TIMESTAMP WITH TIME ZONE, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); -- Indexs utiles CREATE INDEX IF NOT EXISTS idx_federated_identities_user_id ON federated_identities(user_id); CREATE INDEX IF NOT EXISTS idx_federated_identities_provider_id ON federated_identities(provider, provider_id); -- ================================================================= -- 5. VÉRIFICATION FINALE (Tracks & Playlists) -- ================================================================= -- On s'assure que les tables critiques Tracks et Playlists ont bien leurs FKs attachées -- (Au cas où le CASCADE du début aurait sauté leurs FKs) DO $$ BEGIN -- Tracks IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE table_name = 'tracks' AND constraint_type = 'FOREIGN KEY') THEN ALTER TABLE tracks ADD CONSTRAINT fk_tracks_users FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; END IF; -- Playlists IF NOT EXISTS (SELECT 1 FROM information_schema.table_constraints WHERE table_name = 'playlists' AND constraint_type = 'FOREIGN KEY') THEN ALTER TABLE playlists ADD CONSTRAINT fk_playlists_users FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; END IF; END $$;