-- ClipForge Database Schema CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; -- Job status enum CREATE TYPE job_status AS ENUM ( 'pending', 'downloading', 'transcribing', 'analyzing', 'extracting', 'complete', 'failed' ); -- Source type enum CREATE TYPE source_type AS ENUM ( 'youtube', 'upload' ); -- Aspect ratio enum CREATE TYPE aspect_ratio AS ENUM ( '16:9', '9:16', '1:1', '4:5' ); -- Render status enum CREATE TYPE render_status AS ENUM ( 'pending', 'rendering', 'complete', 'failed' ); -- Jobs table CREATE TABLE jobs ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), source_type source_type NOT NULL, source_url TEXT, source_filename TEXT, title TEXT, duration FLOAT, status job_status NOT NULL DEFAULT 'pending', progress FLOAT NOT NULL DEFAULT 0.0, stage_message TEXT, error_message TEXT, media_path TEXT, transcript JSONB, scene_boundaries JSONB, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); -- Clips table CREATE TABLE clips ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), job_id UUID NOT NULL REFERENCES jobs(id) ON DELETE CASCADE, title TEXT NOT NULL, start_time FLOAT NOT NULL, end_time FLOAT NOT NULL, duration FLOAT GENERATED ALWAYS AS (end_time - start_time) STORED, virality_score FLOAT NOT NULL DEFAULT 0.0, category TEXT, reasoning TEXT, transcript_segment TEXT, thumbnail_path TEXT, raw_clip_path TEXT, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); -- Render requests table CREATE TABLE render_requests ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), clip_id UUID NOT NULL REFERENCES clips(id) ON DELETE CASCADE, aspect_ratio aspect_ratio NOT NULL DEFAULT '9:16', subtitle_style TEXT NOT NULL DEFAULT 'tiktok', status render_status NOT NULL DEFAULT 'pending', progress FLOAT NOT NULL DEFAULT 0.0, output_path TEXT, error_message TEXT, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); -- Indexes CREATE INDEX idx_jobs_status ON jobs(status); CREATE INDEX idx_jobs_created_at ON jobs(created_at DESC); CREATE INDEX idx_clips_job_id ON clips(job_id); CREATE INDEX idx_clips_virality ON clips(virality_score DESC); CREATE INDEX idx_renders_clip_id ON render_requests(clip_id); CREATE INDEX idx_renders_status ON render_requests(status); -- Updated_at trigger CREATE OR REPLACE FUNCTION update_updated_at() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = NOW(); RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER jobs_updated_at BEFORE UPDATE ON jobs FOR EACH ROW EXECUTE FUNCTION update_updated_at(); CREATE TRIGGER renders_updated_at BEFORE UPDATE ON render_requests FOR EACH ROW EXECUTE FUNCTION update_updated_at();