114 lines
2.9 KiB
PL/PgSQL
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();
|