From 2de223561c0881ba5514eef87da3e038061be220 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 17 Jul 2026 06:57:10 +0000 Subject: [PATCH] Remove unused content-approval Directus hook The content-approval hook listened on podcast_generated_content.items.update and copied approved shownotes to the podcast description. Since PR #207 removed the legacy Gemini generator that wrote to podcast_generated_content, shownotes now go straight to podcasts.description, leaving this hook unused. Deletes src/content-approval/ and its entry in the bundle manifest. The shared safeHook helper stays (used by 15 other hooks). schema.json is intentionally untouched (auto-managed by the schema-snapshot workflow). --- .../package.json | 5 - .../src/content-approval/index.ts | 130 ------------------ 2 files changed, 135 deletions(-) delete mode 100644 directus-cms/extensions/directus-extension-programmierbar-bundle/src/content-approval/index.ts diff --git a/directus-cms/extensions/directus-extension-programmierbar-bundle/package.json b/directus-cms/extensions/directus-extension-programmierbar-bundle/package.json index 39e06c6f..4d6bacc0 100644 --- a/directus-cms/extensions/directus-extension-programmierbar-bundle/package.json +++ b/directus-cms/extensions/directus-extension-programmierbar-bundle/package.json @@ -79,11 +79,6 @@ "name": "member-matching", "source": "src/member-matching/index.ts" }, - { - "type": "hook", - "name": "content-approval", - "source": "src/content-approval/index.ts" - }, { "type": "hook", "name": "social-media-publish", diff --git a/directus-cms/extensions/directus-extension-programmierbar-bundle/src/content-approval/index.ts b/directus-cms/extensions/directus-extension-programmierbar-bundle/src/content-approval/index.ts deleted file mode 100644 index 821edc57..00000000 --- a/directus-cms/extensions/directus-extension-programmierbar-bundle/src/content-approval/index.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { defineHook } from '@directus/extensions-sdk' -import { safeAction } from '../shared/safeHook.ts' - -const HOOK_NAME = 'content-approval' - -export default defineHook(({ action }, hookContext) => { - const logger = hookContext.logger - const ItemsService = hookContext.services.ItemsService - const getSchema = hookContext.getSchema - - // Listen for updates to podcast_generated_content - action('podcast_generated_content.items.update', safeAction(HOOK_NAME, logger, async function (metadata, eventContext) { - const { payload, keys } = metadata - - if (payload.status === 'approved') { - await handleApproval(keys, eventContext) - } else if (payload.status && payload.status !== 'approved') { - await handleUnapproval(keys, eventContext) - } - })) - - async function handleApproval(keys: string[], eventContext: any) { - try { - const schema = await getSchema() - - const generatedContentService = new ItemsService('podcast_generated_content', { - schema, - accountability: eventContext.accountability, - }) - - const podcastsService = new ItemsService('podcasts', { - schema, - accountability: eventContext.accountability, - }) - - // Process each approved content item - for (const contentId of keys) { - const content = await generatedContentService.readOne(contentId, { - fields: ['id', 'podcast_id', 'content_type', 'generated_text'], - }) - - if (!content || !content.podcast_id) { - continue - } - - // If this is shownotes, copy to podcast description - if (content.content_type === 'shownotes') { - if (content.generated_text) { - logger.info( - `${HOOK_NAME}: Copying approved shownotes to podcast ${content.podcast_id} description` - ) - - await podcastsService.updateOne(content.podcast_id, { - description: content.generated_text, - }) - } - } - - // Check if all content for this podcast is approved - const allContent = await generatedContentService.readByQuery({ - filter: { - podcast_id: { _eq: content.podcast_id }, - }, - fields: ['id', 'status'], - }) - - const allApproved = - allContent.length > 0 && allContent.every((c: any) => c.status === 'approved') - - if (allApproved) { - logger.info( - `${HOOK_NAME}: All content approved for podcast ${content.podcast_id}, updating status to 'approved'` - ) - - await podcastsService.updateOne(content.podcast_id, { - publishing_status: 'approved', - }) - } - } - } catch (err: any) { - logger.error(`${HOOK_NAME}: Error processing content approval: ${err?.message || err}`) - } - } - - async function handleUnapproval(keys: string[], eventContext: any) { - try { - const schema = await getSchema() - - const generatedContentService = new ItemsService('podcast_generated_content', { - schema, - accountability: eventContext.accountability, - }) - - const podcastsService = new ItemsService('podcasts', { - schema, - accountability: eventContext.accountability, - }) - - // Process each unapproved content item - for (const contentId of keys) { - const content = await generatedContentService.readOne(contentId, { - fields: ['id', 'podcast_id'], - }) - - if (!content || !content.podcast_id) { - continue - } - - // If the podcast was marked as approved, revert to content_review - const podcast = await podcastsService.readOne(content.podcast_id, { - fields: ['publishing_status'], - }) - - if (podcast.publishing_status === 'approved') { - logger.info( - `${HOOK_NAME}: Content unapproved for podcast ${content.podcast_id}, reverting status to 'content_review'` - ) - - await podcastsService.updateOne(content.podcast_id, { - publishing_status: 'content_review', - }) - } - } - } catch (err: any) { - logger.error(`${HOOK_NAME}: Error processing content unapproval: ${err?.message || err}`) - } - } - - logger.info(`${HOOK_NAME} hook registered`) -})