mirror of
https://github.com/lucasrcsantana/story-generator.git
synced 2025-12-16 21:37:51 +00:00
fix: corrigindo salvamento da história no banco de dados
This commit is contained in:
parent
7e3b4551ec
commit
8af9950ed7
47
CHANGELOG.md
Normal file
47
CHANGELOG.md
Normal file
@ -0,0 +1,47 @@
|
||||
# Changelog
|
||||
|
||||
Todas as mudanças notáveis neste projeto serão documentadas neste arquivo.
|
||||
|
||||
O formato é baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.0.0/),
|
||||
e este projeto adere ao [Semantic Versioning](https://semver.org/lang/pt-BR/).
|
||||
|
||||
## [0.1.0] - 2024-03-23
|
||||
|
||||
### Adicionado
|
||||
- Edge function `generate-story` para geração de histórias com IA
|
||||
- Integração com OpenAI GPT para criação de texto
|
||||
- Integração com DALL-E para geração de imagens
|
||||
- Sistema de logs estruturados para monitoramento
|
||||
- Tratamento robusto de erros e validações
|
||||
|
||||
- Componente `StoryGenerator` para interface de criação
|
||||
- Fluxo de seleção de categorias (tema, disciplina, personagem, cenário)
|
||||
- Feedback visual do processo de geração
|
||||
- Validações de campos obrigatórios
|
||||
- Navegação automática entre etapas
|
||||
- Tratamento de erros com feedback visual
|
||||
|
||||
### Modificado
|
||||
- Atualização do schema do banco para suportar novas categorias
|
||||
- Adição de tabelas para temas, disciplinas, personagens e cenários
|
||||
- Relacionamentos entre histórias e categorias
|
||||
- Índices para otimização de consultas
|
||||
|
||||
### Técnico
|
||||
- Implementação de logs estruturados com prefixos por contexto
|
||||
- Validações de dados em múltiplas camadas
|
||||
- Tratamento de respostas da IA com fallbacks
|
||||
- Otimização de queries no banco de dados
|
||||
- Feedback em tempo real do processo de geração
|
||||
|
||||
### Segurança
|
||||
- Validação de dados de entrada na edge function
|
||||
- Verificação de permissões do usuário
|
||||
- Sanitização de prompts para a IA
|
||||
- Proteção contra dados sensíveis nos logs
|
||||
|
||||
### Próximos Passos
|
||||
- [ ] Implementar cache de respostas da IA
|
||||
- [ ] Adicionar retry policy para falhas de geração
|
||||
- [ ] Melhorar prompts para histórias mais educativas
|
||||
- [ ] Adicionar métricas de uso e performance
|
||||
@ -14,7 +14,26 @@ interface StoryPrompt {
|
||||
context?: string;
|
||||
}
|
||||
|
||||
const ALLOWED_ORIGINS = [
|
||||
'http://localhost:5173', // Vite dev server
|
||||
'http://localhost:3000', // Caso use outro port
|
||||
'https://historiasmagicas.netlify.app' // Produção
|
||||
];
|
||||
|
||||
serve(async (req) => {
|
||||
const origin = req.headers.get('origin') || '';
|
||||
const corsHeaders = {
|
||||
'Access-Control-Allow-Origin': ALLOWED_ORIGINS.includes(origin) ? origin : ALLOWED_ORIGINS[0],
|
||||
'Access-Control-Allow-Methods': 'POST, OPTIONS',
|
||||
'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
|
||||
'Access-Control-Max-Age': '86400', // 24 horas
|
||||
};
|
||||
|
||||
// Preflight request
|
||||
if (req.method === 'OPTIONS') {
|
||||
return new Response('ok', { headers: corsHeaders })
|
||||
}
|
||||
|
||||
const { record } = await req.json()
|
||||
console.log('[Request]', record)
|
||||
|
||||
@ -111,6 +130,11 @@ serve(async (req) => {
|
||||
console.log('[GPT] História gerada:', completion.choices[0].message)
|
||||
const storyContent = JSON.parse(completion.choices[0].message.content || '{}')
|
||||
|
||||
// Validar estrutura do retorno da IA
|
||||
if (!storyContent.title || !Array.isArray(storyContent.pages)) {
|
||||
throw new Error('Formato inválido retornado pela IA');
|
||||
}
|
||||
|
||||
console.log('[DALL-E] Iniciando geração de imagens...')
|
||||
const pages = await Promise.all(
|
||||
storyContent.pages.map(async (page: any, index: number) => {
|
||||
@ -131,33 +155,53 @@ serve(async (req) => {
|
||||
|
||||
console.log('[DALL-E] Todas as imagens geradas com sucesso')
|
||||
|
||||
console.log('[DB] Salvando história...')
|
||||
await supabase
|
||||
.from('stories')
|
||||
.update({
|
||||
// Preparar dados para salvar
|
||||
const storyData = {
|
||||
title: storyContent.title,
|
||||
content: {
|
||||
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)
|
||||
pages: pages,
|
||||
theme: theme.title,
|
||||
subject: subject.title,
|
||||
character: character.title,
|
||||
setting: setting.title,
|
||||
context: record.context,
|
||||
original_prompt: prompt,
|
||||
ai_response: completion.choices[0].message.content
|
||||
},
|
||||
status: 'published',
|
||||
theme_id: theme.id,
|
||||
subject_id: subject.id,
|
||||
character_id: character.id,
|
||||
setting_id: setting.id,
|
||||
updated_at: new Date().toISOString()
|
||||
}
|
||||
|
||||
console.log('[DB] História salva com sucesso')
|
||||
console.log('[DB] Dados para salvar:', storyData)
|
||||
|
||||
// Atualizar história no Supabase
|
||||
console.log('[DB] Salvando história...')
|
||||
const { data: savedStory, error: updateError } = await supabase
|
||||
.from('stories')
|
||||
.update(storyData)
|
||||
.eq('id', record.id)
|
||||
.select()
|
||||
.single()
|
||||
|
||||
if (updateError) {
|
||||
throw new Error(`Erro ao salvar história: ${updateError.message}`);
|
||||
}
|
||||
|
||||
console.log('[DB] História salva com sucesso:', savedStory)
|
||||
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
success: true,
|
||||
message: 'História gerada e salva com sucesso',
|
||||
storyId: record.id
|
||||
storyId: record.id,
|
||||
story: savedStory
|
||||
}),
|
||||
{ headers: { 'Content-Type': 'application/json' } }
|
||||
{ headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
|
||||
)
|
||||
|
||||
} catch (error) {
|
||||
@ -171,9 +215,9 @@ serve(async (req) => {
|
||||
timestamp: new Date().toISOString()
|
||||
}),
|
||||
{
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
|
||||
status: 500
|
||||
}
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
||||
Loading…
Reference in New Issue
Block a user