import { GlobalFunctions, TransferAreaProperties } from '@/GlobalFunctions'; import { apiService } from './api'; /** * Interface para a resposta da API de transcrição */ export interface TranscriptionResponse { success: boolean; transcription_id: string; audio_url: string; message: string; } /** * Interface para uma transcrição armazenada no banco de dados */ export interface TranscriptionRecord { id: string; user_email: string; estabelecimento_id: number; audio_file_name: string; audio_duration_seconds: number; transcription_text: string; model: string; audio_url: string; cost_usd: string; created_at: string; } /** * Interface para os dados necessários para transcrição */ export interface TranscriptionRequest { audioFile: File; userEmail?: string; estabelecimentoId?: number; } /** * Serviço de transcrição de áudio */ class TranscriptionService { private readonly TRANSCRIPTION_ENDPOINT = '/webhook/codex/transcrever_audio'; private readonly GET_TRANSCRIPTIONS_ENDPOINT = '/webhook/fd073ec0-81ab-4681-8acd-b0da71f6ad30/codex/get_transcrever_audio'; private readonly DELETE_TRANSCRIPTION_ENDPOINT = '/webhook/fd073ec0-81ab-4681-8acd-b0da71f6ad30/codex/delete_transcrever_audio'; /** * Transcreve um arquivo de áudio * * @param request - Dados da requisição (arquivo, email, estabelecimento) * @returns Promise com a resposta da API */ async transcribeAudio(request: TranscriptionRequest): Promise { const { audioFile, userEmail, estabelecimentoId } = request; // Cria FormData para envio multipart const formData = new FormData(); formData.append('data', audioFile); // Usa valores do .env se não forem fornecidos const email = GlobalFunctions.getTransferProperty(TransferAreaProperties.UsuarioEmail);//userEmail || import.meta.env.VITE_USER_EMAIL || ''; const estabId = GlobalFunctions.getTransferProperty(TransferAreaProperties.EstabelecimentoCodigo);//estabelecimentoId || import.meta.env.VITE_ESTABELECIMENTO_ID || ''; formData.append('user_email', email); formData.append('estabelecimento_id', estabId.toString()); // Log para debug (remover em produção se necessário) console.log('Enviando transcrição:', { fileName: audioFile.name, fileSize: audioFile.size, fileType: audioFile.type, userEmail: email, estabelecimentoId: estabId, }); try { // Faz a requisição usando o serviço de API const response = await apiService.postFormData( this.TRANSCRIPTION_ENDPOINT, formData ); return response.data; } catch (error: any) { // Trata erros específicos console.error('Erro na transcrição:', error); throw { success: false, message: error.message || 'Erro ao transcrever áudio', status: error.status, }; } } /** * Valida se o arquivo de áudio é suportado * * @param file - Arquivo a ser validado * @param maxSizeMB - Tamanho máximo em MB (padrão: 25MB) * @returns Objeto com resultado da validação */ validateAudioFile(file: File, maxSizeMB: number = 25): { valid: boolean; error?: string } { const SUPPORTED_FORMATS = ['flac', 'm4a', 'mp3', 'mp4', 'mpeg', 'mpga', 'oga', 'ogg', 'wav', 'webm']; const MAX_FILE_SIZE = maxSizeMB * 1024 * 1024; // Valida tamanho if (file.size > MAX_FILE_SIZE) { return { valid: false, error: `Arquivo muito grande. Tamanho máximo: ${maxSizeMB}MB`, }; } // Valida formato const fileExtension = file.name.split('.').pop()?.toLowerCase(); if (!fileExtension || !SUPPORTED_FORMATS.includes(fileExtension)) { return { valid: false, error: `Formato não suportado. Formatos aceitos: ${SUPPORTED_FORMATS.join(', ')}`, }; } return { valid: true }; } /** * Lista transcrições do banco de dados com paginação * * @param userEmail - Email do usuário * @param page - Número da página (padrão: 1) * @param perPage - Quantidade de itens por página (padrão: 10) * @returns Promise com o array de transcrições */ async getTranscriptions( userEmail?: string, page: number = 1, perPage: number = 10 ): Promise { // Usa valores do GlobalFunctions se não forem fornecidos const email = userEmail || GlobalFunctions.getTransferProperty(TransferAreaProperties.UsuarioEmail); if (!email) { throw { success: false, message: 'Email do usuário não fornecido', }; } console.log('Buscando transcrições:', { userEmail: email, page, perPage, }); try { // Faz a requisição GET com parâmetros na URL e query const response = await apiService.get( `${this.GET_TRANSCRIPTIONS_ENDPOINT}/${email}`, { params: { page: page.toString(), per_page: perPage.toString(), }, } ); console.log('Resposta completa da API:', response); console.log('response.data:', response.data); console.log('É array?:', Array.isArray(response.data)); // A API retorna diretamente o array de transcrições // Garante que sempre retorna um array if (Array.isArray(response.data)) { return response.data; } else if (response.data && typeof response.data === 'object') { // Se a resposta for um objeto com uma propriedade 'transcriptions' ou similar console.warn('API retornou objeto em vez de array:', response.data); // Tenta encontrar o array dentro do objeto if (Array.isArray((response.data as any).transcriptions)) { return (response.data as any).transcriptions; } else if (Array.isArray((response.data as any).data)) { return (response.data as any).data; } } // Se não conseguir extrair array, retorna vazio console.warn('Não foi possível extrair array de transcrições da resposta'); return []; } catch (error: any) { console.error('Erro ao buscar transcrições:', error); throw { success: false, message: error.message || 'Erro ao buscar transcrições', status: error.status, }; } } /** * Deleta uma transcrição do banco de dados * * @param transcriptionId - ID da transcrição a ser deletada * @param userEmail - Email do usuário (opcional) * @returns Promise com sucesso ou erro */ async deleteTranscription(transcriptionId: string, userEmail?: string): Promise<{ success: boolean; message?: string }> { // Usa valores do GlobalFunctions se não forem fornecidos const email = userEmail || GlobalFunctions.getTransferProperty(TransferAreaProperties.UsuarioEmail); if (!email) { throw { success: false, message: 'Email do usuário não fornecido', }; } if (!transcriptionId) { throw { success: false, message: 'ID da transcrição não fornecido', }; } console.log('Deletando transcrição:', { transcriptionId, userEmail: email, }); try { // Faz a requisição DELETE com parâmetros na URL const response = await apiService.delete<{ success: boolean; message?: string } | Array<{ success: boolean; message?: string }>>( `${this.DELETE_TRANSCRIPTION_ENDPOINT}/${email}/${transcriptionId}` ); console.log('Resposta completa do DELETE:', response); console.log('response.data:', response.data); // A API retorna um array com um objeto: [{"success":true}] let result: { success: boolean; message?: string }; if (Array.isArray(response.data)) { // Se for array, pega o primeiro elemento result = response.data[0]; console.log('API retornou array, usando primeiro elemento:', result); } else { // Se for objeto direto result = response.data; console.log('API retornou objeto direto:', result); } // Garante que tem a estrutura mínima return { success: result.success ?? true, message: result.message || 'Transcrição deletada com sucesso', }; } catch (error: any) { console.error('Erro ao deletar transcrição:', error); throw { success: false, message: error.message || 'Erro ao deletar transcrição', status: error.status, }; } } } // Exporta instância única (Singleton) export const transcriptionService = new TranscriptionService();