-- Wild Dragon MAM Platform - PostgreSQL Schema -- Enable UUID extension CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; -- ENUM types CREATE TYPE asset_status AS ENUM ( 'ingesting', 'processing', 'ready', 'error', 'archived' ); CREATE TYPE media_type AS ENUM ( 'video', 'audio', 'image', 'document' ); CREATE TYPE job_type AS ENUM ( 'proxy_gen', 'thumbnail', 'conform', 'export' ); CREATE TYPE job_status AS ENUM ( 'queued', 'processing', 'complete', 'failed' ); -- Projects table CREATE TABLE projects ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), name TEXT NOT NULL, description TEXT, s3_prefix TEXT NOT NULL, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); -- Bins table CREATE TABLE bins ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), project_id UUID NOT NULL REFERENCES projects ON DELETE CASCADE, parent_id UUID REFERENCES bins ON DELETE SET NULL, name TEXT NOT NULL, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); -- Assets table CREATE TABLE assets ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), project_id UUID NOT NULL REFERENCES projects ON DELETE CASCADE, bin_id UUID REFERENCES bins ON DELETE SET NULL, filename TEXT NOT NULL, display_name TEXT, status asset_status DEFAULT 'ingesting', media_type media_type NOT NULL, original_s3_key TEXT, proxy_s3_key TEXT, thumbnail_s3_key TEXT, codec TEXT, resolution TEXT, fps NUMERIC(6,3), duration_ms BIGINT, start_tc TEXT, file_size BIGINT, tags TEXT[] DEFAULT '{}', notes TEXT, -- AMPP sync fields (used by upload.js to mirror folder structure) ampp_folder_id TEXT, ampp_synced_at TIMESTAMPTZ, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); -- Jobs table CREATE TABLE jobs ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), type job_type NOT NULL, asset_id UUID REFERENCES assets ON DELETE SET NULL, status job_status DEFAULT 'queued', payload JSONB DEFAULT '{}', result JSONB DEFAULT '{}', error TEXT, progress INTEGER DEFAULT 0, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); -- Capture Sessions table CREATE TABLE capture_sessions ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), project_id UUID NOT NULL REFERENCES projects, bin_id UUID REFERENCES bins, clip_name TEXT NOT NULL, device TEXT NOT NULL, started_at TIMESTAMPTZ DEFAULT NOW(), stopped_at TIMESTAMPTZ, asset_id UUID REFERENCES assets ); -- Users table CREATE TABLE users ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), username TEXT UNIQUE NOT NULL, password_hash TEXT NOT NULL, display_name TEXT, role TEXT DEFAULT 'editor', created_at TIMESTAMPTZ DEFAULT NOW() ); -- Sessions table (for connect-pg-simple session store) CREATE TABLE sessions ( sid TEXT PRIMARY KEY, sess JSONB NOT NULL, expire TIMESTAMPTZ NOT NULL ); -- Indexes CREATE INDEX idx_assets_project_id ON assets(project_id); CREATE INDEX idx_assets_status ON assets(status); CREATE INDEX idx_assets_created_at_desc ON assets(created_at DESC); CREATE INDEX idx_assets_tags ON assets USING GIN(tags); CREATE INDEX idx_assets_fulltext ON assets USING GIN(to_tsvector('english', COALESCE(display_name, '') || ' ' || COALESCE(filename, '') || ' ' || COALESCE(notes, ''))); CREATE INDEX idx_jobs_asset_id ON jobs(asset_id); CREATE INDEX idx_jobs_status ON jobs(status); CREATE INDEX idx_jobs_type ON jobs(type); CREATE INDEX idx_bins_project_id ON bins(project_id); CREATE INDEX idx_sessions_expire ON sessions(expire); -- Recorder source types CREATE TYPE source_type AS ENUM ('sdi', 'srt', 'rtmp'); -- Recorder instances table -- NOTE: current_session_id is TEXT (stores a human-readable clip name, not a UUID) CREATE TABLE recorders ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), name TEXT NOT NULL, source_type source_type NOT NULL, source_config JSONB NOT NULL DEFAULT '{}', recording_codec TEXT NOT NULL DEFAULT 'prores_hq', recording_resolution TEXT DEFAULT 'native', proxy_enabled BOOLEAN DEFAULT true, proxy_codec TEXT DEFAULT 'libx264', proxy_resolution TEXT DEFAULT '1920x1080', project_id UUID REFERENCES projects, container_id TEXT, status TEXT DEFAULT 'stopped', current_session_id TEXT, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX idx_recorders_status ON recorders(status);