chore(backend): remove legacy migrations and main file

This commit is contained in:
okinrev 2025-12-06 11:50:22 +01:00
parent ad46483da0
commit 4f6ced6494
45 changed files with 0 additions and 2063 deletions

View file

@ -1,78 +0,0 @@
package main
import (
"context"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"veza-backend-api/internal/config"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
func main() {
// Initialiser la configuration
cfg, err := config.NewConfig()
if err != nil {
log.Fatalf("Failed to initialize configuration: %v", err)
}
defer cfg.Close()
// Configurer Gin
if os.Getenv("GIN_MODE") == "release" {
gin.SetMode(gin.ReleaseMode)
}
// Créer le router
router := gin.New()
// Configurer les middlewares globaux
cfg.SetupMiddleware(router)
// Configurer les routes
cfg.SetupRoutes(router)
// Configuration du serveur
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
server := &http.Server{
Addr: ":" + port,
Handler: router,
ReadTimeout: 15 * time.Second,
WriteTimeout: 15 * time.Second,
IdleTimeout: 60 * time.Second,
}
// Démarrer le serveur en arrière-plan
go func() {
cfg.Logger.Info("Starting server", zap.String("port", port))
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
cfg.Logger.Fatal("Failed to start server", zap.Error(err))
}
}()
// Attendre un signal d'arrêt
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
cfg.Logger.Info("Shutting down server...")
// Arrêter le serveur gracieusement
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
if err := server.Shutdown(ctx); err != nil {
cfg.Logger.Fatal("Server forced to shutdown", zap.Error(err))
}
cfg.Logger.Info("Server exited")
}

View file

@ -1,44 +0,0 @@
-- Migration: Create users table
-- Core user table for authentication and profile
CREATE TABLE IF NOT EXISTS users (
id BIGSERIAL PRIMARY KEY,
username VARCHAR(30) NOT NULL,
slug VARCHAR(255),
email VARCHAR(255) NOT NULL,
password_hash VARCHAR(255),
token_version INTEGER NOT NULL DEFAULT 0,
first_name VARCHAR(100),
last_name VARCHAR(100),
avatar TEXT,
bio TEXT,
location VARCHAR(100),
birthdate TIMESTAMP WITH TIME ZONE,
gender VARCHAR(20),
username_changed_at TIMESTAMP WITH TIME ZONE,
role VARCHAR(50) NOT NULL DEFAULT 'user',
is_active BOOLEAN DEFAULT TRUE,
is_verified BOOLEAN DEFAULT FALSE,
is_admin BOOLEAN DEFAULT FALSE,
is_public BOOLEAN DEFAULT TRUE,
last_login_at TIMESTAMP WITH TIME ZONE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP WITH TIME ZONE
);
-- Unique indexes with soft delete support
CREATE UNIQUE INDEX IF NOT EXISTS idx_users_email ON users(email) WHERE deleted_at IS NULL;
CREATE UNIQUE INDEX IF NOT EXISTS idx_users_username ON users(username) WHERE deleted_at IS NULL;
CREATE UNIQUE INDEX IF NOT EXISTS idx_users_slug ON users(slug) WHERE deleted_at IS NULL;
-- Performance indexes
CREATE INDEX IF NOT EXISTS idx_users_deleted_at ON users(deleted_at);
CREATE INDEX IF NOT EXISTS idx_users_created_at ON users(created_at DESC);
CREATE INDEX IF NOT EXISTS idx_users_is_active ON users(is_active) WHERE deleted_at IS NULL;
-- Comments
COMMENT ON TABLE users IS 'Core user accounts for authentication and profiles';
COMMENT ON COLUMN users.token_version IS 'Version number for JWT token invalidation';
COMMENT ON COLUMN users.slug IS 'URL-friendly unique identifier for user profile';

View file

