Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
307 lines
12 KiB
SQL
307 lines
12 KiB
SQL
-- Migration: Convertir users.id de BIGINT vers UUID
|
|
-- CRITIQUE: Cette migration doit être exécutée AVANT tout déploiement utilisant les nouveaux modèles UUID
|
|
-- Date: 2024-11-27
|
|
-- Impact: BREAKING CHANGE - Toutes les FK doivent être migrées
|
|
|
|
-- =====================================================
|
|
-- ÉTAPE 1: Créer une colonne temporaire UUID
|
|
-- =====================================================
|
|
|
|
-- Activer l'extension UUID si pas déjà fait
|
|
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
|
CREATE EXTENSION IF NOT EXISTS "pgcrypto"; -- Pour gen_random_uuid()
|
|
|
|
-- Ajouter une colonne temporaire pour stocker les nouveaux UUIDs
|
|
ALTER TABLE users ADD COLUMN IF NOT EXISTS id_uuid UUID;
|
|
|
|
-- Générer un UUID pour chaque utilisateur existant (mapping déterministe depuis l'ID)
|
|
-- Note: On utilise uuid_generate_v5 pour créer un UUID déterministe basé sur l'ID existant
|
|
UPDATE users
|
|
SET id_uuid = uuid_generate_v5(
|
|
'6ba7b810-9dad-11d1-80b4-00c04fd430c8'::uuid, -- Namespace UUID arbitraire mais fixe
|
|
id::text
|
|
)
|
|
WHERE id_uuid IS NULL;
|
|
|
|
-- =====================================================
|
|
-- ÉTAPE 2: Migrer les tables dépendantes (FK)
|
|
-- =====================================================
|
|
|
|
-- Pour chaque table avec user_id en BIGINT, créer une colonne temporaire UUID
|
|
|
|
-- user_roles
|
|
ALTER TABLE user_roles ADD COLUMN IF NOT EXISTS user_id_uuid UUID;
|
|
UPDATE user_roles ur
|
|
SET user_id_uuid = u.id_uuid
|
|
FROM users u
|
|
WHERE ur.user_id = u.id AND ur.user_id_uuid IS NULL;
|
|
|
|
-- tracks
|
|
ALTER TABLE tracks ADD COLUMN IF NOT EXISTS user_id_uuid UUID;
|
|
UPDATE tracks t
|
|
SET user_id_uuid = u.id_uuid
|
|
FROM users u
|
|
WHERE t.user_id = u.id AND t.user_id_uuid IS NULL;
|
|
|
|
-- playlists
|
|
ALTER TABLE playlists ADD COLUMN IF NOT EXISTS user_id_uuid UUID;
|
|
UPDATE playlists p
|
|
SET user_id_uuid = u.id_uuid
|
|
FROM users u
|
|
WHERE p.user_id = u.id AND p.user_id_uuid IS NULL;
|
|
|
|
-- refresh_tokens
|
|
ALTER TABLE refresh_tokens ADD COLUMN IF NOT EXISTS user_id_uuid UUID;
|
|
UPDATE refresh_tokens rt
|
|
SET user_id_uuid = u.id_uuid
|
|
FROM users u
|
|
WHERE rt.user_id = u.id AND rt.user_id_uuid IS NULL;
|
|
|
|
-- sessions (déjà en UUID, mais vérifier cohérence)
|
|
-- Si sessions.user_id est déjà UUID, créer un mapping inverse
|
|
-- Note: Cette table semble déjà utiliser UUID, donc on va juste s'assurer de la cohérence
|
|
-- UPDATE sessions s SET user_id = u.id_uuid FROM users u WHERE ... (si nécessaire)
|
|
|
|
-- messages
|
|
ALTER TABLE messages ADD COLUMN IF NOT EXISTS sender_id_uuid UUID;
|
|
UPDATE messages m
|
|
SET sender_id_uuid = u.id_uuid
|
|
FROM users u
|
|
WHERE m.sender_id = u.id AND m.sender_id_uuid IS NULL;
|
|
|
|
-- rooms (owner_id)
|
|
ALTER TABLE rooms ADD COLUMN IF NOT EXISTS owner_id_uuid UUID;
|
|
UPDATE rooms r
|
|
SET owner_id_uuid = u.id_uuid
|
|
FROM users u
|
|
WHERE r.owner_id = u.id AND r.owner_id_uuid IS NULL;
|
|
|
|
-- room_members
|
|
ALTER TABLE room_members ADD COLUMN IF NOT EXISTS user_id_uuid UUID;
|
|
UPDATE room_members rm
|
|
SET user_id_uuid = u.id_uuid
|
|
FROM users u
|
|
WHERE rm.user_id = u.id AND rm.user_id_uuid IS NULL;
|
|
|
|
-- track_likes
|
|
ALTER TABLE track_likes ADD COLUMN IF NOT EXISTS user_id_uuid UUID;
|
|
UPDATE track_likes tl
|
|
SET user_id_uuid = u.id_uuid
|
|
FROM users u
|
|
WHERE tl.user_id = u.id AND tl.user_id_uuid IS NULL;
|
|
|
|
-- track_comments
|
|
ALTER TABLE track_comments ADD COLUMN IF NOT EXISTS user_id_uuid UUID;
|
|
UPDATE track_comments tc
|
|
SET user_id_uuid = u.id_uuid
|
|
FROM users u
|
|
WHERE tc.user_id = u.id AND tc.user_id_uuid IS NULL;
|
|
|
|
-- track_shares
|
|
ALTER TABLE track_shares ADD COLUMN IF NOT EXISTS user_id_uuid UUID;
|
|
UPDATE track_shares ts
|
|
SET user_id_uuid = u.id_uuid
|
|
FROM users u
|
|
WHERE ts.user_id = u.id AND ts.user_id_uuid IS NULL;
|
|
|
|
-- playlist_collaborators
|
|
ALTER TABLE playlist_collaborators ADD COLUMN IF NOT EXISTS user_id_uuid UUID;
|
|
UPDATE playlist_collaborators pc
|
|
SET user_id_uuid = u.id_uuid
|
|
FROM users u
|
|
WHERE pc.user_id = u.id AND pc.user_id_uuid IS NULL;
|
|
|
|
-- playlist_follows
|
|
ALTER TABLE playlist_follows ADD COLUMN IF NOT EXISTS user_id_uuid UUID;
|
|
UPDATE playlist_follows pf
|
|
SET user_id_uuid = u.id_uuid
|
|
FROM users u
|
|
WHERE pf.user_id = u.id AND pf.user_id_uuid IS NULL;
|
|
|
|
-- user_settings
|
|
ALTER TABLE user_settings ADD COLUMN IF NOT EXISTS user_id_uuid UUID;
|
|
UPDATE user_settings us
|
|
SET user_id_uuid = u.id_uuid
|
|
FROM users u
|
|
WHERE us.user_id = u.id AND us.user_id_uuid IS NULL;
|
|
|
|
-- =====================================================
|
|
-- ÉTAPE 3: Supprimer anciennes colonnes et renommer UUID
|
|
-- =====================================================
|
|
|
|
-- NOTE: Ces étapes sont DESTRUCTIVES et ne peuvent être annulées sans backup
|
|
-- En production, exécuter avec précaution et APRÈS validation complète
|
|
|
|
-- Supprimer les anciennes FK constraints
|
|
ALTER TABLE user_roles DROP CONSTRAINT IF EXISTS user_roles_user_id_fkey;
|
|
ALTER TABLE tracks DROP CONSTRAINT IF EXISTS tracks_user_id_fkey;
|
|
ALTER TABLE playlists DROP CONSTRAINT IF EXISTS playlists_user_id_fkey;
|
|
ALTER TABLE refresh_tokens DROP CONSTRAINT IF EXISTS refresh_tokens_user_id_fkey;
|
|
ALTER TABLE messages DROP CONSTRAINT IF EXISTS messages_sender_id_fkey;
|
|
ALTER TABLE rooms DROP CONSTRAINT IF EXISTS rooms_owner_id_fkey;
|
|
ALTER TABLE room_members DROP CONSTRAINT IF EXISTS room_members_user_id_fkey;
|
|
ALTER TABLE track_likes DROP CONSTRAINT IF EXISTS track_likes_user_id_fkey;
|
|
ALTER TABLE track_comments DROP CONSTRAINT IF EXISTS track_comments_user_id_fkey;
|
|
ALTER TABLE track_shares DROP CONSTRAINT IF EXISTS track_shares_user_id_fkey;
|
|
ALTER TABLE playlist_collaborators DROP CONSTRAINT IF EXISTS playlist_collaborators_user_id_fkey;
|
|
ALTER TABLE playlist_follows DROP CONSTRAINT IF EXISTS playlist_follows_user_id_fkey;
|
|
ALTER TABLE user_settings DROP CONSTRAINT IF EXISTS user_settings_user_id_fkey;
|
|
|
|
-- Supprimer anciennes colonnes INT
|
|
ALTER TABLE user_roles DROP COLUMN IF EXISTS user_id;
|
|
ALTER TABLE tracks DROP COLUMN IF EXISTS user_id;
|
|
ALTER TABLE playlists DROP COLUMN IF EXISTS user_id;
|
|
ALTER TABLE refresh_tokens DROP COLUMN IF EXISTS user_id;
|
|
ALTER TABLE messages DROP COLUMN IF EXISTS sender_id;
|
|
ALTER TABLE rooms DROP COLUMN IF EXISTS owner_id;
|
|
ALTER TABLE room_members DROP COLUMN IF EXISTS user_id;
|
|
ALTER TABLE track_likes DROP COLUMN IF EXISTS user_id;
|
|
ALTER TABLE track_comments DROP COLUMN IF EXISTS user_id;
|
|
ALTER TABLE track_shares DROP COLUMN IF EXISTS user_id;
|
|
ALTER TABLE playlist_collaborators DROP COLUMN IF EXISTS user_id;
|
|
ALTER TABLE playlist_follows DROP COLUMN IF EXISTS user_id;
|
|
ALTER TABLE user_settings DROP COLUMN IF EXISTS user_id;
|
|
|
|
-- Renommer colonnes UUID vers le nom standard
|
|
ALTER TABLE user_roles RENAME COLUMN user_id_uuid TO user_id;
|
|
ALTER TABLE tracks RENAME COLUMN user_id_uuid TO user_id;
|
|
ALTER TABLE playlists RENAME COLUMN user_id_uuid TO user_id;
|
|
ALTER TABLE refresh_tokens RENAME COLUMN user_id_uuid TO user_id;
|
|
ALTER TABLE messages RENAME COLUMN sender_id_uuid TO sender_id;
|
|
ALTER TABLE rooms RENAME COLUMN owner_id_uuid TO owner_id;
|
|
ALTER TABLE room_members RENAME COLUMN user_id_uuid TO user_id;
|
|
ALTER TABLE track_likes RENAME COLUMN user_id_uuid TO user_id;
|
|
ALTER TABLE track_comments RENAME COLUMN user_id_uuid TO user_id;
|
|
ALTER TABLE track_shares RENAME COLUMN user_id_uuid TO user_id;
|
|
ALTER TABLE playlist_collaborators RENAME COLUMN user_id_uuid TO user_id;
|
|
ALTER TABLE playlist_follows RENAME COLUMN user_id_uuid TO user_id;
|
|
ALTER TABLE user_settings RENAME COLUMN user_id_uuid TO user_id;
|
|
|
|
-- Définir NOT NULL sur les colonnes
|
|
ALTER TABLE user_roles ALTER COLUMN user_id SET NOT NULL;
|
|
ALTER TABLE tracks ALTER COLUMN user_id SET NOT NULL;
|
|
ALTER TABLE playlists ALTER COLUMN user_id SET NOT NULL;
|
|
ALTER TABLE refresh_tokens ALTER COLUMN user_id SET NOT NULL;
|
|
ALTER TABLE messages ALTER COLUMN sender_id SET NOT NULL;
|
|
ALTER TABLE rooms ALTER COLUMN owner_id SET NOT NULL;
|
|
ALTER TABLE room_members ALTER COLUMN user_id SET NOT NULL;
|
|
ALTER TABLE track_likes ALTER COLUMN user_id SET NOT NULL;
|
|
ALTER TABLE track_comments ALTER COLUMN user_id SET NOT NULL;
|
|
ALTER TABLE track_shares ALTER COLUMN user_id SET NOT NULL;
|
|
ALTER TABLE playlist_collaborators ALTER COLUMN user_id SET NOT NULL;
|
|
ALTER TABLE playlist_follows ALTER COLUMN user_id SET NOT NULL;
|
|
ALTER TABLE user_settings ALTER COLUMN user_id SET NOT NULL;
|
|
|
|
-- =====================================================
|
|
-- ÉTAPE 4: Migrer users.id vers UUID
|
|
-- =====================================================
|
|
|
|
-- Supprimer l'ancienne colonne id (BIGINT)
|
|
ALTER TABLE users DROP CONSTRAINT IF EXISTS users_pkey;
|
|
ALTER TABLE users DROP COLUMN IF EXISTS id;
|
|
|
|
-- Renommer id_uuid vers id
|
|
ALTER TABLE users RENAME COLUMN id_uuid TO id;
|
|
|
|
-- Définir comme PRIMARY KEY
|
|
ALTER TABLE users ADD PRIMARY KEY (id);
|
|
|
|
-- =====================================================
|
|
-- ÉTAPE 5: Recréer les FK constraints avec UUID
|
|
-- =====================================================
|
|
|
|
ALTER TABLE user_roles
|
|
ADD CONSTRAINT fk_user_roles_users
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
|
|
|
ALTER TABLE tracks
|
|
ADD CONSTRAINT fk_tracks_users
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
|
|
|
ALTER TABLE playlists
|
|
ADD CONSTRAINT fk_playlists_users
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
|
|
|
ALTER TABLE refresh_tokens
|
|
ADD CONSTRAINT fk_refresh_tokens_users
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
|
|
|
ALTER TABLE messages
|
|
ADD CONSTRAINT fk_messages_users
|
|
FOREIGN KEY (sender_id) REFERENCES users(id) ON DELETE CASCADE;
|
|
|
|
ALTER TABLE rooms
|
|
ADD CONSTRAINT fk_rooms_users
|
|
FOREIGN KEY (owner_id) REFERENCES users(id) ON DELETE CASCADE;
|
|
|
|
ALTER TABLE room_members
|
|
ADD CONSTRAINT fk_room_members_users
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
|
|
|
ALTER TABLE track_likes
|
|
ADD CONSTRAINT fk_track_likes_users
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
|
|
|
ALTER TABLE track_comments
|
|
ADD CONSTRAINT fk_track_comments_users
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
|
|
|
ALTER TABLE track_shares
|
|
ADD CONSTRAINT fk_track_shares_users
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
|
|
|
ALTER TABLE playlist_collaborators
|
|
ADD CONSTRAINT fk_playlist_collaborators_users
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
|
|
|
ALTER TABLE playlist_follows
|
|
ADD CONSTRAINT fk_playlist_follows_users
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
|
|
|
ALTER TABLE user_settings
|
|
ADD CONSTRAINT fk_user_settings_users
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
|
|
|
-- =====================================================
|
|
-- ÉTAPE 6: Recréer les indexes
|
|
-- =====================================================
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_user_roles_user_id ON user_roles(user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_tracks_user_id ON tracks(user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_playlists_user_id ON playlists(user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_refresh_tokens_user_id ON refresh_tokens(user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_messages_sender_id ON messages(sender_id);
|
|
CREATE INDEX IF NOT EXISTS idx_rooms_owner_id ON rooms(owner_id);
|
|
CREATE INDEX IF NOT EXISTS idx_room_members_user_id ON room_members(user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_track_likes_user_id ON track_likes(user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_track_comments_user_id ON track_comments(user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_track_shares_user_id ON track_shares(user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_playlist_collaborators_user_id ON playlist_collaborators(user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_playlist_follows_user_id ON playlist_follows(user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_user_settings_user_id ON user_settings(user_id);
|
|
|
|
-- =====================================================
|
|
-- VERIFICATION
|
|
-- =====================================================
|
|
|
|
-- Vérifier que tous les users ont un UUID valide
|
|
DO $$
|
|
DECLARE
|
|
user_count INT;
|
|
null_uuid_count INT;
|
|
BEGIN
|
|
SELECT COUNT(*) INTO user_count FROM users;
|
|
SELECT COUNT(*) INTO null_uuid_count FROM users WHERE id IS NULL;
|
|
|
|
RAISE NOTICE 'Migration UUID - Total users: %, Users avec UUID NULL: %', user_count, null_uuid_count;
|
|
|
|
IF null_uuid_count > 0 THEN
|
|
RAISE EXCEPTION 'Migration échouée: % utilisateurs ont un UUID NULL', null_uuid_count;
|
|
END IF;
|
|
END $$;
|
|
|
|
-- Vérifier l'intégrité référentielle
|
|
-- TODO: Ajouter des checks supplémentaires si nécessaire
|
|
|
|
COMMENT ON COLUMN users.id IS 'UUID unique de l''utilisateur (migré de BIGINT)';
|
|
|