feat(youtube): add upload queue job definition

Add YOUTUBE_UPLOAD to QUEUE_NAMES and create the job definition
with enqueue and status functions. Uses 2 retry attempts instead
of the default 3 since uploads are resource-intensive.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Martin Porwoll 2026-02-14 13:30:07 +00:00
parent 289b69380f
commit fb4d5a8fe5
2 changed files with 80 additions and 0 deletions

View file

@ -0,0 +1,79 @@
/**
* YouTube Upload Job Definition
*
* Definiert den YouTube-Upload-Job fuer die Queue.
* Uploads sind ressourcenintensiv, daher nur 2 Retry-Versuche.
*/
import { Job } from 'bullmq'
import { getQueue, QUEUE_NAMES, defaultJobOptions } from '../queue-service'
// Job-Daten Typen
export interface YouTubeUploadJobData {
contentId: number
channelId: number
mediaId: number
metadata: {
title: string
description: string
tags: string[]
visibility: 'public' | 'unlisted' | 'private'
categoryId?: string
}
scheduledPublishAt?: string
triggeredBy: number
}
export interface YouTubeUploadJobResult {
success: boolean
youtubeVideoId?: string
youtubeUrl?: string
error?: string
timestamp: string
}
/**
* Fuegt einen YouTube-Upload-Job zur Queue hinzu
*/
export async function enqueueYouTubeUpload(
data: YouTubeUploadJobData,
): Promise<Job<YouTubeUploadJobData>> {
const queue = getQueue(QUEUE_NAMES.YOUTUBE_UPLOAD)
const jobOptions = {
...defaultJobOptions,
attempts: 2,
}
const job = await queue.add('youtube-upload', data, jobOptions)
console.log(
`[YouTubeUploadQueue] Job ${job.id} queued for content ${data.contentId} on channel ${data.channelId}`,
)
return job
}
/**
* Holt den Status eines YouTube-Upload-Jobs
*/
export async function getYouTubeUploadJobStatus(jobId: string): Promise<{
state: string
progress: number
result?: YouTubeUploadJobResult
failedReason?: string
} | null> {
const queue = getQueue(QUEUE_NAMES.YOUTUBE_UPLOAD)
const job = await queue.getJob(jobId)
if (!job) return null
const [state, progress] = await Promise.all([job.getState(), job.progress])
return {
state,
progress: typeof progress === 'number' ? progress : 0,
result: job.returnvalue as YouTubeUploadJobResult | undefined,
failedReason: job.failedReason,
}
}

View file

@ -13,6 +13,7 @@ export const QUEUE_NAMES = {
EMAIL: 'email', EMAIL: 'email',
PDF: 'pdf', PDF: 'pdf',
CLEANUP: 'cleanup', CLEANUP: 'cleanup',
YOUTUBE_UPLOAD: 'youtube-upload',
} as const } as const
export type QueueName = (typeof QUEUE_NAMES)[keyof typeof QUEUE_NAMES] export type QueueName = (typeof QUEUE_NAMES)[keyof typeof QUEUE_NAMES]