@ -1,13 +0,0 @@
CREATE TABLE email_verification_tokens (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
token VARCHAR(255) NOT NULL UNIQUE,
expires_at TIMESTAMP NOT NULL,
used BOOLEAN NOT NULL DEFAULT FALSE,
created_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_email_verification_tokens_token ON email_verification_tokens(token);
CREATE INDEX idx_email_verification_tokens_user_id ON email_verification_tokens(user_id);
CREATE INDEX idx_email_verification_tokens_expires_at ON email_verification_tokens(expires_at);

View file

@ -1,15 +0,0 @@
-- T0191: Create password_reset_tokens table for password reset functionality
CREATE TABLE password_reset_tokens (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
token VARCHAR(255) NOT NULL UNIQUE,
expires_at TIMESTAMP NOT NULL,
used BOOLEAN NOT NULL DEFAULT FALSE,
created_at TIMESTAMP NOT NULL DEFAULT NOW()
);
-- Indexes for performance
CREATE INDEX idx_password_reset_tokens_token ON password_reset_tokens(token);
CREATE INDEX idx_password_reset_tokens_user_id ON password_reset_tokens(user_id);
CREATE INDEX idx_password_reset_tokens_expires_at ON password_reset_tokens(expires_at);

View file

@ -1,16 +0,0 @@
-- T0201: Create sessions table for tracking active user sessions
CREATE TABLE IF NOT EXISTS sessions (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
token_hash VARCHAR(255) NOT NULL UNIQUE,
ip_address VARCHAR(45),
user_agent TEXT,
expires_at TIMESTAMP NOT NULL,
last_activity TIMESTAMP NOT NULL DEFAULT NOW(),
created_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_sessions_user_id ON sessions(user_id);
CREATE INDEX IF NOT EXISTS idx_sessions_token_hash ON sessions(token_hash);
CREATE INDEX IF NOT EXISTS idx_sessions_expires_at ON sessions(expires_at);

View file

@ -1,7 +0,0 @@
-- T0218: Add Profile Privacy Settings
-- Add is_public column to users table for profile privacy control
ALTER TABLE users ADD COLUMN IF NOT EXISTS is_public BOOLEAN NOT NULL DEFAULT TRUE;
CREATE INDEX IF NOT EXISTS idx_users_is_public ON users(is_public);

View file

@ -1,12 +0,0 @@
-- T0219: Add Profile Slug Generation
-- Add slug column to users table for URL-friendly profile URLs
ALTER TABLE users ADD COLUMN IF NOT EXISTS slug VARCHAR(255);
CREATE UNIQUE INDEX IF NOT EXISTS idx_users_slug ON users(slug);
-- Populate existing users with slugs from their usernames
UPDATE users
SET slug = LOWER(REGEXP_REPLACE(username, '[^a-zA-Z0-9]', '-', 'g'))
WHERE slug IS NULL OR slug = '';

View file

@ -1,60 +0,0 @@
-- T0241: Create Role Management Database Models
-- Create tables for roles, permissions, user_roles, and role_permissions
-- Table roles
CREATE TABLE IF NOT EXISTS roles (
id BIGSERIAL PRIMARY KEY,
name VARCHAR(50) UNIQUE NOT NULL,
display_name VARCHAR(100) NOT NULL,
description TEXT,
is_system BOOLEAN DEFAULT FALSE,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Table permissions
CREATE TABLE IF NOT EXISTS permissions (
id BIGSERIAL PRIMARY KEY,
name VARCHAR(100) UNIQUE NOT NULL,
resource VARCHAR(50) NOT NULL,
action VARCHAR(50) NOT NULL,
description TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Table user_roles
CREATE TABLE IF NOT EXISTS user_roles (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
role_id BIGINT NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
assigned_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
assigned_by BIGINT REFERENCES users(id),
expires_at TIMESTAMP,
is_active BOOLEAN DEFAULT TRUE,
UNIQUE(user_id, role_id)
);
-- Table role_permissions
CREATE TABLE IF NOT EXISTS role_permissions (
role_id BIGINT NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
permission_id BIGINT NOT NULL REFERENCES permissions(id) ON DELETE CASCADE,
PRIMARY KEY (role_id, permission_id)
);
-- Indexes
CREATE INDEX IF NOT EXISTS idx_user_roles_user_id ON user_roles(user_id);
CREATE INDEX IF NOT EXISTS idx_user_roles_role_id ON user_roles(role_id);
CREATE INDEX IF NOT EXISTS idx_role_permissions_role_id ON role_permissions(role_id);
CREATE INDEX IF NOT EXISTS idx_role_permissions_permission_id ON role_permissions(permission_id);
-- Seed system roles
INSERT INTO roles (name, display_name, description, is_system) VALUES
('user', 'Utilisateur', 'Utilisateur standard avec accès de base', true),
('artist', 'Artiste', 'Créateur de contenu musical', true),
('producer', 'Producteur', 'Producteur musical', true),
('label', 'Label', 'Label de musique', true),
('moderator', 'Modérateur', 'Modération du contenu', true),
('admin', 'Administrateur', 'Administration complète', true)
ON CONFLICT (name) DO NOTHING;

View file

@ -1,62 +0,0 @@
-- T0244: Seed System Permissions
-- Create system permissions for the application
-- Tracks permissions
INSERT INTO permissions (name, resource, action, description) VALUES
('tracks:create', 'tracks', 'create', 'Create new tracks'),
('tracks:read', 'tracks', 'read', 'View tracks'),
('tracks:edit', 'tracks', 'edit', 'Edit tracks'),
('tracks:delete', 'tracks', 'delete', 'Delete tracks'),
('tracks:publish', 'tracks', 'publish', 'Publish tracks'),
('tracks:unpublish', 'tracks', 'unpublish', 'Unpublish tracks')
ON CONFLICT (name) DO NOTHING;
-- Users permissions
INSERT INTO permissions (name, resource, action, description) VALUES
('users:read', 'users', 'read', 'View users'),
('users:edit', 'users', 'edit', 'Edit users'),
('users:delete', 'users', 'delete', 'Delete users'),
('users:manage', 'users', 'manage', 'Full user management'),
('users:suspend', 'users', 'suspend', 'Suspend users'),
('users:unsuspend', 'users', 'unsuspend', 'Unsuspend users')
ON CONFLICT (name) DO NOTHING;
-- Roles permissions
INSERT INTO permissions (name, resource, action, description) VALUES
('roles:read', 'roles', 'read', 'View roles'),
('roles:create', 'roles', 'create', 'Create roles'),
('roles:edit', 'roles', 'edit', 'Edit roles'),
('roles:delete', 'roles', 'delete', 'Delete roles'),
('roles:assign', 'roles', 'assign', 'Assign roles to users')
ON CONFLICT (name) DO NOTHING;
-- Permissions management
INSERT INTO permissions (name, resource, action, description) VALUES
('permissions:read', 'permissions', 'read', 'View permissions'),
('permissions:create', 'permissions', 'create', 'Create permissions'),
('permissions:assign', 'permissions', 'assign', 'Assign permissions to roles')
ON CONFLICT (name) DO NOTHING;
-- Content moderation
INSERT INTO permissions (name, resource, action, description) VALUES
('content:moderate', 'content', 'moderate', 'Moderate content'),
('content:approve', 'content', 'approve', 'Approve content'),
('content:reject', 'content', 'reject', 'Reject content'),
('content:delete', 'content', 'delete', 'Delete content')
ON CONFLICT (name) DO NOTHING;
-- System administration
INSERT INTO permissions (name, resource, action, description) VALUES
('system:admin', 'system', 'admin', 'System administration'),
('system:config', 'system', 'config', 'Configure system settings'),
('system:logs', 'system', 'logs', 'View system logs'),
('system:backup', 'system', 'backup', 'Create system backups')
ON CONFLICT (name) DO NOTHING;
-- Analytics and reports
INSERT INTO permissions (name, resource, action, description) VALUES
('analytics:read', 'analytics', 'read', 'View analytics'),
('analytics:export', 'analytics', 'export', 'Export analytics data'),
('reports:generate', 'reports', 'generate', 'Generate reports')
ON CONFLICT (name) DO NOTHING;

View file

@ -1,33 +0,0 @@
-- T0251: Create Track Database Model
-- Create table tracks with all required fields
-- Table tracks
CREATE TABLE IF NOT EXISTS tracks (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
title VARCHAR(255) NOT NULL,
artist VARCHAR(255),
album VARCHAR(255),
duration INTEGER NOT NULL,
genre VARCHAR(100),
year INTEGER DEFAULT 0,
file_path VARCHAR(500) NOT NULL,
file_size BIGINT NOT NULL,
format VARCHAR(10),
bitrate INTEGER DEFAULT 0,
sample_rate INTEGER DEFAULT 0,
waveform_path VARCHAR(500),
cover_art_path VARCHAR(500),
is_public BOOLEAN DEFAULT TRUE,
play_count BIGINT DEFAULT 0,
like_count BIGINT DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP
);
-- Indexes
CREATE INDEX IF NOT EXISTS idx_tracks_user_id ON tracks(user_id);
CREATE INDEX IF NOT EXISTS idx_tracks_is_public ON tracks(is_public);
CREATE INDEX IF NOT EXISTS idx_tracks_created_at ON tracks(created_at);

View file

@ -1,9 +0,0 @@
-- T0255: Add Track Upload Progress Tracking
-- Add status and status_message columns to tracks table
ALTER TABLE tracks ADD COLUMN IF NOT EXISTS status VARCHAR(20) DEFAULT 'uploading';
ALTER TABLE tracks ADD COLUMN IF NOT EXISTS status_message TEXT;
-- Create index on status for faster queries
CREATE INDEX IF NOT EXISTS idx_tracks_status ON tracks(status);

View file

@ -1,18 +0,0 @@
-- T0281: Create Track Like System Database Model
-- Create table track_likes with user_id, track_id, created_at and unique index
-- Table track_likes
CREATE TABLE IF NOT EXISTS track_likes (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
track_id BIGINT NOT NULL REFERENCES tracks(id) ON DELETE CASCADE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Indexes
CREATE INDEX IF NOT EXISTS idx_track_likes_user ON track_likes(user_id);
CREATE INDEX IF NOT EXISTS idx_track_likes_track ON track_likes(track_id);
-- Unique constraint to prevent duplicate likes (user can only like a track once)
CREATE UNIQUE INDEX IF NOT EXISTS idx_track_likes_unique ON track_likes(user_id, track_id);

View file

@ -1,17 +0,0 @@
CREATE TABLE track_comments (
id BIGSERIAL PRIMARY KEY,
track_id BIGINT NOT NULL REFERENCES tracks(id) ON DELETE CASCADE,
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
parent_id BIGINT REFERENCES track_comments(id) ON DELETE CASCADE,
content TEXT NOT NULL,
is_edited BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP
);
CREATE INDEX idx_track_comments_track_id ON track_comments(track_id);
CREATE INDEX idx_track_comments_user_id ON track_comments(user_id);
CREATE INDEX idx_track_comments_parent_id ON track_comments(parent_id);
CREATE INDEX idx_track_comments_created_at ON track_comments(created_at DESC);

View file

@ -1,25 +0,0 @@
-- Migration: Create track_plays table for playback analytics
-- T0291: Create Track Playback Analytics Database Model
CREATE TABLE track_plays (
id BIGSERIAL PRIMARY KEY,
track_id BIGINT NOT NULL REFERENCES tracks(id) ON DELETE CASCADE,
user_id BIGINT REFERENCES users(id) ON DELETE SET NULL,
duration INTEGER NOT NULL,
played_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
device VARCHAR(100),
ip_address VARCHAR(45),
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP
);
-- Indexes for performance
CREATE INDEX idx_track_plays_track_id ON track_plays(track_id);
CREATE INDEX idx_track_plays_user_id ON track_plays(user_id);
CREATE INDEX idx_track_plays_played_at ON track_plays(played_at DESC);
CREATE INDEX idx_track_plays_track_played ON track_plays(track_id, played_at DESC);
-- Index for soft deletes
CREATE INDEX idx_track_plays_deleted_at ON track_plays(deleted_at);

View file

@ -1,31 +0,0 @@
-- Migration: Create playlists and playlist_tracks tables
-- T0296: Create Playlist Database Model
CREATE TABLE IF NOT EXISTS playlists (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
title VARCHAR(200) NOT NULL,
description TEXT,
is_public BOOLEAN DEFAULT TRUE,
cover_url VARCHAR(500),
track_count INTEGER DEFAULT 0,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS playlist_tracks (
id BIGSERIAL PRIMARY KEY,
playlist_id BIGINT NOT NULL REFERENCES playlists(id) ON DELETE CASCADE,
track_id BIGINT NOT NULL REFERENCES tracks(id) ON DELETE CASCADE,
position INTEGER NOT NULL,
added_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE(playlist_id, track_id)
);
-- Indexes for performance
CREATE INDEX IF NOT EXISTS idx_playlists_user_id ON playlists(user_id);
CREATE INDEX IF NOT EXISTS idx_playlist_tracks_playlist_id ON playlist_tracks(playlist_id);
CREATE INDEX IF NOT EXISTS idx_playlist_tracks_track_id ON playlist_tracks(track_id);
CREATE INDEX IF NOT EXISTS idx_playlist_tracks_position ON playlist_tracks(playlist_id, position);

View file

@ -1,56 +0,0 @@
-- Migration: Create playlist_collaborators table
-- T0476: Create Playlist Collaboration Model
-- Create enum type for playlist permissions
DO $$ BEGIN
CREATE TYPE playlist_permission AS ENUM ('read', 'write', 'admin');
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
-- Create playlist_collaborators table
CREATE TABLE IF NOT EXISTS playlist_collaborators (
id BIGSERIAL PRIMARY KEY,
playlist_id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
permission VARCHAR(20) NOT NULL DEFAULT 'read',
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP,
-- Foreign keys
CONSTRAINT fk_playlist_collaborators_playlist
FOREIGN KEY (playlist_id)
REFERENCES playlists(id)
ON DELETE CASCADE,
CONSTRAINT fk_playlist_collaborators_user
FOREIGN KEY (user_id)
REFERENCES users(id)
ON DELETE CASCADE,
-- Unique constraint: un utilisateur ne peut être collaborateur qu'une fois par playlist
CONSTRAINT uq_playlist_collaborators_playlist_user
UNIQUE (playlist_id, user_id),
-- Check constraint: permission valide
CONSTRAINT chk_playlist_collaborators_permission
CHECK (permission IN ('read', 'write', 'admin'))
);
-- Create indexes
CREATE INDEX IF NOT EXISTS idx_playlist_collaborators_playlist_id
ON playlist_collaborators(playlist_id)
WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_playlist_collaborators_user_id
ON playlist_collaborators(user_id)
WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_playlist_collaborators_deleted_at
ON playlist_collaborators(deleted_at);
-- Add comment
COMMENT ON TABLE playlist_collaborators IS 'Table des collaborateurs de playlists avec leurs permissions';
COMMENT ON COLUMN playlist_collaborators.permission IS 'Permission du collaborateur: read (lecture), write (écriture), admin (administration)';

View file

@ -1,23 +0,0 @@
-- T0306: Create Track Sharing System Database Model
-- Create table track_shares with all required fields
-- Table track_shares
CREATE TABLE IF NOT EXISTS track_shares (
id BIGSERIAL PRIMARY KEY,
track_id BIGINT NOT NULL REFERENCES tracks(id) ON DELETE CASCADE,
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
share_token VARCHAR(255) UNIQUE NOT NULL,
permissions VARCHAR(50) DEFAULT 'read',
expires_at TIMESTAMP,
access_count BIGINT DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP
);
-- Indexes
CREATE INDEX IF NOT EXISTS idx_track_shares_track_id ON track_shares(track_id);
CREATE INDEX IF NOT EXISTS idx_track_shares_user_id ON track_shares(user_id);
CREATE INDEX IF NOT EXISTS idx_track_shares_share_token ON track_shares(share_token);
CREATE INDEX IF NOT EXISTS idx_track_shares_deleted_at ON track_shares(deleted_at);

View file

@ -1,55 +0,0 @@
-- Migration: Create playlist_follows table
-- T0489: Create Playlist Follow Feature
-- Create playlist_follows table
CREATE TABLE IF NOT EXISTS playlist_follows (
id BIGSERIAL PRIMARY KEY,
playlist_id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP,
-- Foreign keys
CONSTRAINT fk_playlist_follows_playlist
FOREIGN KEY (playlist_id)
REFERENCES playlists(id)
ON DELETE CASCADE,
CONSTRAINT fk_playlist_follows_user
FOREIGN KEY (user_id)
REFERENCES users(id)
ON DELETE CASCADE,
-- Unique constraint: un utilisateur ne peut suivre une playlist qu'une fois
CONSTRAINT uq_playlist_follows_playlist_user
UNIQUE (playlist_id, user_id)
);
-- Create indexes
CREATE INDEX IF NOT EXISTS idx_playlist_follows_playlist_id
ON playlist_follows(playlist_id)
WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_playlist_follows_user_id
ON playlist_follows(user_id)
WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_playlist_follows_deleted_at
ON playlist_follows(deleted_at);
-- Add comment
COMMENT ON TABLE playlist_follows IS 'Table des follows de playlists par les utilisateurs';
-- Add follower_count column to playlists table if it doesn't exist
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_name = 'playlists' AND column_name = 'follower_count'
) THEN
ALTER TABLE playlists ADD COLUMN follower_count INTEGER DEFAULT 0;
CREATE INDEX IF NOT EXISTS idx_playlists_follower_count ON playlists(follower_count);
END IF;
END $$;

View file

@ -1,27 +0,0 @@
-- T0321: Create Track Versioning Database Model
-- Create table track_versions for track versioning
-- Table track_versions
CREATE TABLE IF NOT EXISTS track_versions (
id BIGSERIAL PRIMARY KEY,
track_id BIGINT NOT NULL REFERENCES tracks(id) ON DELETE CASCADE,
version_number INTEGER NOT NULL,
file_path VARCHAR(500) NOT NULL,
file_size BIGINT NOT NULL,
changelog TEXT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP,
-- Unique constraint: one version number per track
UNIQUE(track_id, version_number)
);
-- Indexes for performance
CREATE INDEX IF NOT EXISTS idx_track_versions_track_id ON track_versions(track_id);
CREATE INDEX IF NOT EXISTS idx_track_versions_created_at ON track_versions(created_at DESC);
CREATE INDEX IF NOT EXISTS idx_track_versions_track_version ON track_versions(track_id, version_number DESC);
-- Index for soft deletes
CREATE INDEX IF NOT EXISTS idx_track_versions_deleted_at ON track_versions(deleted_at);

View file

@ -1,21 +0,0 @@
-- T0326: Create Track History Database Model
-- Create table track_history for tracking track modifications
-- Table track_history
CREATE TABLE IF NOT EXISTS track_history (
id BIGSERIAL PRIMARY KEY,
track_id BIGINT NOT NULL REFERENCES tracks(id) ON DELETE CASCADE,
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE SET NULL,
action VARCHAR(50) NOT NULL,
old_value TEXT,
new_value TEXT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- Indexes for performance
CREATE INDEX IF NOT EXISTS idx_track_history_track_id ON track_history(track_id);
CREATE INDEX IF NOT EXISTS idx_track_history_user_id ON track_history(user_id);
CREATE INDEX IF NOT EXISTS idx_track_history_action ON track_history(action);
CREATE INDEX IF NOT EXISTS idx_track_history_created_at ON track_history(created_at DESC);
CREATE INDEX IF NOT EXISTS idx_track_history_track_created ON track_history(track_id, created_at DESC);

View file

@ -1,19 +0,0 @@
-- T0331: Create HLS Streaming Database Model
-- Create table hls_streams for HLS streaming support
-- Table hls_streams
CREATE TABLE IF NOT EXISTS hls_streams (
id BIGSERIAL PRIMARY KEY,
track_id BIGINT NOT NULL REFERENCES tracks(id) ON DELETE CASCADE,
playlist_url VARCHAR(500) NOT NULL,
segments_count INTEGER NOT NULL DEFAULT 0,
bitrates JSONB NOT NULL DEFAULT '[]',
status VARCHAR(20) NOT NULL DEFAULT 'pending',
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- Indexes for performance
CREATE INDEX IF NOT EXISTS idx_hls_streams_track_id ON hls_streams(track_id);
CREATE INDEX IF NOT EXISTS idx_hls_streams_status ON hls_streams(status);

View file

@ -1,16 +0,0 @@
CREATE TABLE hls_transcode_queue (
id BIGSERIAL PRIMARY KEY,
track_id BIGINT NOT NULL REFERENCES tracks(id) ON DELETE CASCADE,
priority INTEGER NOT NULL DEFAULT 5,
status VARCHAR(20) NOT NULL DEFAULT 'pending',
retry_count INTEGER NOT NULL DEFAULT 0,
max_retries INTEGER NOT NULL DEFAULT 3,
error_message TEXT,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
started_at TIMESTAMP,
completed_at TIMESTAMP
);
CREATE INDEX idx_hls_transcode_queue_status ON hls_transcode_queue(status, priority DESC);
CREATE INDEX idx_hls_transcode_queue_track_id ON hls_transcode_queue(track_id);

View file

@ -1,18 +0,0 @@
-- T0346: Create Bitrate Adaptation Database Model
-- Migration pour créer la table bitrate_adaptation_logs
CREATE TABLE bitrate_adaptation_logs (
id BIGSERIAL PRIMARY KEY,
track_id BIGINT NOT NULL REFERENCES tracks(id) ON DELETE CASCADE,
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
old_bitrate INTEGER NOT NULL,
new_bitrate INTEGER NOT NULL,
reason VARCHAR(50) NOT NULL,
network_bandwidth INTEGER,
created_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_bitrate_adaptation_track_id ON bitrate_adaptation_logs(track_id);
CREATE INDEX idx_bitrate_adaptation_user_id ON bitrate_adaptation_logs(user_id);
CREATE INDEX idx_bitrate_adaptation_created_at ON bitrate_adaptation_logs(created_at);

View file

@ -1,20 +0,0 @@
-- T0356: Create Playback Analytics Database Model
-- Migration pour créer la table playback_analytics
CREATE TABLE playback_analytics (
id BIGSERIAL PRIMARY KEY,
track_id BIGINT NOT NULL REFERENCES tracks(id) ON DELETE CASCADE,
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
play_time INTEGER NOT NULL DEFAULT 0,
pause_count INTEGER NOT NULL DEFAULT 0,
seek_count INTEGER NOT NULL DEFAULT 0,
completion_rate DECIMAL(5,2) NOT NULL DEFAULT 0,
started_at TIMESTAMP NOT NULL,
ended_at TIMESTAMP,
created_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_playback_analytics_track_id ON playback_analytics(track_id);
CREATE INDEX idx_playback_analytics_user_id ON playback_analytics(user_id);
CREATE INDEX idx_playback_analytics_created_at ON playback_analytics(created_at);

View file

@ -1,18 +0,0 @@
-- T0381: Create Playback Analytics Performance Optimization
-- Ajout d'index pour optimiser les performances des requêtes analytics
-- Index composite pour les requêtes fréquentes (track_id, user_id, created_at)
CREATE INDEX IF NOT EXISTS idx_playback_analytics_composite ON playback_analytics(track_id, user_id, created_at);
-- Index pour les requêtes par completion_rate
CREATE INDEX IF NOT EXISTS idx_playback_analytics_completion ON playback_analytics(completion_rate);
-- Index pour les requêtes par date (déjà présent via created_at dans le composite, mais ajoutons un index séparé pour les requêtes par date uniquement)
CREATE INDEX IF NOT EXISTS idx_playback_analytics_created_at ON playback_analytics(created_at);
-- Index pour les requêtes par track_id et created_at (pour les dashboards et agrégations)
CREATE INDEX IF NOT EXISTS idx_playback_analytics_track_created ON playback_analytics(track_id, created_at);
-- Index pour les requêtes par user_id et created_at
CREATE INDEX IF NOT EXISTS idx_playback_analytics_user_created ON playback_analytics(user_id, created_at);

View file

@ -1,25 +0,0 @@
-- Migration: Create refresh_tokens table
-- Description: Stores JWT refresh tokens for persistent authentication
CREATE TABLE IF NOT EXISTS refresh_tokens (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL,
token_hash VARCHAR(255) NOT NULL,
expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP WITH TIME ZONE,
CONSTRAINT fk_refresh_tokens_user_id FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
-- Indexes
CREATE INDEX IF NOT EXISTS idx_refresh_tokens_user_id ON refresh_tokens(user_id);
CREATE INDEX IF NOT EXISTS idx_refresh_tokens_token_hash ON refresh_tokens(token_hash);
CREATE INDEX IF NOT EXISTS idx_refresh_tokens_deleted_at ON refresh_tokens(deleted_at);
CREATE INDEX IF NOT EXISTS idx_refresh_tokens_expires_at ON refresh_tokens(expires_at) WHERE deleted_at IS NULL;
-- Comments
COMMENT ON TABLE refresh_tokens IS 'JWT refresh tokens for persistent authentication (T0165)';
COMMENT ON COLUMN refresh_tokens.token_hash IS 'SHA-256 hash of the refresh token';
COMMENT ON COLUMN refresh_tokens.expires_at IS 'Token expiration timestamp';

View file

@ -1,30 +0,0 @@
-- Migration: Create rooms table for chat
-- Description: Chat rooms for real-time messaging
CREATE TABLE IF NOT EXISTS rooms (
id BIGSERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
description TEXT,
room_type VARCHAR(50) NOT NULL DEFAULT 'public', -- 'public', 'private', 'direct'
creator_id BIGINT NOT NULL,
is_active BOOLEAN DEFAULT true,
max_members INTEGER DEFAULT 100,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP WITH TIME ZONE,
CONSTRAINT fk_rooms_creator_id FOREIGN KEY (creator_id) REFERENCES users(id) ON DELETE CASCADE
);
-- Indexes
CREATE INDEX IF NOT EXISTS idx_rooms_creator_id ON rooms(creator_id);
CREATE INDEX IF NOT EXISTS idx_rooms_room_type ON rooms(room_type);
CREATE INDEX IF NOT EXISTS idx_rooms_is_active ON rooms(is_active) WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_rooms_deleted_at ON rooms(deleted_at);
CREATE INDEX IF NOT EXISTS idx_rooms_created_at ON rooms(created_at DESC);
-- Comments
COMMENT ON TABLE rooms IS 'Chat rooms for real-time messaging';
COMMENT ON COLUMN rooms.room_type IS 'Type of room: public, private, or direct';
COMMENT ON COLUMN rooms.max_members IS 'Maximum number of members allowed in the room';

View file

@ -1,32 +0,0 @@
-- Migration: Create room_members table
-- Description: Members of chat rooms
CREATE TABLE IF NOT EXISTS room_members (
id BIGSERIAL PRIMARY KEY,
room_id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
role VARCHAR(50) NOT NULL DEFAULT 'member', -- 'admin', 'moderator', 'member'
joined_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
last_read_at TIMESTAMP WITH TIME ZONE,
is_muted BOOLEAN DEFAULT false,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP WITH TIME ZONE,
CONSTRAINT fk_room_members_room_id FOREIGN KEY (room_id) REFERENCES rooms(id) ON DELETE CASCADE,
CONSTRAINT fk_room_members_user_id FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
CONSTRAINT unique_room_member UNIQUE (room_id, user_id)
);
-- Indexes
CREATE INDEX IF NOT EXISTS idx_room_members_room_id ON room_members(room_id);
CREATE INDEX IF NOT EXISTS idx_room_members_user_id ON room_members(user_id);
CREATE INDEX IF NOT EXISTS idx_room_members_role ON room_members(role);
CREATE INDEX IF NOT EXISTS idx_room_members_deleted_at ON room_members(deleted_at);
-- Comments
COMMENT ON TABLE room_members IS 'Members of chat rooms with roles and permissions';
COMMENT ON COLUMN room_members.role IS 'Member role: admin, moderator, or member';
COMMENT ON COLUMN room_members.last_read_at IS 'Timestamp of last message read by user';
COMMENT ON COLUMN room_members.is_muted IS 'Whether notifications are muted for this user';

View file

@ -1,39 +0,0 @@
-- Migration: Create messages table
-- Description: Chat messages in rooms
CREATE TABLE IF NOT EXISTS messages (
id BIGSERIAL PRIMARY KEY,
room_id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
content TEXT NOT NULL,
message_type VARCHAR(50) NOT NULL DEFAULT 'text', -- 'text', 'image', 'audio', 'file', 'system'
parent_id BIGINT, -- For threaded replies
is_edited BOOLEAN DEFAULT false,
is_deleted BOOLEAN DEFAULT false,
metadata JSONB, -- For additional data (file info, mentions, etc.)
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP WITH TIME ZONE,
CONSTRAINT fk_messages_room_id FOREIGN KEY (room_id) REFERENCES rooms(id) ON DELETE CASCADE,
CONSTRAINT fk_messages_user_id FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
CONSTRAINT fk_messages_parent_id FOREIGN KEY (parent_id) REFERENCES messages(id) ON DELETE SET NULL
);
-- Indexes
CREATE INDEX IF NOT EXISTS idx_messages_room_id_created_at ON messages(room_id, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_messages_user_id ON messages(user_id);
CREATE INDEX IF NOT EXISTS idx_messages_parent_id ON messages(parent_id) WHERE parent_id IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_messages_message_type ON messages(message_type);
CREATE INDEX IF NOT EXISTS idx_messages_deleted_at ON messages(deleted_at);
CREATE INDEX IF NOT EXISTS idx_messages_is_deleted ON messages(is_deleted) WHERE is_deleted = false;
-- Full-text search index for message content
CREATE INDEX IF NOT EXISTS idx_messages_content_search ON messages USING gin(to_tsvector('english', content));
-- Comments
COMMENT ON TABLE messages IS 'Chat messages in rooms with support for threading and different types';
COMMENT ON COLUMN messages.message_type IS 'Type of message: text, image, audio, file, or system';
COMMENT ON COLUMN messages.parent_id IS 'Parent message ID for threaded replies';
COMMENT ON COLUMN messages.metadata IS 'JSON metadata for file info, mentions, reactions, etc.';

View file

@ -1,11 +0,0 @@
-- Migration: Add revoked_at column to sessions table
-- Description: Add revoked_at timestamp to track revoked sessions
ALTER TABLE sessions ADD COLUMN IF NOT EXISTS revoked_at TIMESTAMP WITH TIME ZONE;
-- Index for revoked sessions
CREATE INDEX IF NOT EXISTS idx_sessions_revoked_at ON sessions(revoked_at) WHERE revoked_at IS NOT NULL;
-- Comments
COMMENT ON COLUMN sessions.revoked_at IS 'Timestamp when the session was revoked (for logout, password reset, etc.)';

View file

@ -1,36 +0,0 @@
-- Migration: Create user_sessions table (alias for sessions compatibility)
-- Description: Alternative sessions table for legacy compatibility
-- This is actually just a view or alias for the sessions table
-- The sessions table already exists and serves this purpose
-- If we really need a separate user_sessions table:
CREATE TABLE IF NOT EXISTS user_sessions (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL,
session_token VARCHAR(255) NOT NULL,
ip_address VARCHAR(45),
user_agent TEXT,
is_active BOOLEAN DEFAULT true,
last_activity TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
revoked_at TIMESTAMP WITH TIME ZONE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_user_sessions_user_id FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
-- Indexes
CREATE UNIQUE INDEX IF NOT EXISTS idx_user_sessions_token ON user_sessions(session_token);
CREATE INDEX IF NOT EXISTS idx_user_sessions_user_id ON user_sessions(user_id);
CREATE INDEX IF NOT EXISTS idx_user_sessions_is_active ON user_sessions(is_active) WHERE is_active = true;
CREATE INDEX IF NOT EXISTS idx_user_sessions_expires_at ON user_sessions(expires_at);
CREATE INDEX IF NOT EXISTS idx_user_sessions_last_activity ON user_sessions(last_activity DESC);
-- Comments
COMMENT ON TABLE user_sessions IS 'User sessions for authentication tracking (alternative to sessions table)';
COMMENT ON COLUMN user_sessions.session_token IS 'Unique session token (hashed)';
COMMENT ON COLUMN user_sessions.revoked_at IS 'Timestamp when session was revoked';
COMMENT ON COLUMN user_sessions.last_activity IS 'Last activity timestamp (updated periodically with debounce)';

View file

@ -1,12 +0,0 @@
-- Migration: Add missing columns to playlists table
-- Adds follower_count and deleted_at for soft delete support
-- Add follower_count column
ALTER TABLE playlists ADD COLUMN IF NOT EXISTS follower_count INTEGER DEFAULT 0;
-- Add deleted_at for soft delete support
ALTER TABLE playlists ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMP WITH TIME ZONE;
-- Index on deleted_at for soft delete queries
CREATE INDEX IF NOT EXISTS idx_playlists_deleted_at ON playlists(deleted_at);

View file

@ -1,307 +0,0 @@
-- 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)';

View file

@ -1,28 +0,0 @@
-- Migration to convert webhooks tables to use UUIDs
-- Since the feature was disabled/broken, we drop and recreate to ensure clean state
DROP TABLE IF EXISTS webhook_failures;
DROP TABLE IF EXISTS webhooks;
CREATE TABLE webhooks (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
url TEXT NOT NULL,
events TEXT[],
active BOOLEAN DEFAULT true,
secret TEXT NOT NULL,
created_at TIMESTAMPTZ,
updated_at TIMESTAMPTZ
);
CREATE TABLE webhook_failures (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
webhook_id UUID NOT NULL REFERENCES webhooks(id) ON DELETE CASCADE,
event TEXT NOT NULL,
error TEXT NOT NULL,
retries INTEGER DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL
);
CREATE INDEX idx_webhooks_user_id ON webhooks(user_id);
CREATE INDEX idx_webhook_failures_webhook_id ON webhook_failures(webhook_id);

View file

@ -1,23 +0,0 @@
-- Migration to convert sessions table to use UUIDs
-- We will recreate the table to ensure clean state as it is a critical table
DROP TABLE IF EXISTS sessions;
CREATE TABLE sessions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
token_hash VARCHAR(255) NOT NULL UNIQUE,
ip_address VARCHAR(45),
user_agent TEXT,
is_active BOOLEAN DEFAULT true,
expires_at TIMESTAMPTZ,
revoked_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
deleted_at TIMESTAMPTZ
);
CREATE INDEX idx_sessions_user_id ON sessions(user_id);
CREATE INDEX idx_sessions_token_hash ON sessions(token_hash);
CREATE INDEX idx_sessions_deleted_at ON sessions(deleted_at);

View file

@ -1,19 +0,0 @@
-- Migration to convert room_members table to use UUIDs for ID
-- We will recreate the table to ensure clean state
DROP TABLE IF EXISTS room_members;
CREATE TABLE room_members (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
room_id UUID NOT NULL REFERENCES rooms(id) ON DELETE CASCADE,
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
role VARCHAR(50) NOT NULL DEFAULT 'member',
joined_at TIMESTAMPTZ DEFAULT NOW(),
CONSTRAINT uq_room_members_room_user UNIQUE (room_id, user_id)
);
CREATE INDEX idx_room_members_room_id ON room_members(room_id);
CREATE INDEX idx_room_members_user_id ON room_members(user_id);
CREATE INDEX idx_room_members_role ON room_members(role);

View file

@ -1,24 +0,0 @@
-- Migration to convert messages table to use UUIDs for ID, RoomID, ParentID
-- We will recreate the table to ensure clean state
DROP TABLE IF EXISTS messages;
CREATE TABLE messages (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
room_id UUID NOT NULL REFERENCES rooms(id) ON DELETE CASCADE,
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
content TEXT NOT NULL,
type VARCHAR(50) NOT NULL DEFAULT 'text',
parent_id UUID REFERENCES messages(id) ON DELETE SET NULL,
is_edited BOOLEAN DEFAULT false,
is_deleted BOOLEAN DEFAULT false,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
deleted_at TIMESTAMPTZ
);
CREATE INDEX idx_messages_room_id_created_at ON messages(room_id, created_at DESC);
CREATE INDEX idx_messages_sender_id ON messages(user_id);
CREATE INDEX idx_messages_parent_id ON messages(parent_id);
CREATE INDEX idx_messages_deleted_at ON messages(deleted_at);

View file

@ -1,201 +0,0 @@
-- Migration: 060_migrate_tracks_playlists_to_uuid
-- Description: Migrate IDs from BIGINT to UUID for Tracks, Playlists and all related tables
-- Strategy: Add new UUID columns, fill them, update FKs, swap PKs, drop old columns.
BEGIN;
-- 1. Ensure pgcrypto is available for gen_random_uuid()
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
-- =================================================================
-- PHASE 1: TRACKS
-- =================================================================
-- 1.1 Add new UUID column to tracks
ALTER TABLE tracks ADD COLUMN new_id UUID DEFAULT gen_random_uuid();
-- 1.2 Create mapping table for tracks (old_id -> new_id) to help migration
CREATE TEMP TABLE track_id_map AS SELECT id AS old_id, new_id FROM tracks;
CREATE INDEX ON track_id_map(old_id);
-- 1.3 Add UUID columns to all tables referencing tracks
ALTER TABLE track_likes ADD COLUMN new_track_id UUID;
ALTER TABLE track_comments ADD COLUMN new_track_id UUID;
ALTER TABLE track_plays ADD COLUMN new_track_id UUID;
ALTER TABLE track_shares ADD COLUMN new_track_id UUID;
ALTER TABLE track_versions ADD COLUMN new_track_id UUID;
ALTER TABLE track_history ADD COLUMN new_track_id UUID;
ALTER TABLE hls_streams ADD COLUMN new_track_id UUID;
ALTER TABLE hls_transcode_queue ADD COLUMN new_track_id UUID;
ALTER TABLE bitrate_adaptation_logs ADD COLUMN new_track_id UUID;
ALTER TABLE playback_analytics ADD COLUMN new_track_id UUID;
ALTER TABLE playlist_tracks ADD COLUMN new_track_id UUID;
-- 1.4 Update FK columns using the mapping
UPDATE track_likes fk SET new_track_id = map.new_id FROM track_id_map map WHERE fk.track_id = map.old_id;
UPDATE track_comments fk SET new_track_id = map.new_id FROM track_id_map map WHERE fk.track_id = map.old_id;
UPDATE track_plays fk SET new_track_id = map.new_id FROM track_id_map map WHERE fk.track_id = map.old_id;
UPDATE track_shares fk SET new_track_id = map.new_id FROM track_id_map map WHERE fk.track_id = map.old_id;
UPDATE track_versions fk SET new_track_id = map.new_id FROM track_id_map map WHERE fk.track_id = map.old_id;
UPDATE track_history fk SET new_track_id = map.new_id FROM track_id_map map WHERE fk.track_id = map.old_id;
UPDATE hls_streams fk SET new_track_id = map.new_id FROM track_id_map map WHERE fk.track_id = map.old_id;
UPDATE hls_transcode_queue fk SET new_track_id = map.new_id FROM track_id_map map WHERE fk.track_id = map.old_id;
UPDATE bitrate_adaptation_logs fk SET new_track_id = map.new_id FROM track_id_map map WHERE fk.track_id = map.old_id;
UPDATE playback_analytics fk SET new_track_id = map.new_id FROM track_id_map map WHERE fk.track_id = map.old_id;
UPDATE playlist_tracks fk SET new_track_id = map.new_id FROM track_id_map map WHERE fk.track_id = map.old_id;
-- =================================================================
-- PHASE 2: PLAYLISTS
-- =================================================================
-- 2.1 Add new UUID column to playlists
ALTER TABLE playlists ADD COLUMN new_id UUID DEFAULT gen_random_uuid();
-- 2.2 Create mapping table for playlists
CREATE TEMP TABLE playlist_id_map AS SELECT id AS old_id, new_id FROM playlists;
CREATE INDEX ON playlist_id_map(old_id);
-- 2.3 Add UUID columns to all tables referencing playlists
ALTER TABLE playlist_collaborators ADD COLUMN new_playlist_id UUID;
ALTER TABLE playlist_follows ADD COLUMN new_playlist_id UUID;
-- playlist_tracks already has new_track_id, now adding new_playlist_id
ALTER TABLE playlist_tracks ADD COLUMN new_playlist_id UUID;
-- 2.4 Update FK columns using the mapping
UPDATE playlist_collaborators fk SET new_playlist_id = map.new_id FROM playlist_id_map map WHERE fk.playlist_id = map.old_id;
UPDATE playlist_follows fk SET new_playlist_id = map.new_id FROM playlist_id_map map WHERE fk.playlist_id = map.old_id;
UPDATE playlist_tracks fk SET new_playlist_id = map.new_id FROM playlist_id_map map WHERE fk.playlist_id = map.old_id;
-- =================================================================
-- PHASE 3: SWITCH COLUMNS AND CONSTRAINTS
-- =================================================================
-- 3.1 Drop old constraints (This list must be exhaustive based on existing migrations)
-- Note: Constraint names are guessed based on standard naming. If custom names were used, this might need adjustment.
-- It is safer to DROP CASCADE on the PKs but that destroys indexes we want to keep.
-- We will manually alter tables.
-- TRACKS DEPENDENTS
ALTER TABLE track_likes DROP CONSTRAINT IF EXISTS track_likes_track_id_fkey;
ALTER TABLE track_comments DROP CONSTRAINT IF EXISTS track_comments_track_id_fkey;
ALTER TABLE track_plays DROP CONSTRAINT IF EXISTS track_plays_track_id_fkey;
ALTER TABLE track_shares DROP CONSTRAINT IF EXISTS track_shares_track_id_fkey;
ALTER TABLE track_versions DROP CONSTRAINT IF EXISTS track_versions_track_id_fkey;
ALTER TABLE track_history DROP CONSTRAINT IF EXISTS track_history_track_id_fkey;
ALTER TABLE hls_streams DROP CONSTRAINT IF EXISTS hls_streams_track_id_fkey;
ALTER TABLE hls_transcode_queue DROP CONSTRAINT IF EXISTS hls_transcode_queue_track_id_fkey;
ALTER TABLE bitrate_adaptation_logs DROP CONSTRAINT IF EXISTS bitrate_adaptation_logs_track_id_fkey;
ALTER TABLE playback_analytics DROP CONSTRAINT IF EXISTS playback_analytics_track_id_fkey;
ALTER TABLE playlist_tracks DROP CONSTRAINT IF EXISTS playlist_tracks_track_id_fkey;
-- PLAYLISTS DEPENDENTS
ALTER TABLE playlist_collaborators DROP CONSTRAINT IF EXISTS playlist_collaborators_playlist_id_fkey;
ALTER TABLE playlist_follows DROP CONSTRAINT IF EXISTS playlist_follows_playlist_id_fkey;
ALTER TABLE playlist_tracks DROP CONSTRAINT IF EXISTS playlist_tracks_playlist_id_fkey;
-- 3.2 Drop old ID columns and Rename new ones (Tracks)
ALTER TABLE tracks DROP CONSTRAINT tracks_pkey CASCADE;
ALTER TABLE tracks DROP COLUMN id;
ALTER TABLE tracks RENAME COLUMN new_id TO id;
ALTER TABLE tracks ADD PRIMARY KEY (id);
-- 3.3 Drop old ID columns and Rename new ones (Playlists)
ALTER TABLE playlists DROP CONSTRAINT playlists_pkey CASCADE;
ALTER TABLE playlists DROP COLUMN id;
ALTER TABLE playlists RENAME COLUMN new_id TO id;
ALTER TABLE playlists ADD PRIMARY KEY (id);
-- 3.4 Switch columns in dependent tables (Tracks)
-- track_likes
ALTER TABLE track_likes DROP COLUMN track_id;
ALTER TABLE track_likes RENAME COLUMN new_track_id TO track_id;
ALTER TABLE track_likes ALTER COLUMN track_id SET NOT NULL;
ALTER TABLE track_likes ADD CONSTRAINT fk_track_likes_track FOREIGN KEY (track_id) REFERENCES tracks(id) ON DELETE CASCADE;
-- track_comments
ALTER TABLE track_comments DROP COLUMN track_id;
ALTER TABLE track_comments RENAME COLUMN new_track_id TO track_id;
ALTER TABLE track_comments ALTER COLUMN track_id SET NOT NULL;
ALTER TABLE track_comments ADD CONSTRAINT fk_track_comments_track FOREIGN KEY (track_id) REFERENCES tracks(id) ON DELETE CASCADE;
-- track_plays
ALTER TABLE track_plays DROP COLUMN track_id;
ALTER TABLE track_plays RENAME COLUMN new_track_id TO track_id;
ALTER TABLE track_plays ALTER COLUMN track_id SET NOT NULL;
ALTER TABLE track_plays ADD CONSTRAINT fk_track_plays_track FOREIGN KEY (track_id) REFERENCES tracks(id) ON DELETE CASCADE;
-- track_shares
ALTER TABLE track_shares DROP COLUMN track_id;
ALTER TABLE track_shares RENAME COLUMN new_track_id TO track_id;
ALTER TABLE track_shares ALTER COLUMN track_id SET NOT NULL;
ALTER TABLE track_shares ADD CONSTRAINT fk_track_shares_track FOREIGN KEY (track_id) REFERENCES tracks(id) ON DELETE CASCADE;
-- track_versions
ALTER TABLE track_versions DROP COLUMN track_id;
ALTER TABLE track_versions RENAME COLUMN new_track_id TO track_id;
ALTER TABLE track_versions ALTER COLUMN track_id SET NOT NULL;
ALTER TABLE track_versions ADD CONSTRAINT fk_track_versions_track FOREIGN KEY (track_id) REFERENCES tracks(id) ON DELETE CASCADE;
-- track_history
ALTER TABLE track_history DROP COLUMN track_id;
ALTER TABLE track_history RENAME COLUMN new_track_id TO track_id;
ALTER TABLE track_history ALTER COLUMN track_id SET NOT NULL;
ALTER TABLE track_history ADD CONSTRAINT fk_track_history_track FOREIGN KEY (track_id) REFERENCES tracks(id) ON DELETE CASCADE;
-- hls_streams
ALTER TABLE hls_streams DROP COLUMN track_id;
ALTER TABLE hls_streams RENAME COLUMN new_track_id TO track_id;
ALTER TABLE hls_streams ALTER COLUMN track_id SET NOT NULL;
ALTER TABLE hls_streams ADD CONSTRAINT fk_hls_streams_track FOREIGN KEY (track_id) REFERENCES tracks(id) ON DELETE CASCADE;
-- hls_transcode_queue
ALTER TABLE hls_transcode_queue DROP COLUMN track_id;
ALTER TABLE hls_transcode_queue RENAME COLUMN new_track_id TO track_id;
ALTER TABLE hls_transcode_queue ALTER COLUMN track_id SET NOT NULL;
ALTER TABLE hls_transcode_queue ADD CONSTRAINT fk_hls_transcode_queue_track FOREIGN KEY (track_id) REFERENCES tracks(id) ON DELETE CASCADE;
-- bitrate_adaptation_logs
ALTER TABLE bitrate_adaptation_logs DROP COLUMN track_id;
ALTER TABLE bitrate_adaptation_logs RENAME COLUMN new_track_id TO track_id;
ALTER TABLE bitrate_adaptation_logs ALTER COLUMN track_id SET NOT NULL;
ALTER TABLE bitrate_adaptation_logs ADD CONSTRAINT fk_bitrate_adaptation_logs_track FOREIGN KEY (track_id) REFERENCES tracks(id) ON DELETE CASCADE;
-- playback_analytics
ALTER TABLE playback_analytics DROP COLUMN track_id;
ALTER TABLE playback_analytics RENAME COLUMN new_track_id TO track_id;
ALTER TABLE playback_analytics ALTER COLUMN track_id SET NOT NULL;
ALTER TABLE playback_analytics ADD CONSTRAINT fk_playback_analytics_track FOREIGN KEY (track_id) REFERENCES tracks(id) ON DELETE CASCADE;
-- 3.5 Switch columns in dependent tables (Playlists & PlaylistTracks)
-- playlist_collaborators
ALTER TABLE playlist_collaborators DROP COLUMN playlist_id;
ALTER TABLE playlist_collaborators RENAME COLUMN new_playlist_id TO playlist_id;
ALTER TABLE playlist_collaborators ALTER COLUMN playlist_id SET NOT NULL;
ALTER TABLE playlist_collaborators ADD CONSTRAINT fk_playlist_collaborators_playlist FOREIGN KEY (playlist_id) REFERENCES playlists(id) ON DELETE CASCADE;
-- playlist_follows
ALTER TABLE playlist_follows DROP COLUMN playlist_id;
ALTER TABLE playlist_follows RENAME COLUMN new_playlist_id TO playlist_id;
ALTER TABLE playlist_follows ALTER COLUMN playlist_id SET NOT NULL;
ALTER TABLE playlist_follows ADD CONSTRAINT fk_playlist_follows_playlist FOREIGN KEY (playlist_id) REFERENCES playlists(id) ON DELETE CASCADE;
-- playlist_tracks (Junction Table)
ALTER TABLE playlist_tracks DROP COLUMN playlist_id;
ALTER TABLE playlist_tracks DROP COLUMN track_id;
ALTER TABLE playlist_tracks RENAME COLUMN new_playlist_id TO playlist_id;
ALTER TABLE playlist_tracks RENAME COLUMN new_track_id TO track_id;
ALTER TABLE playlist_tracks ALTER COLUMN playlist_id SET NOT NULL;
ALTER TABLE playlist_tracks ALTER COLUMN track_id SET NOT NULL;
ALTER TABLE playlist_tracks ADD CONSTRAINT fk_playlist_tracks_playlist FOREIGN KEY (playlist_id) REFERENCES playlists(id) ON DELETE CASCADE;
ALTER TABLE playlist_tracks ADD CONSTRAINT fk_playlist_tracks_track FOREIGN KEY (track_id) REFERENCES tracks(id) ON DELETE CASCADE;
-- 3.6 Cleanup PlaylistTracks ID (also needs to be UUID ideally, but let's migrate it too for consistency)
-- Assuming playlist_tracks has an ID column. Migrating it to UUID as well for full consistency.
ALTER TABLE playlist_tracks ADD COLUMN new_id UUID DEFAULT gen_random_uuid();
ALTER TABLE playlist_tracks DROP CONSTRAINT IF EXISTS playlist_tracks_pkey;
ALTER TABLE playlist_tracks DROP COLUMN id;
ALTER TABLE playlist_tracks RENAME COLUMN new_id TO id;
ALTER TABLE playlist_tracks ADD PRIMARY KEY (id);
COMMIT;

View file

@ -1,73 +0,0 @@
-- Migration: Ensure AuditLog and AdminSettings use UUIDs
-- Date: 2024-11-30
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
-- ==========================================
-- TABLE: audit_logs
-- ==========================================
DO $$
BEGIN
-- Check if audit_logs exists
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'audit_logs') THEN
-- Check if user_id exists and is NOT uuid
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'audit_logs' AND column_name = 'user_id' AND data_type NOT IN ('uuid')) THEN
RAISE NOTICE 'Converting audit_logs.user_id to UUID. Warning: Old integer IDs will be lost (TRUNCATE).';
-- We truncate because we cannot map old int IDs to new UUIDs without the mapping table (which might be gone)
TRUNCATE TABLE audit_logs;
ALTER TABLE audit_logs DROP COLUMN IF EXISTS user_id;
ALTER TABLE audit_logs ADD COLUMN user_id UUID;
-- Also migrate ID if it's int
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'audit_logs' AND column_name = 'id' AND data_type NOT IN ('uuid')) THEN
ALTER TABLE audit_logs DROP CONSTRAINT IF EXISTS audit_logs_pkey;
ALTER TABLE audit_logs DROP COLUMN IF EXISTS id;
ALTER TABLE audit_logs ADD COLUMN id UUID PRIMARY KEY DEFAULT gen_random_uuid();
END IF;
-- ResourceID
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'audit_logs' AND column_name = 'resource_id' AND data_type NOT IN ('uuid')) THEN
ALTER TABLE audit_logs DROP COLUMN IF EXISTS resource_id;
ALTER TABLE audit_logs ADD COLUMN resource_id UUID;
END IF;
END IF;
END IF;
END $$;
-- ==========================================
-- TABLE: admin_settings
-- ==========================================
-- Create if not exists
CREATE TABLE IF NOT EXISTS admin_settings (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
key VARCHAR(255) NOT NULL UNIQUE,
value TEXT,
type VARCHAR(50),
description TEXT,
category VARCHAR(50),
is_public BOOLEAN DEFAULT false,
updated_by UUID,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
-- If it exists but has int ID
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'admin_settings' AND column_name = 'id' AND data_type NOT IN ('uuid')) THEN
ALTER TABLE admin_settings ADD COLUMN id_uuid UUID DEFAULT gen_random_uuid();
ALTER TABLE admin_settings DROP CONSTRAINT IF EXISTS admin_settings_pkey;
ALTER TABLE admin_settings DROP COLUMN id;
ALTER TABLE admin_settings RENAME COLUMN id_uuid TO id;
ALTER TABLE admin_settings ADD PRIMARY KEY (id);
END IF;
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'admin_settings' AND column_name = 'updated_by' AND data_type NOT IN ('uuid')) THEN
ALTER TABLE admin_settings DROP COLUMN updated_by;
ALTER TABLE admin_settings ADD COLUMN updated_by UUID;
END IF;
END $$;

View file

@ -1,164 +0,0 @@
-- Migration: Migrate roles, permissions, user_roles, and role_permissions to UUID
-- Date: 2025-01-27
-- Reference: GO-004, GO-001, GO-005, GO-006
--
-- This migration converts all RBAC tables from BIGINT to UUID to align with the models
-- and ensure consistency with the rest of the application.
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- ==========================================
-- TABLE: roles
-- ==========================================
DO $$
BEGIN
-- Check if roles table exists and has BIGINT ID
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'roles') THEN
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'roles' AND column_name = 'id' AND data_type = 'bigint') THEN
RAISE NOTICE 'Migrating roles.id from BIGINT to UUID';
-- Add UUID column
ALTER TABLE roles ADD COLUMN IF NOT EXISTS id_uuid UUID DEFAULT gen_random_uuid();
-- Update role_permissions to use UUID (temporary mapping)
ALTER TABLE role_permissions ADD COLUMN IF NOT EXISTS role_id_uuid UUID;
UPDATE role_permissions rp
SET role_id_uuid = r.id_uuid
FROM roles r
WHERE rp.role_id = r.id;
-- Update user_roles to use UUID (temporary mapping)
ALTER TABLE user_roles ADD COLUMN IF NOT EXISTS role_id_uuid UUID;
UPDATE user_roles ur
SET role_id_uuid = r.id_uuid
FROM roles r
WHERE ur.role_id = r.id;
-- Drop foreign key constraints
ALTER TABLE role_permissions DROP CONSTRAINT IF EXISTS role_permissions_role_id_fkey;
ALTER TABLE user_roles DROP CONSTRAINT IF EXISTS user_roles_role_id_fkey;
-- Drop old ID column and rename UUID column
ALTER TABLE roles DROP CONSTRAINT IF EXISTS roles_pkey;
ALTER TABLE roles DROP COLUMN id;
ALTER TABLE roles RENAME COLUMN id_uuid TO id;
ALTER TABLE roles ADD PRIMARY KEY (id);
-- Update role_permissions
ALTER TABLE role_permissions DROP COLUMN role_id;
ALTER TABLE role_permissions RENAME COLUMN role_id_uuid TO role_id;
ALTER TABLE role_permissions ADD CONSTRAINT role_permissions_role_id_fkey
FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE;
-- Update user_roles
ALTER TABLE user_roles DROP COLUMN role_id;
ALTER TABLE user_roles RENAME COLUMN role_id_uuid TO role_id;
ALTER TABLE user_roles ADD CONSTRAINT user_roles_role_id_fkey
FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE;
END IF;
END IF;
END $$;
-- ==========================================
-- TABLE: permissions
-- ==========================================
DO $$
BEGIN
-- Check if permissions table exists and has BIGINT ID
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'permissions') THEN
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'permissions' AND column_name = 'id' AND data_type = 'bigint') THEN
RAISE NOTICE 'Migrating permissions.id from BIGINT to UUID';
-- Add UUID column
ALTER TABLE permissions ADD COLUMN IF NOT EXISTS id_uuid UUID DEFAULT gen_random_uuid();
-- Update role_permissions to use UUID (temporary mapping)
ALTER TABLE role_permissions ADD COLUMN IF NOT EXISTS permission_id_uuid UUID;
UPDATE role_permissions rp
SET permission_id_uuid = p.id_uuid
FROM permissions p
WHERE rp.permission_id = p.id;
-- Drop foreign key constraint
ALTER TABLE role_permissions DROP CONSTRAINT IF EXISTS role_permissions_permission_id_fkey;
-- Drop old ID column and rename UUID column
ALTER TABLE permissions DROP CONSTRAINT IF EXISTS permissions_pkey;
ALTER TABLE permissions DROP COLUMN id;
ALTER TABLE permissions RENAME COLUMN id_uuid TO id;
ALTER TABLE permissions ADD PRIMARY KEY (id);
-- Update role_permissions
ALTER TABLE role_permissions DROP COLUMN permission_id;
ALTER TABLE role_permissions RENAME COLUMN permission_id_uuid TO permission_id;
ALTER TABLE role_permissions ADD CONSTRAINT role_permissions_permission_id_fkey
FOREIGN KEY (permission_id) REFERENCES permissions(id) ON DELETE CASCADE;
-- Recreate composite primary key
ALTER TABLE role_permissions DROP CONSTRAINT IF EXISTS role_permissions_pkey;
ALTER TABLE role_permissions ADD PRIMARY KEY (role_id, permission_id);
END IF;
END IF;
END $$;
-- ==========================================
-- TABLE: user_roles
-- ==========================================
DO $$
BEGIN
-- Check if user_roles table exists and has BIGINT ID
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'user_roles') THEN
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'user_roles' AND column_name = 'id' AND data_type = 'bigint') THEN
RAISE NOTICE 'Migrating user_roles.id from BIGINT to UUID';
-- Add UUID column
ALTER TABLE user_roles ADD COLUMN IF NOT EXISTS id_uuid UUID DEFAULT gen_random_uuid();
-- Drop old ID column and rename UUID column
ALTER TABLE user_roles DROP CONSTRAINT IF EXISTS user_roles_pkey;
ALTER TABLE user_roles DROP COLUMN id;
ALTER TABLE user_roles RENAME COLUMN id_uuid TO id;
ALTER TABLE user_roles ADD PRIMARY KEY (id);
END IF;
-- Ensure user_id is UUID (should already be done by migration 047, but double-check)
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'user_roles' AND column_name = 'user_id' AND data_type = 'bigint') THEN
RAISE NOTICE 'user_roles.user_id is still BIGINT, should have been migrated by 047. This is unexpected.';
END IF;
-- Ensure assigned_by is UUID if it exists
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'user_roles' AND column_name = 'assigned_by' AND data_type = 'bigint') THEN
RAISE NOTICE 'Migrating user_roles.assigned_by from BIGINT to UUID';
ALTER TABLE user_roles ADD COLUMN IF NOT EXISTS assigned_by_uuid UUID;
UPDATE user_roles ur
SET assigned_by_uuid = u.id
FROM users u
WHERE ur.assigned_by = u.id::bigint AND u.id IS NOT NULL;
ALTER TABLE user_roles DROP COLUMN assigned_by;
ALTER TABLE user_roles RENAME COLUMN assigned_by_uuid TO assigned_by;
END IF;
END IF;
END $$;
-- ==========================================
-- INDEXES
-- ==========================================
-- Recreate indexes if they don't exist
CREATE INDEX IF NOT EXISTS idx_user_roles_user_id ON user_roles(user_id);
CREATE INDEX IF NOT EXISTS idx_user_roles_role_id ON user_roles(role_id);
CREATE INDEX IF NOT EXISTS idx_role_permissions_role_id ON role_permissions(role_id);
CREATE INDEX IF NOT EXISTS idx_role_permissions_permission_id ON role_permissions(permission_id);
-- ==========================================
-- COMMENTS
-- ==========================================
COMMENT ON TABLE roles IS 'System roles for RBAC (migrated to UUID)';
COMMENT ON TABLE permissions IS 'System permissions for RBAC (migrated to UUID)';
COMMENT ON TABLE user_roles IS 'User role assignments (migrated to UUID)';
COMMENT ON TABLE role_permissions IS 'Role permission mappings (migrated to UUID)';

