Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | import { NextResponse } from 'next/server' import { PHI_EXPLORE_SUBJECTS } from '@/components/toys/number-line/constants/phiExploreData' import { startPhiExploreGeneration } from '@/lib/tasks/phi-explore-generate' import type { PhiExploreGenerateInput } from '@/lib/tasks/phi-explore-generate' import { withAuth } from '@/lib/auth/withAuth' const VALID_PROVIDERS = ['gemini', 'openai'] as const const VALID_THEMES = ['light', 'dark'] as const /** * POST /api/admin/constant-images/phi-explore/generate * * Starts a background task to generate phi explore subject illustrations. * Body: { provider, model, targets?, forceRegenerate?, theme?, pipeline? } * pipeline: true → generates all subjects × [base, light, dark] in a single server-side task * Response: { taskId: string } */ export const POST = withAuth( async (request, { userId }) => { try { const body = await request.json() const { provider, model, targets, forceRegenerate, theme, pipeline } = body // Validate provider if (!provider || !VALID_PROVIDERS.includes(provider)) { return NextResponse.json( { error: `provider must be one of: ${VALID_PROVIDERS.join(', ')}` }, { status: 400 } ) } // Validate model if (typeof model !== 'string' || model.trim().length === 0) { return NextResponse.json({ error: 'model must be a non-empty string' }, { status: 400 }) } // Validate top-level theme if (theme !== undefined && !VALID_THEMES.includes(theme)) { return NextResponse.json( { error: `theme must be one of: ${VALID_THEMES.join(', ')}` }, { status: 400 } ) } // Build targets list let resolvedTargets: PhiExploreGenerateInput['targets'] if (pipeline) { // Pipeline: all subjects × [base, light, dark] in order resolvedTargets = [ ...PHI_EXPLORE_SUBJECTS.map((s) => ({ subjectId: s.id })), ...PHI_EXPLORE_SUBJECTS.map((s) => ({ subjectId: s.id, theme: 'light' as const })), ...PHI_EXPLORE_SUBJECTS.map((s) => ({ subjectId: s.id, theme: 'dark' as const })), ] } else if (targets && Array.isArray(targets) && targets.length > 0) { const subjectIds = new Set(PHI_EXPLORE_SUBJECTS.map((s) => s.id)) for (const t of targets) { if (!subjectIds.has(t.subjectId)) { return NextResponse.json( { error: `Unknown subjectId: ${t.subjectId}` }, { status: 400 } ) } if (t.theme !== undefined && !VALID_THEMES.includes(t.theme)) { return NextResponse.json( { error: `target theme must be one of: ${VALID_THEMES.join(', ')}` }, { status: 400 } ) } } resolvedTargets = targets } else { // Default: all subjects (with optional top-level theme) resolvedTargets = PHI_EXPLORE_SUBJECTS.map((s) => ({ subjectId: s.id, ...(theme && { theme: theme as 'light' | 'dark' }), })) } const taskId = await startPhiExploreGeneration({ provider, model: model.trim(), targets: resolvedTargets, forceRegenerate: !!forceRegenerate, _userId: userId, }) return NextResponse.json({ taskId }) } catch (error) { console.error('Error starting phi explore generation:', error) return NextResponse.json({ error: 'Failed to start phi explore generation' }, { status: 500 }) } }, { role: 'admin' } ) |