veza/veza-backend-api/migrations/030_files_management.sql

160 lines
4.5 KiB
MySQL
Raw Normal View History

P0: stabilisation backend/chat/stream + nouvelle base migrations v1 Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
2025-12-06 10:14:38 +00:00
-- 030_files_management.sql
-- File Management (Origin Standard)
-- === FILES ===
CREATE TABLE public.files (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES public.users(id) ON DELETE CASCADE,
-- File Info
filename VARCHAR(255) NOT NULL,
original_filename VARCHAR(255) NOT NULL,
mime_type VARCHAR(100) NOT NULL,
file_size BIGINT NOT NULL,
-- Storage
storage_path TEXT NOT NULL,
storage_provider VARCHAR(50) NOT NULL DEFAULT 's3',
bucket_name VARCHAR(255),
-- URLs
url TEXT NOT NULL,
thumbnail_url TEXT,
-- Metadata
file_hash VARCHAR(64),
metadata JSONB,
-- Processing
is_processed BOOLEAN NOT NULL DEFAULT false,
processed_at TIMESTAMPTZ,
processing_error TEXT,
-- Security
virus_scanned BOOLEAN NOT NULL DEFAULT false,
virus_scan_result VARCHAR(50),
virus_scanned_at TIMESTAMPTZ,
-- Visibility
is_public BOOLEAN NOT NULL DEFAULT false,
-- Timestamps
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
deleted_at TIMESTAMPTZ,
CONSTRAINT chk_files_size_positive CHECK (file_size > 0)
);
CREATE INDEX idx_files_user_id ON public.files(user_id);
CREATE INDEX idx_files_mime_type ON public.files(mime_type);
CREATE INDEX idx_files_file_hash ON public.files(file_hash) WHERE file_hash IS NOT NULL;
CREATE INDEX idx_files_created_at_desc ON public.files(created_at DESC);
-- === FILE UPLOADS ===
CREATE TABLE public.file_uploads (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES public.users(id) ON DELETE CASCADE,
-- Upload Info
filename VARCHAR(255) NOT NULL,
file_size BIGINT NOT NULL,
mime_type VARCHAR(100) NOT NULL,
-- Progress
bytes_uploaded BIGINT NOT NULL DEFAULT 0,
chunks_uploaded INTEGER NOT NULL DEFAULT 0,
total_chunks INTEGER,
-- Status
status VARCHAR(50) NOT NULL DEFAULT 'pending',
-- Storage
storage_key TEXT,
upload_id TEXT,
-- Metadata
metadata JSONB,
-- Timestamps
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
expires_at TIMESTAMPTZ NOT NULL,
CONSTRAINT chk_file_uploads_bytes_uploaded CHECK (bytes_uploaded >= 0 AND bytes_uploaded <= file_size)
);
CREATE INDEX idx_file_uploads_user_id ON public.file_uploads(user_id);
CREATE INDEX idx_file_uploads_status ON public.file_uploads(status);
CREATE INDEX idx_file_uploads_expires_at ON public.file_uploads(expires_at);
-- === FILE METADATA ===
CREATE TABLE public.file_metadata (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
file_id UUID NOT NULL REFERENCES public.files(id) ON DELETE CASCADE,
-- Audio
title VARCHAR(255),
artist VARCHAR(255),
album VARCHAR(255),
genre VARCHAR(100),
year INTEGER,
duration INTEGER,
bitrate INTEGER,
sample_rate INTEGER,
channels INTEGER,
codec VARCHAR(50),
-- Image
width INTEGER,
height INTEGER,
format VARCHAR(50),
-- Video
video_codec VARCHAR(50),
audio_codec VARCHAR(50),
framerate DECIMAL(10,2),
-- Advanced
bpm INTEGER,
musical_key VARCHAR(10),
time_signature VARCHAR(10),
-- Raw
raw_metadata JSONB,
-- Timestamps
extracted_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT uq_file_metadata_file_id UNIQUE (file_id)
);
CREATE INDEX idx_file_metadata_genre ON public.file_metadata(genre) WHERE genre IS NOT NULL;
CREATE INDEX idx_file_metadata_duration ON public.file_metadata(duration) WHERE duration IS NOT NULL;
-- === FILE CONVERSIONS ===
CREATE TABLE public.file_conversions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
source_file_id UUID NOT NULL REFERENCES public.files(id) ON DELETE CASCADE,
converted_file_id UUID REFERENCES public.files(id) ON DELETE SET NULL,
-- Conversion
target_format VARCHAR(50) NOT NULL,
target_quality VARCHAR(50),
-- Status
status VARCHAR(50) NOT NULL DEFAULT 'pending',
progress INTEGER NOT NULL DEFAULT 0,
-- Error
error_message TEXT,
-- Timestamps
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
completed_at TIMESTAMPTZ
);
CREATE INDEX idx_file_conversions_source_file_id ON public.file_conversions(source_file_id);
CREATE INDEX idx_file_conversions_status ON public.file_conversions(status);