* Fire-and-forget: generate a Gemini cover image for a newly-submitted * perspective and auto-approve it so the review dashboard has something * to show. Mirrors the digest-publisher pattern: errors are logged but * never fail the caller — submission succeeds even if Gemini is down or * rate-lim
( perspectiveId: string, title: string, category: string | null, excerpt: string | null, )
| 114 | * title/body to prompt on. |
| 115 | */ |
| 116 | async function generateCoverImageForPendingReview( |
| 117 | perspectiveId: string, |
| 118 | title: string, |
| 119 | category: string | null, |
| 120 | excerpt: string | null, |
| 121 | ): Promise<void> { |
| 122 | const { imageBuffer, promptUsed, c2pa } = await generateIllustration({ |
| 123 | title, |
| 124 | category: category ?? 'Perspective', |
| 125 | excerpt: excerpt ?? undefined, |
| 126 | }); |
| 127 | |
| 128 | const illustration = await createIllustration({ |
| 129 | perspective_id: perspectiveId, |
| 130 | image_data: imageBuffer, |
| 131 | prompt_used: promptUsed, |
| 132 | status: 'generated', |
| 133 | c2pa_signed_at: c2pa?.signedAt, |
| 134 | c2pa_manifest_digest: c2pa?.manifestDigest, |
| 135 | }); |
| 136 | |
| 137 | await approveIllustration(illustration.id, perspectiveId); |
| 138 | logger.info({ perspectiveId }, 'Cover image generated and approved for pending_review content'); |
| 139 | } |
| 140 | |
| 141 | /** |
| 142 | * Notify reviewers that content has entered pending_review. |
no test coverage detected