clip-forge/database/init.sql

114 lines
2.9 KiB
PL/PgSQL

-- 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();