-- ================================================================ -- Migration 003: Job Worker System -- Version: 003 -- Date: 2026-03-24 -- Description: Add job worker system tables and columns for -- automatic video processing after registration -- ================================================================ -- 3.1.1: Update videos table - add status, user_id, job_id columns ALTER TABLE videos ADD COLUMN IF NOT EXISTS status VARCHAR(20) DEFAULT 'pending'; ALTER TABLE videos ADD COLUMN IF NOT EXISTS user_id BIGINT; ALTER TABLE videos ADD COLUMN IF NOT EXISTS job_id INTEGER; COMMENT ON COLUMN videos.status IS 'Video processing status: pending, processing, completed, failed'; COMMENT ON COLUMN videos.user_id IS 'WordPress user ID (for user association tracking)'; COMMENT ON COLUMN videos.job_id IS 'Associated monitor_jobs ID'; -- 3.1.2: Add foreign key for job_id after ensuring monitor_jobs table exists DO $$ BEGIN IF EXISTS ( SELECT 1 FROM information_schema.tables WHERE table_name = 'monitor_jobs' ) THEN ALTER TABLE videos ADD CONSTRAINT fk_videos_job_id FOREIGN KEY (job_id) REFERENCES monitor_jobs(id) ON DELETE SET NULL; END IF; END $$; -- 3.1.3: Update monitor_jobs table - add video_id, user_id, processors columns ALTER TABLE monitor_jobs ADD COLUMN IF NOT EXISTS video_id BIGINT; ALTER TABLE monitor_jobs ADD COLUMN IF NOT EXISTS user_id BIGINT; ALTER TABLE monitor_jobs ADD COLUMN IF NOT EXISTS processors VARCHAR(20)[]; ALTER TABLE monitor_jobs ADD COLUMN IF NOT EXISTS completed_processors VARCHAR(20)[]; ALTER TABLE monitor_jobs ADD COLUMN IF NOT EXISTS failed_processors VARCHAR(20)[]; COMMENT ON COLUMN monitor_jobs.video_id IS 'Foreign key to videos.id'; COMMENT ON COLUMN monitor_jobs.user_id IS 'WordPress user ID'; COMMENT ON COLUMN monitor_jobs.processors IS 'Processors to run: asr, cut, yolo, ocr, face, pose, asrx'; COMMENT ON COLUMN monitor_jobs.completed_processors IS 'Successfully completed processors'; COMMENT ON COLUMN monitor_jobs.failed_processors IS 'Failed processors'; -- 3.1.4: Add foreign key for video_id in monitor_jobs DO $$ BEGIN IF EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'monitor_jobs' AND column_name = 'video_id' ) THEN ALTER TABLE monitor_jobs ADD CONSTRAINT fk_monitor_jobs_video_id FOREIGN KEY (video_id) REFERENCES videos(id) ON DELETE CASCADE; END IF; END $$; -- 3.1.5: Create processor_results table CREATE TABLE IF NOT EXISTS processor_results ( id SERIAL PRIMARY KEY, job_id INTEGER REFERENCES monitor_jobs(id) ON DELETE CASCADE, video_id BIGINT REFERENCES videos(id) ON DELETE CASCADE, processor VARCHAR(20) NOT NULL, status VARCHAR(20) NOT NULL DEFAULT 'pending', output_path TEXT, started_at TIMESTAMP, completed_at TIMESTAMP, error_message TEXT, progress_total INT DEFAULT 0, progress_current INT DEFAULT 0, last_checkpoint JSONB, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, CONSTRAINT unique_job_processor UNIQUE(job_id, processor) ); -- 3.1.6: Create indexes for processor_results CREATE INDEX IF NOT EXISTS idx_processor_results_job ON processor_results(job_id); CREATE INDEX IF NOT EXISTS idx_processor_results_video ON processor_results(video_id); CREATE INDEX IF NOT EXISTS idx_processor_results_status ON processor_results(status); COMMENT ON TABLE processor_results IS 'Tracks individual processor execution status'; COMMENT ON COLUMN processor_results.status IS 'pending, running, completed, failed, skipped'; -- 3.1.7: Add function to update updated_at timestamp CREATE OR REPLACE FUNCTION update_updated_at_column() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = CURRENT_TIMESTAMP; RETURN NEW; END; $$ language 'plpgsql'; -- 3.1.8: Create triggers for updated_at DROP TRIGGER IF EXISTS update_videos_updated_at ON videos; CREATE TRIGGER update_videos_updated_at BEFORE UPDATE ON videos FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); DROP TRIGGER IF EXISTS update_monitor_jobs_updated_at ON monitor_jobs; CREATE TRIGGER update_monitor_jobs_updated_at BEFORE UPDATE ON monitor_jobs FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); DROP TRIGGER IF EXISTS update_processor_results_updated_at ON processor_results; CREATE TRIGGER update_processor_results_updated_at BEFORE UPDATE ON processor_results FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); -- 3.1.9: Add check constraint for videos.status DO $$ BEGIN IF EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'videos' AND column_name = 'status' ) THEN ALTER TABLE videos ADD CONSTRAINT chk_videos_status CHECK (status IN ('pending', 'processing', 'completed', 'failed')); END IF; END $$; -- 3.1.10: Add check constraint for monitor_jobs.status (update existing if needed) ALTER TABLE monitor_jobs DROP CONSTRAINT IF EXISTS chk_monitor_jobs_status; ALTER TABLE monitor_jobs ADD CONSTRAINT chk_monitor_jobs_status CHECK (status IN ('pending', 'running', 'completed', 'failed', 'cancelled')); -- 3.1.11: Add check constraint for processor_results.status ALTER TABLE processor_results DROP CONSTRAINT IF EXISTS chk_processor_results_status; ALTER TABLE processor_results ADD CONSTRAINT chk_processor_results_status CHECK (status IN ('pending', 'running', 'completed', 'failed', 'skipped')); -- 3.1.12: Create index on videos.status for efficient queries CREATE INDEX IF NOT EXISTS idx_videos_status ON videos(status); CREATE INDEX IF NOT EXISTS idx_videos_job_id ON videos(job_id); CREATE INDEX IF NOT EXISTS idx_videos_user_id ON videos(user_id); -- 3.1.13: Create index on monitor_jobs.video_id CREATE INDEX IF NOT EXISTS idx_monitor_jobs_video_id ON monitor_jobs(video_id); CREATE INDEX IF NOT EXISTS idx_monitor_jobs_status_created ON monitor_jobs(status, created_at);