View file

@ -1,53 +0,0 @@
-- Migration: Finaliser la transition UUID pour les tables secondaires
-- Date: 2024-12-04
-- Description: Finalise le travail de migrations/001_migrate_ids_to_uuid_up.sql
-- Pour chaque table ayant une colonne 'new_id' (UUID) et une ancienne 'id' (INT/BIGINT),
-- on supprime l'ancienne et on promeut la nouvelle en Primary Key.
-- Liste des tables concernées:
-- hls_transcode_queue, bitrate_adaptation_logs, contests, contest_entries, contest_judges,
-- contest_votes, contest_sponsors, contest_stems, contest_analytics, contest_badges,
-- federated_identities, equipment, hardware_sales, equipment_trades, hardware_offers,
-- mfa_configs, playback_analytics, recovery_codes, refresh_tokens, roles, permissions,
-- user_roles, royalty_records, royalty_payouts, royalty_rates, creator_royalty_rates,
-- royalty_config, sellable_contents, jury_members, track_history, track_versions,
-- user_settings, user_profiles
DO $$
DECLARE
tables text[] := ARRAY[
'hls_transcode_queue', 'bitrate_adaptation_logs', 'contests', 'contest_entries',
'contest_judges', 'contest_votes', 'contest_sponsors', 'contest_stems',
'contest_analytics', 'contest_badges', 'federated_identities', 'equipment',
'hardware_sales', 'equipment_trades', 'hardware_offers', 'mfa_configs',
'playback_analytics', 'recovery_codes', 'refresh_tokens', 'roles', 'permissions',
'user_roles', 'royalty_records', 'royalty_payouts', 'royalty_rates',
'creator_royalty_rates', 'royalty_config', 'sellable_contents', 'jury_members',
'track_history', 'track_versions', 'user_settings', 'user_profiles'
];
t text;
BEGIN
FOREACH t IN ARRAY tables LOOP
-- Vérifier si la table existe et a la colonne new_id
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = t AND column_name = 'new_id') THEN
-- 1. Supprimer l'ancienne contrainte de clé primaire (si elle existe)
-- On cherche le nom de la contrainte PK
EXECUTE 'ALTER TABLE ' || quote_ident(t) || ' DROP CONSTRAINT IF EXISTS ' || quote_ident(t || '_pkey') || ' CASCADE';
-- 2. Supprimer l'ancienne colonne ID
EXECUTE 'ALTER TABLE ' || quote_ident(t) || ' DROP COLUMN IF EXISTS id CASCADE';
-- 3. Renommer new_id en id
EXECUTE 'ALTER TABLE ' || quote_ident(t) || ' RENAME COLUMN new_id TO id';
-- 4. Mettre id en NOT NULL (devrait déjà l'être via default, mais sécurité)
EXECUTE 'ALTER TABLE ' || quote_ident(t) || ' ALTER COLUMN id SET NOT NULL';
-- 5. Ajouter la nouvelle clé primaire
EXECUTE 'ALTER TABLE ' || quote_ident(t) || ' ADD PRIMARY KEY (id)';
RAISE NOTICE 'Table % migrée avec succès vers UUID', t;
END IF;
END LOOP;
END $$;

View file

@ -1,157 +0,0 @@
-- 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 $$;

View file

@ -1,77 +0,0 @@
-- Migration: Migrer PK tracks et playlists vers UUID
-- Date: 2024-12-04
-- Description: S'assure que les tables tracks et playlists utilisent bien UUID comme clé primaire.
-- Si elles sont encore en SERIAL/INT, on effectue la migration.
-- Extension requise (déjà là normalement)
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- =================================================================
-- TRACKS
-- =================================================================
DO $$
DECLARE
col_type text;
BEGIN
-- Vérifier le type actuel de la colonne id dans tracks
SELECT data_type INTO col_type FROM information_schema.columns
WHERE table_name = 'tracks' AND column_name = 'id';
-- Si ce n'est pas déjà un UUID, on migre
IF col_type != 'uuid' THEN
RAISE NOTICE 'Migration tracks.id de % vers UUID', col_type;
-- 1. Ajouter colonne temporaire
ALTER TABLE tracks ADD COLUMN IF NOT EXISTS id_uuid UUID DEFAULT uuid_generate_v4();
-- 2. Populer (déjà fait par défaut, mais update pour être sûr)
UPDATE tracks SET id_uuid = uuid_generate_v4() WHERE id_uuid IS NULL;
-- 3. Dropper contraintes dépendantes (FKs pointant vers tracks)
-- Ex: playlist_tracks, track_likes, track_comments, track_shares, hls_streams...
-- NOTE: En prod, il faudrait migrer les FKs de ces tables aussi !
-- Pour cette phase, on suppose que les tables liées sont gérées par GORM ou seront fixées.
-- Simplification: On drop la PK, on switch, on remet la PK.
ALTER TABLE tracks DROP CONSTRAINT IF EXISTS tracks_pkey CASCADE;
-- 4. Swap
ALTER TABLE tracks DROP COLUMN id;
ALTER TABLE tracks RENAME COLUMN id_uuid TO id;
-- 5. PK
ALTER TABLE tracks ADD PRIMARY KEY (id);
ELSE
RAISE NOTICE 'tracks.id est déjà un UUID. Pas de changement.';
END IF;
END $$;
-- =================================================================
-- PLAYLISTS
-- =================================================================
DO $$
DECLARE
col_type text;
BEGIN
SELECT data_type INTO col_type FROM information_schema.columns
WHERE table_name = 'playlists' AND column_name = 'id';
IF col_type != 'uuid' THEN
RAISE NOTICE 'Migration playlists.id de % vers UUID', col_type;
ALTER TABLE playlists ADD COLUMN IF NOT EXISTS id_uuid UUID DEFAULT uuid_generate_v4();
UPDATE playlists SET id_uuid = uuid_generate_v4() WHERE id_uuid IS NULL;
ALTER TABLE playlists DROP CONSTRAINT IF EXISTS playlists_pkey CASCADE;
ALTER TABLE playlists DROP COLUMN id;
ALTER TABLE playlists RENAME COLUMN id_uuid TO id;
ALTER TABLE playlists ADD PRIMARY KEY (id);
ELSE
RAISE NOTICE 'playlists.id est déjà un UUID. Pas de changement.';
END IF;
END $$;

View file

@ -1,13 +0,0 @@
-- Migration: Création du schéma Chat
-- Date: 2024-12-04
-- Description: Crée le schéma isolé pour le Chat Server afin d'éviter les conflits de tables.
-- Créer le schéma s'il n'existe pas
CREATE SCHEMA IF NOT EXISTS chat;
-- Commentaire explicatif
COMMENT ON SCHEMA chat IS 'Schéma isolé pour les données du Veza Chat Server (Rust)';
-- Droits (Optionnel selon la config user DB, mais recommandé)
-- GRANT ALL ON SCHEMA chat TO veza_user;
-- GRANT ALL ON ALL TABLES IN SCHEMA chat TO veza_user;

View file

@ -1,26 +0,0 @@
-- T0509: Create Playlist Version History
-- Create table playlist_versions for tracking playlist versions
-- Table playlist_versions
CREATE TABLE IF NOT EXISTS playlist_versions (
id BIGSERIAL PRIMARY KEY,
playlist_id BIGINT NOT NULL REFERENCES playlists(id) ON DELETE CASCADE,
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE SET NULL,
version INTEGER NOT NULL,
action VARCHAR(50) NOT NULL,
title VARCHAR(200),
description TEXT,
is_public BOOLEAN DEFAULT TRUE,
cover_url VARCHAR(500),
tracks_snapshot TEXT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- Indexes for performance
CREATE INDEX IF NOT EXISTS idx_playlist_versions_playlist_id ON playlist_versions(playlist_id);
CREATE INDEX IF NOT EXISTS idx_playlist_versions_user_id ON playlist_versions(user_id);
CREATE INDEX IF NOT EXISTS idx_playlist_versions_action ON playlist_versions(action);
CREATE INDEX IF NOT EXISTS idx_playlist_versions_created_at ON playlist_versions(created_at DESC);
CREATE INDEX IF NOT EXISTS idx_playlist_versions_playlist_created ON playlist_versions(playlist_id, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_playlist_versions_playlist_version ON playlist_versions(playlist_id, version);