import { serve } from 'https://deno.land/std@0.168.0/http/server.ts' import { createClient } from 'https://esm.sh/@supabase/supabase-js@2' import OpenAI from 'https://esm.sh/openai@4.20.1' const openai = new OpenAI({ apiKey: Deno.env.get('OPENAI_API_KEY') }); interface StoryPrompt { theme_id: string; subject_id: string; character_id: string; setting_id: string; context?: string; } serve(async (req) => { const { record } = await req.json() console.log('[Request]', record) try { const supabase = createClient( Deno.env.get('SUPABASE_URL') ?? '', Deno.env.get('SUPABASE_ANON_KEY') ?? '' ) console.log('[Supabase] Cliente inicializado') console.log('[DB] Buscando categorias...') const [themeResult, subjectResult, characterResult, settingResult] = await Promise.all([ supabase.from('story_themes').select('*').eq('id', record.theme_id).single(), supabase.from('story_subjects').select('*').eq('id', record.subject_id).single(), supabase.from('story_characters').select('*').eq('id', record.character_id).single(), supabase.from('story_settings').select('*').eq('id', record.setting_id).single() ]) console.log('[DB] Resultados das consultas:', { theme: themeResult, subject: subjectResult, character: characterResult, setting: settingResult }) if (themeResult.error) throw new Error(`Erro ao buscar tema: ${themeResult.error.message}`); if (subjectResult.error) throw new Error(`Erro ao buscar disciplina: ${subjectResult.error.message}`); if (characterResult.error) throw new Error(`Erro ao buscar personagem: ${characterResult.error.message}`); if (settingResult.error) throw new Error(`Erro ao buscar cenário: ${settingResult.error.message}`); if (!themeResult.data) throw new Error(`Tema não encontrado: ${record.theme_id}`); if (!subjectResult.data) throw new Error(`Disciplina não encontrada: ${record.subject_id}`); if (!characterResult.data) throw new Error(`Personagem não encontrado: ${record.character_id}`); if (!settingResult.data) throw new Error(`Cenário não encontrado: ${record.setting_id}`); const theme = themeResult.data; const subject = subjectResult.data; const character = characterResult.data; const setting = settingResult.data; console.log('[Validation] Categorias validadas com sucesso') console.log('[GPT] Construindo prompt...') const prompt = ` Crie uma história educativa para crianças com as seguintes características: Tema: ${theme.title} Disciplina: ${subject.title} Personagem Principal: ${character.title} Cenário: ${setting.title} ${record.context ? `Contexto Adicional: ${record.context}` : ''} Requisitos: - História adequada para crianças de 6-12 anos - Conteúdo educativo focado em ${subject.title} - Linguagem clara e envolvente - 3-5 páginas de conteúdo - Cada página deve ter um texto curto e sugestão para uma imagem - Evitar conteúdo sensível ou inadequado - Incluir elementos de ${theme.title} - Ambientado em ${setting.title} - Personagem principal baseado em ${character.title} Formato da resposta: { "title": "Título da História", "pages": [ { "text": "Texto da página", "image_prompt": "Descrição para gerar a imagem" } ] } ` console.log('[GPT] Prompt construído:', prompt) console.log('[GPT] Iniciando geração da história...') const completion = await openai.chat.completions.create({ model: "gpt-4o-mini", messages: [ { role: "system", content: "Você é um contador de histórias infantis especializado em conteúdo educativo." }, { role: "user", content: prompt } ], temperature: 0.7, max_tokens: 1000 }) console.log('[GPT] História gerada:', completion.choices[0].message) const storyContent = JSON.parse(completion.choices[0].message.content || '{}') console.log('[DALL-E] Iniciando geração de imagens...') const pages = await Promise.all( storyContent.pages.map(async (page: any, index: number) => { console.log(`[DALL-E] Gerando imagem ${index + 1}/${storyContent.pages.length}...`) const imageResponse = await openai.images.generate({ prompt: `${page.image_prompt}. Style: children's book illustration, colorful, educational, safe for kids`, n: 1, size: "1024x1024" }) console.log(`[DALL-E] Imagem ${index + 1} gerada com sucesso`) return { text: page.text, image: imageResponse.data[0].url } }) ) console.log('[DALL-E] Todas as imagens geradas com sucesso') console.log('[DB] Salvando história...') await supabase .from('stories') .update({ title: storyContent.title, content: { title: storyContent.title, pages: pages, theme: theme.title, subject: subject.title, character: character.title, setting: setting.title, context: record.context }, status: 'published' }) .eq('id', record.id) console.log('[DB] História salva com sucesso') return new Response( JSON.stringify({ success: true, message: 'História gerada e salva com sucesso', storyId: record.id }), { headers: { 'Content-Type': 'application/json' } } ) } catch (error) { console.error('[Error] Erro ao gerar história:', error) console.error('[Error] Stack trace:', error.stack) return new Response( JSON.stringify({ error: error.message, stack: error.stack, timestamp: new Date().toISOString() }), { headers: { 'Content-Type': 'application/json' }, status: 500 } ) } })