From 007441c285f3d726f3691c3ae03f6ffeab0ad87c Mon Sep 17 00:00:00 2001 From: Lucas Santana Date: Fri, 27 Dec 2024 16:54:34 -0300 Subject: [PATCH] Corrigindo erro supabase --- supabase/functions/process-audio/index.ts | 232 +++++++++++++++------- 1 file changed, 158 insertions(+), 74 deletions(-) diff --git a/supabase/functions/process-audio/index.ts b/supabase/functions/process-audio/index.ts index 332ef7d..cdc0f63 100644 --- a/supabase/functions/process-audio/index.ts +++ b/supabase/functions/process-audio/index.ts @@ -33,15 +33,137 @@ interface AudioRecord { suggestions: string | null } +// Função principal de processamento +async function processAudioRecord(audioRecord: AudioRecord, logger: any) { + const supabase = createClient( + Deno.env.get('SUPABASE_URL') ?? '', + Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? '' + ) + + // 1. Atualiza status para processing + logger.info('status_update_start', 'Atualizando status para processing') + const { error: processingError } = await supabase + .from('story_recordings') + .update({ status: 'processing' }) + .eq('id', audioRecord.id) + + if (processingError) { + logger.error('processing_status_error', processingError) + throw processingError + } + + // 2. Processamento do áudio + logger.info('processing_start', 'Iniciando processamento do áudio') + const transcription = await processAudioWithWhisper(audioRecord.audio_url, logger) + logger.info('transcription_complete', 'Transcrição concluída', { length: transcription?.length || 0 }) + + // 3. Análise do áudio + const analysis = await analyzeReading(transcription, audioRecord.story_id, logger) + logger.info('analysis_complete', 'Análise concluída', { scores: analysis }) + + // 4. Prepara dados para atualização + const updateData = { + status: 'completed', + transcription: transcription || '', + processed_at: new Date().toISOString(), + fluency_score: Number(analysis.fluency_score) || 0, + pronunciation_score: Number(analysis.pronunciation_score) || 0, + accuracy_score: Number(analysis.accuracy_score) || 0, + comprehension_score: Number(analysis.comprehension_score) || 0, + words_per_minute: Number(analysis.words_per_minute) || 0, + pause_count: Number(analysis.pause_count) || 0, + error_count: Number(analysis.error_count) || 0, + self_corrections: Number(analysis.self_corrections) || 0, + strengths: Array.isArray(analysis.strengths) ? analysis.strengths : [], + improvements: Array.isArray(analysis.improvements) ? analysis.improvements : [], + suggestions: analysis.suggestions || '' + } + + logger.info('update_start', 'Iniciando atualização no banco', updateData) + + // 5. Verifica se o registro existe antes do update + const { data: preUpdateCheck, error: preCheckError } = await supabase + .from('story_recordings') + .select('id, status') + .eq('id', audioRecord.id) + .limit(1) + + if (preCheckError) { + logger.error('pre_check_error', preCheckError) + throw preCheckError + } + + if (!preUpdateCheck || preUpdateCheck.length === 0) { + const error = new Error(`Registro ${audioRecord.id} não encontrado antes do update`) + logger.error('pre_update_check_error', error) + throw error + } + + logger.info('pre_update_check', 'Registro encontrado antes do update', preUpdateCheck[0]) + + // Realiza o update + const { data: updateResult, error: updateError } = await supabase + .from('story_recordings') + .update(updateData) + .eq('id', audioRecord.id) + .select() + + if (updateError) { + logger.error('update_error', updateError, { id: audioRecord.id }) + throw updateError + } + + logger.info('update_result', 'Resultado do update', { + hasData: !!updateResult, + dataLength: updateResult?.length || 0, + updateData + }) + + // Verifica novamente após o update + const { data: verifyData, error: verifyError } = await supabase + .from('story_recordings') + .select('*') + .eq('id', audioRecord.id) + .limit(1) + + logger.info('verify_result', 'Resultado da verificação', { + hasData: !!verifyData, + dataLength: verifyData?.length || 0, + firstRecord: verifyData?.[0]?.id + }) + + if (verifyError) { + logger.error('verify_error', verifyError) + throw verifyError + } + + if (!verifyData || verifyData.length === 0) { + const error = new Error(`Registro ${audioRecord.id} não encontrado após atualização`) + logger.error('update_validation_error', error) + throw error + } + + const updatedData = verifyData[0] + + logger.info('update_complete', 'Atualização concluída com sucesso', { + success: true, + updatedData + }) + + return { analysis, updatedData } +} + +// Handler principal da Edge Function serve(async (req) => { + let logger: any = null + let data: { record: AudioRecord } | null = null + if (req.method === 'OPTIONS') { return new Response('ok', { headers: corsHeaders }) } - let logger: any = null - try { - const data = await req.json() + data = await req.json() logger = createLogger(data?.record?.id || 'unknown') logger.info('request_received', 'Iniciando processamento', { @@ -50,67 +172,17 @@ serve(async (req) => { // Validação if (!data?.record?.id || !data?.record?.audio_url) { - logger.error('validation', new Error('Payload inválido')) - throw new Error('Dados inválidos') + const error = new Error('Dados inválidos: ID ou URL do áudio ausentes') + logger.error('validation_error', error) + throw error } - const audioRecord = data.record as AudioRecord - logger.info('record_loaded', 'Registro carregado', audioRecord) - - // Processamento - logger.info('processing_start', 'Iniciando processamento do áudio') - const transcription = await processAudioWithWhisper(audioRecord.audio_url, logger) - logger.info('transcription_complete', 'Transcrição concluída', { length: transcription.length }) - - const analysis = await analyzeReading(transcription, audioRecord.story_id, logger) - logger.info('analysis_complete', 'Análise concluída', { scores: analysis }) - - const supabase = createClient( - Deno.env.get('SUPABASE_URL') ?? '', - Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? '' - ) - - // 1. Atualiza status para processing - await supabase - .from('story_recordings') - .update({ status: 'processing' }) - .eq('id', audioRecord.id) - - // 4. Atualiza o registro com os resultados - const updateData = { - status: 'completed', - transcription, - processed_at: new Date().toISOString(), - fluency_score: analysis.fluency_score || 0, - pronunciation_score: analysis.pronunciation_score || 0, - accuracy_score: analysis.accuracy_score || 0, - comprehension_score: analysis.comprehension_score || 0, - words_per_minute: analysis.words_per_minute || 0, - pause_count: analysis.pause_count || 0, - error_count: analysis.error_count || 0, - self_corrections: analysis.self_corrections || 0, - strengths: Array.isArray(analysis.strengths) ? analysis.strengths : [], - improvements: Array.isArray(analysis.improvements) ? analysis.improvements : [], - suggestions: analysis.suggestions || '' - } - - console.log('Dados para atualização:', updateData) - console.log('AudioRecord', audioRecord) - - const { error: updateError } = await supabase - .from('story_recordings') - .update(updateData) - .eq('id', audioRecord.id) - - if (updateError) { - console.error('Erro na atualização:', updateError) - throw updateError - } + const result = await processAudioRecord(data.record, logger) return new Response( JSON.stringify({ message: 'Áudio processado com sucesso', - data: analysis + data: result.analysis }), { headers: { ...corsHeaders, 'Content-Type': 'application/json' }, @@ -119,28 +191,40 @@ serve(async (req) => { ) } catch (error) { + logger?.error('processing_error', error) console.error('Erro ao processar áudio:', error) + + try { + if (data?.record?.id) { + const supabase = createClient( + Deno.env.get('SUPABASE_URL') ?? '', + Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? '', + { + auth: { + persistSession: false + } + } + ) - // Só tenta atualizar o registro se tiver o ID - if (data?.record?.id) { - const supabase = createClient( - Deno.env.get('SUPABASE_URL') ?? '', - Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? '' - ) - - await supabase - .from('story_recordings') - .update({ - status: 'error', - error_message: error.message - }) - .eq('id', audioRecord.id) + logger?.info('error_status_update_start', 'Atualizando status para error') + + await supabase + .from('story_recordings') + .update({ + status: 'error', + error_message: error.message || 'Erro desconhecido' + }) + .eq('id', data.record.id) + } + } catch (updateError) { + logger?.error('error_status_update_failed', updateError) + console.error('Erro ao atualizar registro com status de erro:', updateError) } return new Response( JSON.stringify({ error: 'Falha ao processar áudio', - details: error.message + details: error.message || 'Erro desconhecido' }), { headers: { ...corsHeaders, 'Content-Type': 'application/json' }, @@ -148,4 +232,4 @@ serve(async (req) => { } ) } -}) \ No newline at end of file +}) \ No newline at end of file