chore(backend): remove legacy migrations and main file
This commit is contained in:
parent
95c5710563
commit
f13e14f5b0
45 changed files with 0 additions and 2063 deletions
|
|
@ -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")
|
||||
}
|
||||
|
|
@ -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';
|
||||
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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 = '';
|
||||
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
@ -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)';
|
||||
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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 $$;
|
||||
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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';
|
||||
|
||||
|
|
@ -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';
|
||||
|
||||
|
|
@ -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';
|
||||
|
||||
|
|
@ -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.';
|
||||
|
||||
|
|
@ -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.)';
|
||||
|
||||
|
|
@ -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)';
|
||||
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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)';
|
||||
|
||||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
@ -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 $$;
|
||||
|
|
@ -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)';
|
||||
|
||||
|
|
@ -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 $$;
|
||||
|
|
@ -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 $$;
|
||||
|
|
@ -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 $$;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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);
|
||||
|
||||
Loading…
Reference in a new issue