mirror of
https://github.com/complexcaresolutions/cms.c2sgmbh.git
synced 2026-03-17 17:24:12 +00:00
feat(youtube): add auto status transition hook
Automatically transitions YouTube content status when conditions are met (e.g., upload_scheduled -> published when videoId is present) and sends notifications to assigned users. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
9e7b433cd0
commit
8ae5841cc1
3 changed files with 111 additions and 1 deletions
|
|
@ -9,6 +9,7 @@ import {
|
|||
} from '../lib/youtubeAccess'
|
||||
import { createTasksOnStatusChange } from '../hooks/youtubeContent/createTasksOnStatusChange'
|
||||
import { downloadThumbnail } from '../hooks/youtubeContent/downloadThumbnail'
|
||||
import { autoStatusTransitions } from '../hooks/youtubeContent/autoStatusTransitions'
|
||||
// TODO: ScriptSectionBlock causes admin UI rendering issues
|
||||
// import { ScriptSectionBlock } from '../blocks/ScriptSectionBlock'
|
||||
|
||||
|
|
@ -39,7 +40,7 @@ export const YouTubeContent: CollectionConfig = {
|
|||
delete: isYouTubeManager,
|
||||
},
|
||||
hooks: {
|
||||
afterChange: [createTasksOnStatusChange, downloadThumbnail],
|
||||
afterChange: [createTasksOnStatusChange, downloadThumbnail, autoStatusTransitions],
|
||||
beforeChange: [
|
||||
// Auto-Slug generieren
|
||||
({ data }) => {
|
||||
|
|
|
|||
77
src/hooks/youtubeContent/autoStatusTransitions.ts
Normal file
77
src/hooks/youtubeContent/autoStatusTransitions.ts
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
import type { CollectionAfterChangeHook } from 'payload'
|
||||
import { NotificationService } from '@/lib/jobs/NotificationService'
|
||||
|
||||
interface TransitionContext {
|
||||
currentStatus: string
|
||||
youtubeVideoId?: string | null
|
||||
hasAllChecklistsComplete: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the next status based on current state and conditions
|
||||
*/
|
||||
export function getNextStatus(context: TransitionContext): string | null {
|
||||
const { currentStatus, youtubeVideoId } = context
|
||||
|
||||
// Upload completed → published
|
||||
if (currentStatus === 'upload_scheduled' && youtubeVideoId) {
|
||||
return 'published'
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a manual transition should be suggested
|
||||
*/
|
||||
export function shouldTransitionStatus(
|
||||
status: string,
|
||||
context: { hasVideoFile?: boolean },
|
||||
): boolean {
|
||||
if (status === 'approved' && context.hasVideoFile) return true
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook: Automatische Status-Übergänge nach Änderungen
|
||||
*/
|
||||
export const autoStatusTransitions: CollectionAfterChangeHook = async ({
|
||||
doc,
|
||||
previousDoc,
|
||||
req,
|
||||
operation,
|
||||
}) => {
|
||||
if (operation !== 'update') return doc
|
||||
|
||||
const nextStatus = getNextStatus({
|
||||
currentStatus: doc.status,
|
||||
youtubeVideoId: doc.youtube?.videoId,
|
||||
hasAllChecklistsComplete: false,
|
||||
})
|
||||
|
||||
if (nextStatus && nextStatus !== doc.status) {
|
||||
console.log(`[autoStatusTransitions] ${doc.id}: ${doc.status} → ${nextStatus}`)
|
||||
|
||||
await req.payload.update({
|
||||
collection: 'youtube-content',
|
||||
id: doc.id,
|
||||
data: { status: nextStatus },
|
||||
depth: 0,
|
||||
})
|
||||
|
||||
// Notification
|
||||
if (doc.assignedTo) {
|
||||
const assignedToId = typeof doc.assignedTo === 'object' ? doc.assignedTo.id : doc.assignedTo
|
||||
const notificationService = new NotificationService(req.payload)
|
||||
await notificationService.createNotification({
|
||||
recipientId: assignedToId,
|
||||
type: 'system',
|
||||
title: `Video-Status automatisch geändert: ${nextStatus}`,
|
||||
link: `/admin/collections/youtube-content/${doc.id}`,
|
||||
relatedVideoId: doc.id,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return doc
|
||||
}
|
||||
32
tests/unit/youtube/auto-status-transitions.unit.spec.ts
Normal file
32
tests/unit/youtube/auto-status-transitions.unit.spec.ts
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import { describe, it, expect } from 'vitest'
|
||||
import { getNextStatus, shouldTransitionStatus } from '@/hooks/youtubeContent/autoStatusTransitions'
|
||||
|
||||
describe('Auto Status Transitions', () => {
|
||||
it('should transition to published when upload is complete', () => {
|
||||
const result = getNextStatus({
|
||||
currentStatus: 'upload_scheduled',
|
||||
youtubeVideoId: 'VID123',
|
||||
hasAllChecklistsComplete: false,
|
||||
})
|
||||
expect(result).toBe('published')
|
||||
})
|
||||
|
||||
it('should not transition if no video ID on upload_scheduled', () => {
|
||||
const result = getNextStatus({
|
||||
currentStatus: 'upload_scheduled',
|
||||
youtubeVideoId: null,
|
||||
hasAllChecklistsComplete: false,
|
||||
})
|
||||
expect(result).toBeNull()
|
||||
})
|
||||
|
||||
it('should transition approved to upload_scheduled when video file exists', () => {
|
||||
const result = shouldTransitionStatus('approved', { hasVideoFile: true })
|
||||
expect(result).toBe(true)
|
||||
})
|
||||
|
||||
it('should not suggest transition for published status', () => {
|
||||
const result = shouldTransitionStatus('published', { hasVideoFile: true })
|
||||
expect(result).toBe(false)
|
||||
})
|
||||
})
|
||||
Loading…
Reference in a new issue