Files
hack/tools/scripts/llm-key-hunter/results/_cache/content/aryehbenami-ui_guia-kyc-interativo.json
T

1 line
83 KiB
JSON

{"repo": "aryehbenami-ui/guia-kyc-interativo", "files": {"netlify/functions/ai-assistant.js": {"873e3f4b711a74175f73f9893a6f94cf11abdde0": {"t": 1785745555.5601335, "n": 13844, "h": "889765871d6cbe51", "c": "/**\n * Netlify Function - AI Assistant para Guia KYC\n * \n * INTEGRAÇÃO COM DEEPSEEK API + BASE DE CONHECIMENTO TÉCNICO\n * \n * Funcionalidades:\n * 1. Responde baseado no guia KYC (prioritário)\n * 2. Usa conhecimento técnico KYC quando o guia não é suficiente\n * 3. Salva respostas úteis em JSON para base futura\n */\n\n// Configuração\nconst ENABLE_DEEPSEEK = true;\nconst DEEPSEEK_API_URL = 'https://api.deepseek.com/v1/chat/completions';\nconst SAVE_LEARNING = true; // Salvar respostas para base de conhecimento\n\n// Base de conhecimento técnico KYC (além do guia)\nconst KYC_TECHNICAL_KNOWLEDGE = `\nCONHECIMENTO TÉCNICO KYC - INFORMAÇÕES COMPLEMENTARES:\n\n1. REGULAMENTAÇÃO E COMPLIANCE:\n - KYC é exigido pelo Banco Central e COAF no Brasil\n - Lei 9.613/1998 (Lei de Lavagem de Dinheiro)\n - Circular BCB 3.978/2020 (Dispõe sobre a política de relacionamento com clientes)\n - Resolução COAF nº 39/2022 (Obrigações de KYC para instituições financeiras)\n\n2. NÍVEIS DE KYC:\n - KYC Simplificado: Para operações de baixo valor/risco\n - KYC Padrão: Para maioria das operações financeiras\n - KYC Reforçado (EDD - Enhanced Due Diligence): Para PEPs, alto valor, jurisdições de risco\n\n3. DOCUMENTOS VÁLIDOS NO BRASIL:\n - RG (Carteira de Identidade) - todos os estados\n - CNH (Carteira Nacional de Habilitação) - modelo atual\n - RNE (Registro Nacional de Estrangeiro)\n - Passaporte brasileiro (página da foto)\n - Carteira de Trabalho Digital (modelo atual)\n\n4. VALIDAÇÃO DE DOCUMENTOS:\n - Verificar autenticidade através de bases governamentais quando possível\n - Checar consistência dos dados (nome, data nascimento, filiação)\n - Validar se documento não está vencido (exceto RG que não vence)\n - Atenção para sinais de adulteração: fontes diferentes, cores inconsistentes\n\n5. BIOMETRIA FACIAL:\n - Threshold mínimo recomendado: 0.75 (75% similaridade)\n - Fatores que reduzem similaridade: idade da foto, ângulo, iluminação, acessórios\n - Liveness detection previne ataques com fotos/vídeos\n - Importante: fotos muito antigas (>5 anos) podem exigir validação adicional\n\n6. PROBLEMAS COMUNS E SOLUÇÕES:\n - Câmera não abre: 90% dos casos é permissão negada no navegador\n - OCR falha: geralmente por reflexo, baixa iluminação ou documento fora do enquadramento\n - Face match baixo: orientar boa iluminação frontal, remover acessórios\n - Loading infinito: limpar cache do navegador resolve 70% dos casos\n - Erro de conexão: verificar VPN/proxy bloqueando requisições\n\n7. PEP (Pessoa Politicamente Exposta):\n - Definição: pessoas que exercem ou exerceram funções públicas importantes\n - Inclui: políticos, juízes, diretores de estatais, militares de alto escalão\n - Familiares até 2º grau e pessoas próximas também são considerados PEP\n - Exige EDD (Due Diligence Reforçada)\n\n8. SANÇÕES E LISTAS RESTRITIVAS:\n - Listas consultadas: OFAC, UN, EU, CEIS, CNJ\n - Verificação deve ser feita antes de estabelecer relacionamento\n - Match parcial exige análise manual (homônimos são comuns)\n\n9. LIMITES OPERACIONAIS (exemplos comuns):\n - Pix sem KYC completo: até R$ 200/dia (varia por instituição)\n - Transferências TED: exigem KYC completo independentemente do valor\n - Saques: limites variam conforme nível de KYC\n\n10. BOAS PRÁTICAS DE ATENDIMENTO:\n - Sempre validar identidade antes de fornecer informações sensíveis\n - Documentar todas as interações no sistema\n - Em caso de suspeita de fraude, escalar imediatamente\n - Manter sigilo absoluto sobre dados do cliente\n`;\n\n/**\n * Handler principal da função\n */\nexports.handler = async (event, context) => {\n // Headers CORS\n const headers = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Headers': 'Content-Type',\n 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',\n 'Content-Type': 'application/json'\n };\n\n // Handle preflight requests\n if (event.httpMethod === 'OPTIONS') {\n return { statusCode: 200, headers, body: '' };\n }\n\n // GET para health check, POST para chat\n if (event.httpMethod !== 'POST' && event.httpMethod !== 'GET') {\n return {\n statusCode: 405,\n headers,\n body: JSON.stringify({ error: 'Method Not Allowed' })\n };\n }\n\n try {\n // Health check via GET\n if (event.httpMethod === 'GET') {\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify({\n status: 'ok',\n enabled: ENABLE_DEEPSEEK,\n hasApiKey: !!process.env.DEEPSEEK_API_KEY,\n saveLearning: SAVE_LEARNING,\n timestamp: new Date().toISOString()\n })\n };\n }\n\n // Parse do body\n const { query, systemPrompt, context: articlesContext } = JSON.parse(event.body);\n\n if (!query) {\n return {\n statusCode: 400,\n headers,\n body: JSON.stringify({ error: 'Query is required' })\n };\n }\n\n // Se DeepSeek não estiver habilitado, retorna erro amigável\n if (!ENABLE_DEEPSEEK) {\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify({\n response: `⚠️ **Integração com IA ainda não configurada**\n\nA integração com a DeepSeek API estará disponível em breve.\n\nEnquanto isso, utilize o modo offline do assistente que já está funcionando no frontend.`,\n mode: 'offline',\n enabled: false\n })\n };\n }\n\n // Verificar se API key está configurada\n const apiKey = process.env.DEEPSEEK_API_KEY;\n if (!apiKey) {\n return {\n statusCode: 500,\n headers,\n body: JSON.stringify({\n error: 'DeepSeek API key not configured',\n message: 'Configure a variável de ambiente DEEPSEEK_API_KEY no Netlify'\n })\n };\n }\n\n // Construir contexto com artigos do guia (se disponíveis)\n let guideContext = '';\n if (articlesContext && articlesContext.length > 0) {\n guideContext = articlesContext.map(article => {\n return `ARTIGO DO GUIA: ${article.title}\\n${JSON.stringify(article.content, null, 2)}`;\n }).join('\\n\\n');\n }\n\n // System prompt híbrido: guia + conhecimento técnico\n const hybridSystemPrompt = systemPrompt || buildHybridSystemPrompt(guideContext);\n\n // Construir messages\n const messages = [\n {\n role: 'system',\n content: hybridSystemPrompt\n },\n {\n role: 'user',\n content: query\n }\n ];\n\n // Chamada à API DeepSeek\n const response = await fetch(DEEPSEEK_API_URL, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n model: 'deepseek-chat',\n messages: messages,\n temperature: 0.4, // Um pouco mais alto para criatividade controlada\n max_tokens: 1500, // Mais tokens para respostas completas\n top_p: 0.9,\n frequency_penalty: 0.1,\n presence_penalty: 0.1\n })\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n let errorData = {};\n try {\n errorData = JSON.parse(errorText);\n } catch (e) {\n // Response is not JSON\n }\n console.error('DeepSeek API Error:', response.status, errorData);\n \n return {\n statusCode: response.status === 401 ? 401 : 500,\n headers,\n body: JSON.stringify({\n error: 'Failed to get response from AI',\n message: response.status === 401 \n ? 'Invalid API key' \n : `API error: ${response.status}`,\n details: errorData\n })\n };\n }\n\n const data = await response.json();\n const aiResponse = data.choices?.[0]?.message?.content || 'Desculpe, não consegui processar sua solicitação.';\n\n // Salvar aprendizado (se habilitado e resposta for útil)\n if (SAVE_LEARNING && aiResponse && !aiResponse.includes('Não encontrei')) {\n await saveLearning({\n query: query,\n response: aiResponse,\n timestamp: new Date().toISOString(),\n model: 'deepseek-chat',\n usage: data.usage || null,\n context: articlesContext ? articlesContext.map(a => a.title) : []\n });\n }\n\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify({\n response: aiResponse,\n mode: 'online',\n enabled: true,\n model: 'deepseek-chat',\n usage: data.usage || null,\n usedGuide: articlesContext && articlesContext.length > 0,\n usedTechnicalKnowledge: true\n })\n };\n\n } catch (error) {\n console.error('Error in AI Assistant function:', error);\n \n return {\n statusCode: 500,\n headers,\n body: JSON.stringify({\n error: 'Internal server error',\n message: 'An error occurred while processing your request'\n })\n };\n }\n};\n\n/**\n * Constrói system prompt híbrido (guia + conhecimento técnico)\n * Foco em respostas diretas em estilo de prosa, com enriquecimento técnico quando necessário\n */\nfunction buildHybridSystemPrompt(guideContext) {\n let prompt = `Você é um assistente especializado em procedimentos KYC (Know Your Customer) com conhecimento técnico avançado.\n\nSUA FUNÇÃO PRINCIPAL:\nAjudar analistas a resolver problemas operacionais de forma prática e direta. Você deve fornecer respostas claras, em estilo de prosa (texto corrido e direto), evitando listas excessivas ou formatação muito estruturada quando não for necessário.\n\nBASE DE CONHECIMENTO DISPONÍVEL:\n1. GUIA KYC (conteúdo oficial do guia):\n${guideContext || '(nenhum artigo do guia disponível no momento)'}\n\n2. CONHECIMENTO TÉCNICO KYC (informações complementares):\n${KYC_TECHNICAL_KNOWLEDGE}\n\nDIRETRIZES DE RESPOSTA - COMO AGIR:\n\n1. **Quando o guia tiver informação suficiente:**\n - Responda de forma direta e clara, explicando o procedimento em prosa\n - Mencione o artigo do guia de forma natural na resposta (ex: \"Conforme o artigo sobre Face Match...\")\n - Foque na solução prática\n\n2. **Quando o guia NÃO for suficiente ou não abordar o problema:**\n - Enriqueça a resposta com conhecimento técnico relevante\n - Explique conceitos, regulamentações ou práticas que possam ajudar\n - Seja explícito: \"O guia não aborda especificamente este caso, mas com base no conhecimento técnico de KYC...\"\n - Use sua base técnica para oferecer alternativas e contexto adicional\n\n3. **Quando não encontrar informação em nenhuma fonte:**\n - Seja honesto e direto: \"Não encontrei informação específica sobre isso nos procedimentos KYC\"\n - Sugira caminhos alternativos (consultar supervisor, escalar para equipe técnica, etc.)\n\nESTILO DE RESPOSTA - TOM E FORMATO:\n- **Direto e claro**: Vá direto ao ponto, como em uma conversa profissional\n- **Prosa natural**: Use parágrafos bem estruturados em vez de listas excessivas\n- **Prático**: Foque no que o analista precisa fazer para resolver o problema\n- **Empático**: Reconheça a situação do analista/usuário\n- **Técnico quando necessário**: Use terminologia adequada, mas explique se for complexo\n\nEXEMPLO DE ESTRUTURA DE RESPOSTA (em prosa):\n\"Entendi o problema. [Explicação direta do que está acontecendo]. \n\n[Se o guia aborda]: O guia KYC trata disso no artigo sobre [nome do artigo]. Basicamente, você precisa [explicação em prosa dos passos]. \n\n[Se o guia não aborda]: O guia não cobre especificamente essa situação, mas posso ajudar com base no conhecimento técnico. [Explicação técnica em prosa].\n\n[Se houver necessidade de escalar]: Se após essas orientações o problema persistir, o próximo passo é [indicar escalonamento].\"\n\nREGRAS IMPORTANTES:\n- Nunca invente procedimentos, thresholds ou regras\n- Para casos de possível fraude, sempre oriente escalar para equipe especializada\n- Mantenha o foco na solução prática do problema\n- Seja transparente sobre a fonte da informação (guia vs conhecimento técnico)\n- Em caso de dúvida sobre a precisão da informação, prefira ser conservador\n\nLEMBRE-SE:\nSeu objetivo é ser útil e prático. O analista precisa de uma resposta clara e acionável, não de uma aula teórica. Use o conhecimento técnico para enriquecer a resposta quando o guia não for suficiente, mas sempre mantenha o foco na resolução do problema.`;\n\n return prompt;\n}\n\n/**\n * Salva aprendizado em arquivo JSON (simulado via console.log para produção)\n * Em produção, isso poderia salvar em:\n * - AWS S3\n * - Banco de dados\n * - Arquivo JSON no repositório\n */\nasync function saveLearning(data) {\n // Em produção, isso salvaria em um banco de dados ou arquivo\n // Por enquanto, logamos para poder ser capturado pelos logs do Netlify\n console.log('=== APRENDIZADO SALVO ===');\n console.log(JSON.stringify({\n type: 'kyc_learning',\n timestamp: data.timestamp,\n query: data.query.substring(0, 100), // Preview da pergunta\n response_preview: data.response.substring(0, 200), // Preview da resposta\n usedGuide: data.context.length > 0,\n guideArticles: data.context,\n full_data: data // Dados completos para referência\n }, null, 2));\n console.log('=== FIM APRENDIZADO ===');\n \n // TODO: Em produção, implementar salvamento real:\n // 1. AWS S3: await s3.putObject({ Bucket: 'kyc-learning', Key: `learnings/${Date.now()}.json`, Body: JSON.stringify(data) }).promise();\n // 2. Banco de dados: await db.collection('learnings').insertOne(data);\n // 3. Arquivo local: await fs.appendFileSync('learnings.json', JSON.stringify(data) + '\\n');\n \n return true;\n}\n\n/**\n * Health check endpoint (via GET no handler principal)\n */\nexports.health = async (event, context) => {\n return {\n statusCode: 200,\n headers: {\n 'Access-Control-Allow-Origin': '*',\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n status: 'ok',\n enabled: ENABLE_DEEPSEEK,\n hasApiKey: !!process.env.DEEPSEEK_API_KEY,\n saveLearning: SAVE_LEARNING,\n timestamp: new Date().toISOString()\n })\n };\n};"}, "e31b4ae418f09b68e561cd7d6dcdab1dc0393ce4": {"t": 1785754172.9088726, "n": 13844, "h": "889765871d6cbe51", "c": "/**\n * Netlify Function - AI Assistant para Guia KYC\n * \n * INTEGRAÇÃO COM DEEPSEEK API + BASE DE CONHECIMENTO TÉCNICO\n * \n * Funcionalidades:\n * 1. Responde baseado no guia KYC (prioritário)\n * 2. Usa conhecimento técnico KYC quando o guia não é suficiente\n * 3. Salva respostas úteis em JSON para base futura\n */\n\n// Configuração\nconst ENABLE_DEEPSEEK = true;\nconst DEEPSEEK_API_URL = 'https://api.deepseek.com/v1/chat/completions';\nconst SAVE_LEARNING = true; // Salvar respostas para base de conhecimento\n\n// Base de conhecimento técnico KYC (além do guia)\nconst KYC_TECHNICAL_KNOWLEDGE = `\nCONHECIMENTO TÉCNICO KYC - INFORMAÇÕES COMPLEMENTARES:\n\n1. REGULAMENTAÇÃO E COMPLIANCE:\n - KYC é exigido pelo Banco Central e COAF no Brasil\n - Lei 9.613/1998 (Lei de Lavagem de Dinheiro)\n - Circular BCB 3.978/2020 (Dispõe sobre a política de relacionamento com clientes)\n - Resolução COAF nº 39/2022 (Obrigações de KYC para instituições financeiras)\n\n2. NÍVEIS DE KYC:\n - KYC Simplificado: Para operações de baixo valor/risco\n - KYC Padrão: Para maioria das operações financeiras\n - KYC Reforçado (EDD - Enhanced Due Diligence): Para PEPs, alto valor, jurisdições de risco\n\n3. DOCUMENTOS VÁLIDOS NO BRASIL:\n - RG (Carteira de Identidade) - todos os estados\n - CNH (Carteira Nacional de Habilitação) - modelo atual\n - RNE (Registro Nacional de Estrangeiro)\n - Passaporte brasileiro (página da foto)\n - Carteira de Trabalho Digital (modelo atual)\n\n4. VALIDAÇÃO DE DOCUMENTOS:\n - Verificar autenticidade através de bases governamentais quando possível\n - Checar consistência dos dados (nome, data nascimento, filiação)\n - Validar se documento não está vencido (exceto RG que não vence)\n - Atenção para sinais de adulteração: fontes diferentes, cores inconsistentes\n\n5. BIOMETRIA FACIAL:\n - Threshold mínimo recomendado: 0.75 (75% similaridade)\n - Fatores que reduzem similaridade: idade da foto, ângulo, iluminação, acessórios\n - Liveness detection previne ataques com fotos/vídeos\n - Importante: fotos muito antigas (>5 anos) podem exigir validação adicional\n\n6. PROBLEMAS COMUNS E SOLUÇÕES:\n - Câmera não abre: 90% dos casos é permissão negada no navegador\n - OCR falha: geralmente por reflexo, baixa iluminação ou documento fora do enquadramento\n - Face match baixo: orientar boa iluminação frontal, remover acessórios\n - Loading infinito: limpar cache do navegador resolve 70% dos casos\n - Erro de conexão: verificar VPN/proxy bloqueando requisições\n\n7. PEP (Pessoa Politicamente Exposta):\n - Definição: pessoas que exercem ou exerceram funções públicas importantes\n - Inclui: políticos, juízes, diretores de estatais, militares de alto escalão\n - Familiares até 2º grau e pessoas próximas também são considerados PEP\n - Exige EDD (Due Diligence Reforçada)\n\n8. SANÇÕES E LISTAS RESTRITIVAS:\n - Listas consultadas: OFAC, UN, EU, CEIS, CNJ\n - Verificação deve ser feita antes de estabelecer relacionamento\n - Match parcial exige análise manual (homônimos são comuns)\n\n9. LIMITES OPERACIONAIS (exemplos comuns):\n - Pix sem KYC completo: até R$ 200/dia (varia por instituição)\n - Transferências TED: exigem KYC completo independentemente do valor\n - Saques: limites variam conforme nível de KYC\n\n10. BOAS PRÁTICAS DE ATENDIMENTO:\n - Sempre validar identidade antes de fornecer informações sensíveis\n - Documentar todas as interações no sistema\n - Em caso de suspeita de fraude, escalar imediatamente\n - Manter sigilo absoluto sobre dados do cliente\n`;\n\n/**\n * Handler principal da função\n */\nexports.handler = async (event, context) => {\n // Headers CORS\n const headers = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Headers': 'Content-Type',\n 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',\n 'Content-Type': 'application/json'\n };\n\n // Handle preflight requests\n if (event.httpMethod === 'OPTIONS') {\n return { statusCode: 200, headers, body: '' };\n }\n\n // GET para health check, POST para chat\n if (event.httpMethod !== 'POST' && event.httpMethod !== 'GET') {\n return {\n statusCode: 405,\n headers,\n body: JSON.stringify({ error: 'Method Not Allowed' })\n };\n }\n\n try {\n // Health check via GET\n if (event.httpMethod === 'GET') {\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify({\n status: 'ok',\n enabled: ENABLE_DEEPSEEK,\n hasApiKey: !!process.env.DEEPSEEK_API_KEY,\n saveLearning: SAVE_LEARNING,\n timestamp: new Date().toISOString()\n })\n };\n }\n\n // Parse do body\n const { query, systemPrompt, context: articlesContext } = JSON.parse(event.body);\n\n if (!query) {\n return {\n statusCode: 400,\n headers,\n body: JSON.stringify({ error: 'Query is required' })\n };\n }\n\n // Se DeepSeek não estiver habilitado, retorna erro amigável\n if (!ENABLE_DEEPSEEK) {\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify({\n response: `⚠️ **Integração com IA ainda não configurada**\n\nA integração com a DeepSeek API estará disponível em breve.\n\nEnquanto isso, utilize o modo offline do assistente que já está funcionando no frontend.`,\n mode: 'offline',\n enabled: false\n })\n };\n }\n\n // Verificar se API key está configurada\n const apiKey = process.env.DEEPSEEK_API_KEY;\n if (!apiKey) {\n return {\n statusCode: 500,\n headers,\n body: JSON.stringify({\n error: 'DeepSeek API key not configured',\n message: 'Configure a variável de ambiente DEEPSEEK_API_KEY no Netlify'\n })\n };\n }\n\n // Construir contexto com artigos do guia (se disponíveis)\n let guideContext = '';\n if (articlesContext && articlesContext.length > 0) {\n guideContext = articlesContext.map(article => {\n return `ARTIGO DO GUIA: ${article.title}\\n${JSON.stringify(article.content, null, 2)}`;\n }).join('\\n\\n');\n }\n\n // System prompt híbrido: guia + conhecimento técnico\n const hybridSystemPrompt = systemPrompt || buildHybridSystemPrompt(guideContext);\n\n // Construir messages\n const messages = [\n {\n role: 'system',\n content: hybridSystemPrompt\n },\n {\n role: 'user',\n content: query\n }\n ];\n\n // Chamada à API DeepSeek\n const response = await fetch(DEEPSEEK_API_URL, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n model: 'deepseek-chat',\n messages: messages,\n temperature: 0.4, // Um pouco mais alto para criatividade controlada\n max_tokens: 1500, // Mais tokens para respostas completas\n top_p: 0.9,\n frequency_penalty: 0.1,\n presence_penalty: 0.1\n })\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n let errorData = {};\n try {\n errorData = JSON.parse(errorText);\n } catch (e) {\n // Response is not JSON\n }\n console.error('DeepSeek API Error:', response.status, errorData);\n \n return {\n statusCode: response.status === 401 ? 401 : 500,\n headers,\n body: JSON.stringify({\n error: 'Failed to get response from AI',\n message: response.status === 401 \n ? 'Invalid API key' \n : `API error: ${response.status}`,\n details: errorData\n })\n };\n }\n\n const data = await response.json();\n const aiResponse = data.choices?.[0]?.message?.content || 'Desculpe, não consegui processar sua solicitação.';\n\n // Salvar aprendizado (se habilitado e resposta for útil)\n if (SAVE_LEARNING && aiResponse && !aiResponse.includes('Não encontrei')) {\n await saveLearning({\n query: query,\n response: aiResponse,\n timestamp: new Date().toISOString(),\n model: 'deepseek-chat',\n usage: data.usage || null,\n context: articlesContext ? articlesContext.map(a => a.title) : []\n });\n }\n\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify({\n response: aiResponse,\n mode: 'online',\n enabled: true,\n model: 'deepseek-chat',\n usage: data.usage || null,\n usedGuide: articlesContext && articlesContext.length > 0,\n usedTechnicalKnowledge: true\n })\n };\n\n } catch (error) {\n console.error('Error in AI Assistant function:', error);\n \n return {\n statusCode: 500,\n headers,\n body: JSON.stringify({\n error: 'Internal server error',\n message: 'An error occurred while processing your request'\n })\n };\n }\n};\n\n/**\n * Constrói system prompt híbrido (guia + conhecimento técnico)\n * Foco em respostas diretas em estilo de prosa, com enriquecimento técnico quando necessário\n */\nfunction buildHybridSystemPrompt(guideContext) {\n let prompt = `Você é um assistente especializado em procedimentos KYC (Know Your Customer) com conhecimento técnico avançado.\n\nSUA FUNÇÃO PRINCIPAL:\nAjudar analistas a resolver problemas operacionais de forma prática e direta. Você deve fornecer respostas claras, em estilo de prosa (texto corrido e direto), evitando listas excessivas ou formatação muito estruturada quando não for necessário.\n\nBASE DE CONHECIMENTO DISPONÍVEL:\n1. GUIA KYC (conteúdo oficial do guia):\n${guideContext || '(nenhum artigo do guia disponível no momento)'}\n\n2. CONHECIMENTO TÉCNICO KYC (informações complementares):\n${KYC_TECHNICAL_KNOWLEDGE}\n\nDIRETRIZES DE RESPOSTA - COMO AGIR:\n\n1. **Quando o guia tiver informação suficiente:**\n - Responda de forma direta e clara, explicando o procedimento em prosa\n - Mencione o artigo do guia de forma natural na resposta (ex: \"Conforme o artigo sobre Face Match...\")\n - Foque na solução prática\n\n2. **Quando o guia NÃO for suficiente ou não abordar o problema:**\n - Enriqueça a resposta com conhecimento técnico relevante\n - Explique conceitos, regulamentações ou práticas que possam ajudar\n - Seja explícito: \"O guia não aborda especificamente este caso, mas com base no conhecimento técnico de KYC...\"\n - Use sua base técnica para oferecer alternativas e contexto adicional\n\n3. **Quando não encontrar informação em nenhuma fonte:**\n - Seja honesto e direto: \"Não encontrei informação específica sobre isso nos procedimentos KYC\"\n - Sugira caminhos alternativos (consultar supervisor, escalar para equipe técnica, etc.)\n\nESTILO DE RESPOSTA - TOM E FORMATO:\n- **Direto e claro**: Vá direto ao ponto, como em uma conversa profissional\n- **Prosa natural**: Use parágrafos bem estruturados em vez de listas excessivas\n- **Prático**: Foque no que o analista precisa fazer para resolver o problema\n- **Empático**: Reconheça a situação do analista/usuário\n- **Técnico quando necessário**: Use terminologia adequada, mas explique se for complexo\n\nEXEMPLO DE ESTRUTURA DE RESPOSTA (em prosa):\n\"Entendi o problema. [Explicação direta do que está acontecendo]. \n\n[Se o guia aborda]: O guia KYC trata disso no artigo sobre [nome do artigo]. Basicamente, você precisa [explicação em prosa dos passos]. \n\n[Se o guia não aborda]: O guia não cobre especificamente essa situação, mas posso ajudar com base no conhecimento técnico. [Explicação técnica em prosa].\n\n[Se houver necessidade de escalar]: Se após essas orientações o problema persistir, o próximo passo é [indicar escalonamento].\"\n\nREGRAS IMPORTANTES:\n- Nunca invente procedimentos, thresholds ou regras\n- Para casos de possível fraude, sempre oriente escalar para equipe especializada\n- Mantenha o foco na solução prática do problema\n- Seja transparente sobre a fonte da informação (guia vs conhecimento técnico)\n- Em caso de dúvida sobre a precisão da informação, prefira ser conservador\n\nLEMBRE-SE:\nSeu objetivo é ser útil e prático. O analista precisa de uma resposta clara e acionável, não de uma aula teórica. Use o conhecimento técnico para enriquecer a resposta quando o guia não for suficiente, mas sempre mantenha o foco na resolução do problema.`;\n\n return prompt;\n}\n\n/**\n * Salva aprendizado em arquivo JSON (simulado via console.log para produção)\n * Em produção, isso poderia salvar em:\n * - AWS S3\n * - Banco de dados\n * - Arquivo JSON no repositório\n */\nasync function saveLearning(data) {\n // Em produção, isso salvaria em um banco de dados ou arquivo\n // Por enquanto, logamos para poder ser capturado pelos logs do Netlify\n console.log('=== APRENDIZADO SALVO ===');\n console.log(JSON.stringify({\n type: 'kyc_learning',\n timestamp: data.timestamp,\n query: data.query.substring(0, 100), // Preview da pergunta\n response_preview: data.response.substring(0, 200), // Preview da resposta\n usedGuide: data.context.length > 0,\n guideArticles: data.context,\n full_data: data // Dados completos para referência\n }, null, 2));\n console.log('=== FIM APRENDIZADO ===');\n \n // TODO: Em produção, implementar salvamento real:\n // 1. AWS S3: await s3.putObject({ Bucket: 'kyc-learning', Key: `learnings/${Date.now()}.json`, Body: JSON.stringify(data) }).promise();\n // 2. Banco de dados: await db.collection('learnings').insertOne(data);\n // 3. Arquivo local: await fs.appendFileSync('learnings.json', JSON.stringify(data) + '\\n');\n \n return true;\n}\n\n/**\n * Health check endpoint (via GET no handler principal)\n */\nexports.health = async (event, context) => {\n return {\n statusCode: 200,\n headers: {\n 'Access-Control-Allow-Origin': '*',\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n status: 'ok',\n enabled: ENABLE_DEEPSEEK,\n hasApiKey: !!process.env.DEEPSEEK_API_KEY,\n saveLearning: SAVE_LEARNING,\n timestamp: new Date().toISOString()\n })\n };\n};"}, "47e8fbb00b085bb243a12cce7c2005ef59efeae0": {"t": 1785754174.3780127, "n": 12252, "h": "6a8ea609d5bd4b60", "c": "/**\n * Netlify Function - AI Assistant para Guia KYC\n * \n * INTEGRAÇÃO COM DEEPSEEK API + BASE DE CONHECIMENTO TÉCNICO\n * \n * Funcionalidades:\n * 1. Responde baseado no guia KYC (prioritário)\n * 2. Usa conhecimento técnico KYC quando o guia não é suficiente\n * 3. Salva respostas úteis em JSON para base futura\n */\n\n// Configuração\nconst ENABLE_DEEPSEEK = true;\nconst DEEPSEEK_API_URL = 'https://api.deepseek.com/v1/chat/completions';\nconst SAVE_LEARNING = true; // Salvar respostas para base de conhecimento\n\n// Base de conhecimento técnico KYC (além do guia)\nconst KYC_TECHNICAL_KNOWLEDGE = `\nCONHECIMENTO TÉCNICO KYC - INFORMAÇÕES COMPLEMENTARES:\n\n1. REGULAMENTAÇÃO E COMPLIANCE:\n - KYC é exigido pelo Banco Central e COAF no Brasil\n - Lei 9.613/1998 (Lei de Lavagem de Dinheiro)\n - Circular BCB 3.978/2020 (Dispõe sobre a política de relacionamento com clientes)\n - Resolução COAF nº 39/2022 (Obrigações de KYC para instituições financeiras)\n\n2. NÍVEIS DE KYC:\n - KYC Simplificado: Para operações de baixo valor/risco\n - KYC Padrão: Para maioria das operações financeiras\n - KYC Reforçado (EDD - Enhanced Due Diligence): Para PEPs, alto valor, jurisdições de risco\n\n3. DOCUMENTOS VÁLIDOS NO BRASIL:\n - RG (Carteira de Identidade) - todos os estados\n - CNH (Carteira Nacional de Habilitação) - modelo atual\n - RNE (Registro Nacional de Estrangeiro)\n - Passaporte brasileiro (página da foto)\n - Carteira de Trabalho Digital (modelo atual)\n\n4. VALIDAÇÃO DE DOCUMENTOS:\n - Verificar autenticidade através de bases governamentais quando possível\n - Checar consistência dos dados (nome, data nascimento, filiação)\n - Validar se documento não está vencido (exceto RG que não vence)\n - Atenção para sinais de adulteração: fontes diferentes, cores inconsistentes\n\n5. BIOMETRIA FACIAL:\n - Threshold mínimo recomendado: 0.75 (75% similaridade)\n - Fatores que reduzem similaridade: idade da foto, ângulo, iluminação, acessórios\n - Liveness detection previne ataques com fotos/vídeos\n - Importante: fotos muito antigas (>5 anos) podem exigir validação adicional\n\n6. PROBLEMAS COMUNS E SOLUÇÕES:\n - Câmera não abre: 90% dos casos é permissão negada no navegador\n - OCR falha: geralmente por reflexo, baixa iluminação ou documento fora do enquadramento\n - Face match baixo: orientar boa iluminação frontal, remover acessórios\n - Loading infinito: limpar cache do navegador resolve 70% dos casos\n - Erro de conexão: verificar VPN/proxy bloqueando requisições\n\n7. PEP (Pessoa Politicamente Exposta):\n - Definição: pessoas que exercem ou exerceram funções públicas importantes\n - Inclui: políticos, juízes, diretores de estatais, militares de alto escalão\n - Familiares até 2º grau e pessoas próximas também são considerados PEP\n - Exige EDD (Due Diligence Reforçada)\n\n8. SANÇÕES E LISTAS RESTRITIVAS:\n - Listas consultadas: OFAC, UN, EU, CEIS, CNJ\n - Verificação deve ser feita antes de estabelecer relacionamento\n - Match parcial exige análise manual (homônimos são comuns)\n\n9. LIMITES OPERACIONAIS (exemplos comuns):\n - Pix sem KYC completo: até R$ 200/dia (varia por instituição)\n - Transferências TED: exigem KYC completo independentemente do valor\n - Saques: limites variam conforme nível de KYC\n\n10. BOAS PRÁTICAS DE ATENDIMENTO:\n - Sempre validar identidade antes de fornecer informações sensíveis\n - Documentar todas as interações no sistema\n - Em caso de suspeita de fraude, escalar imediatamente\n - Manter sigilo absoluto sobre dados do cliente\n`;\n\n/**\n * Handler principal da função\n */\nexports.handler = async (event, context) => {\n // Headers CORS\n const headers = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Headers': 'Content-Type',\n 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',\n 'Content-Type': 'application/json'\n };\n\n // Handle preflight requests\n if (event.httpMethod === 'OPTIONS') {\n return { statusCode: 200, headers, body: '' };\n }\n\n // GET para health check, POST para chat\n if (event.httpMethod !== 'POST' && event.httpMethod !== 'GET') {\n return {\n statusCode: 405,\n headers,\n body: JSON.stringify({ error: 'Method Not Allowed' })\n };\n }\n\n try {\n // Health check via GET\n if (event.httpMethod === 'GET') {\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify({\n status: 'ok',\n enabled: ENABLE_DEEPSEEK,\n hasApiKey: !!process.env.DEEPSEEK_API_KEY,\n saveLearning: SAVE_LEARNING,\n timestamp: new Date().toISOString()\n })\n };\n }\n\n // Parse do body\n const { query, systemPrompt, context: articlesContext } = JSON.parse(event.body);\n\n if (!query) {\n return {\n statusCode: 400,\n headers,\n body: JSON.stringify({ error: 'Query is required' })\n };\n }\n\n // Se DeepSeek não estiver habilitado, retorna erro amigável\n if (!ENABLE_DEEPSEEK) {\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify({\n response: `⚠️ **Integração com IA ainda não configurada**\n\nA integração com a DeepSeek API estará disponível em breve.\n\nEnquanto isso, utilize o modo offline do assistente que já está funcionando no frontend.`,\n mode: 'offline',\n enabled: false\n })\n };\n }\n\n // Verificar se API key está configurada\n const apiKey = process.env.DEEPSEEK_API_KEY;\n if (!apiKey) {\n return {\n statusCode: 500,\n headers,\n body: JSON.stringify({\n error: 'DeepSeek API key not configured',\n message: 'Configure a variável de ambiente DEEPSEEK_API_KEY no Netlify'\n })\n };\n }\n\n // Construir contexto com artigos do guia (se disponíveis)\n let guideContext = '';\n if (articlesContext && articlesContext.length > 0) {\n guideContext = articlesContext.map(article => {\n return `ARTIGO DO GUIA: ${article.title}\\n${JSON.stringify(article.content, null, 2)}`;\n }).join('\\n\\n');\n }\n\n // System prompt híbrido: guia + conhecimento técnico\n const hybridSystemPrompt = systemPrompt || buildHybridSystemPrompt(guideContext);\n\n // Construir messages\n const messages = [\n {\n role: 'system',\n content: hybridSystemPrompt\n },\n {\n role: 'user',\n content: query\n }\n ];\n\n // Chamada à API DeepSeek\n const response = await fetch(DEEPSEEK_API_URL, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n model: 'deepseek-chat',\n messages: messages,\n temperature: 0.4, // Um pouco mais alto para criatividade controlada\n max_tokens: 1500, // Mais tokens para respostas completas\n top_p: 0.9,\n frequency_penalty: 0.1,\n presence_penalty: 0.1\n })\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n let errorData = {};\n try {\n errorData = JSON.parse(errorText);\n } catch (e) {\n // Response is not JSON\n }\n console.error('DeepSeek API Error:', response.status, errorData);\n \n return {\n statusCode: response.status === 401 ? 401 : 500,\n headers,\n body: JSON.stringify({\n error: 'Failed to get response from AI',\n message: response.status === 401 \n ? 'Invalid API key' \n : `API error: ${response.status}`,\n details: errorData\n })\n };\n }\n\n const data = await response.json();\n const aiResponse = data.choices?.[0]?.message?.content || 'Desculpe, não consegui processar sua solicitação.';\n\n // Salvar aprendizado (se habilitado e resposta for útil)\n if (SAVE_LEARNING && aiResponse && !aiResponse.includes('Não encontrei')) {\n await saveLearning({\n query: query,\n response: aiResponse,\n timestamp: new Date().toISOString(),\n model: 'deepseek-chat',\n usage: data.usage || null,\n context: articlesContext ? articlesContext.map(a => a.title) : []\n });\n }\n\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify({\n response: aiResponse,\n mode: 'online',\n enabled: true,\n model: 'deepseek-chat',\n usage: data.usage || null,\n usedGuide: articlesContext && articlesContext.length > 0,\n usedTechnicalKnowledge: true\n })\n };\n\n } catch (error) {\n console.error('Error in AI Assistant function:', error);\n \n return {\n statusCode: 500,\n headers,\n body: JSON.stringify({\n error: 'Internal server error',\n message: 'An error occurred while processing your request'\n })\n };\n }\n};\n\n/**\n * Constrói system prompt híbrido (guia + conhecimento técnico)\n */\nfunction buildHybridSystemPrompt(guideContext) {\n let prompt = `Você é um assistente especializado em procedimentos KYC (Know Your Customer) com conhecimento técnico avançado.\n\nSUA FUNÇÃO:\n- Ajudar analistas a resolver problemas operacionais durante atendimentos\n- Fornecer informações técnicas sobre KYC quando o guia não for suficiente\n- Explicar regulamentações, melhores práticas e soluções para casos complexos\n\nBASE DE CONHECIMENTO:\n1. GUIA KYC (prioritário quando disponível):\n${guideContext || '(nenhum artigo do guia disponível)'}\n\n2. CONHECIMENTO TÉCNICO KYC:\n${KYC_TECHNICAL_KNOWLEDGE}\n\nREGRAS IMPORTANTES:\n1. PRIORIZE o guia KYC quando ele tiver informação relevante sobre o problema\n2. Se o guia NÃO tiver informação suficiente, use o conhecimento técnico para complementar\n3. Sempre indique claramente se está usando o guia ou conhecimento técnico\n4. Se não encontrar informação em nenhuma fonte, diga claramente \"Não encontrei informação específica\"\n5. Mantenha respostas objetivas e operacionais\n6. Não invente procedimentos, thresholds ou regras\n7. Para casos de possível fraude, sempre oriente a escalar para equipe especializada\n\nFORMATO DE RESPOSTA:\n- Comece identificando se o problema está coberto pelo guia\n- Se estiver: cite o artigo e siga os procedimentos do guia\n- Se não estiver: use conhecimento técnico e indique \"Baseado em conhecimento técnico KYC\"\n- Liste passos de troubleshooting de forma clara e numerada\n- Indique quando escalar para equipe técnica ou fornecedor\n- Inclua referências a regulamentações quando relevante\n\nTOM DE VOZ:\n- Profissional e direto\n- Empático com o analista\n- Focado em solução prática\n- Técnico quando necessário, mas acessível`;\n\n return prompt;\n}\n\n/**\n * Salva aprendizado em arquivo JSON (simulado via console.log para produção)\n * Em produção, isso poderia salvar em:\n * - AWS S3\n * - Banco de dados\n * - Arquivo JSON no repositório\n */\nasync function saveLearning(data) {\n // Em produção, isso salvaria em um banco de dados ou arquivo\n // Por enquanto, logamos para poder ser capturado pelos logs do Netlify\n console.log('=== APRENDIZADO SALVO ===');\n console.log(JSON.stringify({\n type: 'kyc_learning',\n timestamp: data.timestamp,\n query: data.query.substring(0, 100), // Preview da pergunta\n response_preview: data.response.substring(0, 200), // Preview da resposta\n usedGuide: data.context.length > 0,\n guideArticles: data.context,\n full_data: data // Dados completos para referência\n }, null, 2));\n console.log('=== FIM APRENDIZADO ===');\n \n // TODO: Em produção, implementar salvamento real:\n // 1. AWS S3: await s3.putObject({ Bucket: 'kyc-learning', Key: `learnings/${Date.now()}.json`, Body: JSON.stringify(data) }).promise();\n // 2. Banco de dados: await db.collection('learnings').insertOne(data);\n // 3. Arquivo local: await fs.appendFileSync('learnings.json', JSON.stringify(data) + '\\n');\n \n return true;\n}\n\n/**\n * Health check endpoint (via GET no handler principal)\n */\nexports.health = async (event, context) => {\n return {\n statusCode: 200,\n headers: {\n 'Access-Control-Allow-Origin': '*',\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n status: 'ok',\n enabled: ENABLE_DEEPSEEK,\n hasApiKey: !!process.env.DEEPSEEK_API_KEY,\n saveLearning: SAVE_LEARNING,\n timestamp: new Date().toISOString()\n })\n };\n};"}, "10ceb46a8f3641d1db71023c59785f97ac995727": {"t": 1785754175.6535761, "n": 6123, "h": "9b3c9c57cca36733", "c": "\n\n// Configuração - Mudar para true após configurar API key\nconst ENABLE_DEEPSEEK = true;\n\n// URL da API DeepSeek\nconst DEEPSEEK_API_URL = 'https://api.deepseek.com/v1/chat/completions';\n\n/**\n * Handler principal da função\n */\nexports.handler = async (event, context) => {\n // Headers CORS\n const headers = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Headers': 'Content-Type',\n 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',\n 'Content-Type': 'application/json'\n };\n\n // Handle preflight requests\n if (event.httpMethod === 'OPTIONS') {\n return { statusCode: 200, headers, body: '' };\n }\n\n // GET para health check, POST para chat\n if (event.httpMethod !== 'POST' && event.httpMethod !== 'GET') {\n return {\n statusCode: 405,\n headers,\n body: JSON.stringify({ error: 'Method Not Allowed' })\n };\n }\n\n try {\n // Health check via GET\n if (event.httpMethod === 'GET') {\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify({\n status: 'ok',\n enabled: ENABLE_DEEPSEEK,\n hasApiKey: !!process.env.DEEPSEEK_API_KEY,\n timestamp: new Date().toISOString()\n })\n };\n }\n\n // Parse do body\n const { query, systemPrompt, context: articlesContext } = JSON.parse(event.body);\n\n if (!query) {\n return {\n statusCode: 400,\n headers,\n body: JSON.stringify({ error: 'Query is required' })\n };\n }\n\n // Se DeepSeek não estiver habilitado, retorna erro amigável\n if (!ENABLE_DEEPSEEK) {\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify({\n response: `⚠️ **Integração com IA ainda não configurada**\n\nA integração com a DeepSeek API estará disponível em breve.\n\nEnquanto isso, utilize o modo offline do assistente que já está funcionando no frontend.\n\n**Para ativar a integração:**\n1. Configure a API key no Netlify\n2. Atualize a configuração para habilitar a API`,\n mode: 'offline',\n enabled: false\n })\n };\n }\n\n // Verificar se API key está configurada\n const apiKey = process.env.DEEPSEEK_API_KEY;\n if (!apiKey) {\n return {\n statusCode: 500,\n headers,\n body: JSON.stringify({\n error: 'DeepSeek API key not configured',\n message: 'Configure a variável de ambiente DEEPSEEK_API_KEY no Netlify',\n debug: {\n hasEnvVar: !!process.env.DEEPSEEK_API_KEY,\n envVarLength: process.env.DEEPSEEK_API_KEY ? process.env.DEEPSEEK_API_KEY.length : 0\n }\n })\n };\n }\n \n // Debug: log da API key (apenas os últimos 5 caracteres)\n console.log('API Key configurada:', apiKey ? `***${apiKey.slice(-5)}` : 'não configurada');\n console.log('API Key length:', apiKey ? apiKey.length : 0);\n\n // Construir prompt com contexto KYC\n const messages = [\n {\n role: 'system',\n content: systemPrompt || buildDefaultSystemPrompt()\n },\n {\n role: 'user',\n content: query\n }\n ];\n\n // Chamada à API DeepSeek\n const response = await fetch(DEEPSEEK_API_URL, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n model: 'deepseek-chat',\n messages: messages,\n temperature: 0.3, // Baixa temperatura para consistência\n max_tokens: 1024, // Limite de tokens\n top_p: 0.9,\n frequency_penalty: 0.1, // Reduz repetição\n presence_penalty: 0.1\n })\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n let errorData = {};\n try {\n errorData = JSON.parse(errorText);\n } catch (e) {\n // Response is not JSON\n }\n console.error('DeepSeek API Error:', response.status, errorData);\n console.error('DeepSeek API Error Raw:', errorText);\n \n return {\n statusCode: response.status === 401 ? 401 : 500,\n headers,\n body: JSON.stringify({\n error: 'Failed to get response from AI',\n message: response.status === 401 \n ? 'Invalid API key' \n : `API error: ${response.status}`,\n details: errorData,\n rawError: errorText.substring(0, 500)\n })\n };\n }\n\n const data = await response.json();\n const aiResponse = data.choices?.[0]?.message?.content || 'Desculpe, não consegui processar sua solicitação.';\n\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify({\n response: aiResponse,\n mode: 'online',\n enabled: true,\n model: 'deepseek-chat',\n usage: data.usage || null\n })\n };\n\n } catch (error) {\n console.error('Error in AI Assistant function:', error);\n \n return {\n statusCode: 500,\n headers,\n body: JSON.stringify({\n error: 'Internal server error',\n message: 'An error occurred while processing your request'\n })\n };\n }\n};\n\n/**\n * Constrói o system prompt padrão\n */\nfunction buildDefaultSystemPrompt() {\n return `Você é um assistente especializado em procedimentos KYC (Know Your Customer).\nSua função é ajudar analistas a resolver problemas operacionais durante atendimentos.\n\nREGRAS IMPORTANTES:\n1. Baseie suas respostas APENAS nos artigos e procedimentos fornecidos no contexto\n2. Se não encontrar informação nos documentos, diga claramente \"Não encontrei informação específica nos procedimentos KYC\"\n3. Cite sempre a seção/artigo de referência\n4. Mantenha respostas objetivas e operacionais\n5. Não invente procedimentos, thresholds ou regras\n6. Não forneça informações sobre casos específicos de usuários\n7. Mantenha foco em troubleshooting operacional\n\nFORMATO DE RESPOSTA:\n- Identifique o problema principal\n- Liste passos de troubleshooting de forma clara e numerada\n- Indique quando escalar para equipe técnica ou fornecedor\n- Cite artigos relacionados quando relevante\n\nTOM DE VOZ:\n- Profissional e direto\n- Empático com o analista\n- Focado em solução prática`;\n}\n\n"}, "3e22134e75d5732d337493685873eaa7995421d1": {"t": 1785754176.8252685, "n": 5862, "h": "c01b0ef8b337acc5", "c": "\n\n// Configuração - Mudar para true após configurar API key\nconst ENABLE_DEEPSEEK = true;\n\n// URL da API DeepSeek\nconst DEEPSEEK_API_URL = 'https://api.deepseek.com/v1/chat/completions';\n\n/**\n * Handler principal da função\n */\nexports.handler = async (event, context) => {\n // Headers CORS\n const headers = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Headers': 'Content-Type',\n 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',\n 'Content-Type': 'application/json'\n };\n\n // Handle preflight requests\n if (event.httpMethod === 'OPTIONS') {\n return { statusCode: 200, headers, body: '' };\n }\n\n // GET para health check, POST para chat\n if (event.httpMethod !== 'POST' && event.httpMethod !== 'GET') {\n return {\n statusCode: 405,\n headers,\n body: JSON.stringify({ error: 'Method Not Allowed' })\n };\n }\n\n try {\n // Health check via GET\n if (event.httpMethod === 'GET') {\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify({\n status: 'ok',\n enabled: ENABLE_DEEPSEEK,\n hasApiKey: !!process.env.DEEPSEEK_API_KEY,\n timestamp: new Date().toISOString()\n })\n };\n }\n\n // Parse do body\n const { query, systemPrompt, context: articlesContext } = JSON.parse(event.body);\n\n if (!query) {\n return {\n statusCode: 400,\n headers,\n body: JSON.stringify({ error: 'Query is required' })\n };\n }\n\n // Se DeepSeek não estiver habilitado, retorna erro amigável\n if (!ENABLE_DEEPSEEK) {\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify({\n response: `⚠️ **Integração com IA ainda não configurada**\n\nA integração com a DeepSeek API estará disponível em breve.\n\nEnquanto isso, utilize o modo offline do assistente que já está funcionando no frontend.\n\n**Para ativar a integração:**\n1. Configure a API key no Netlify\n2. Atualize a configuração para habilitar a API`,\n mode: 'offline',\n enabled: false\n })\n };\n }\n\n // Verificar se API key está configurada\n const apiKey = process.env.DEEPSEEK_API_KEY;\n if (!apiKey) {\n return {\n statusCode: 500,\n headers,\n body: JSON.stringify({\n error: 'DeepSeek API key not configured',\n message: 'Configure a variável de ambiente DEEPSEEK_API_KEY no Netlify',\n debug: {\n hasEnvVar: !!process.env.DEEPSEEK_API_KEY,\n envVarLength: process.env.DEEPSEEK_API_KEY ? process.env.DEEPSEEK_API_KEY.length : 0\n }\n })\n };\n }\n \n // Debug: log da API key (apenas os últimos 5 caracteres)\n console.log('API Key configurada:', apiKey ? `***${apiKey.slice(-5)}` : 'não configurada');\n console.log('API Key length:', apiKey ? apiKey.length : 0);\n\n // Construir prompt com contexto KYC\n const messages = [\n {\n role: 'system',\n content: systemPrompt || buildDefaultSystemPrompt()\n },\n {\n role: 'user',\n content: query\n }\n ];\n\n // Chamada à API DeepSeek\n const response = await fetch(DEEPSEEK_API_URL, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n model: 'deepseek-chat',\n messages: messages,\n temperature: 0.3, // Baixa temperatura para consistência\n max_tokens: 1024, // Limite de tokens\n top_p: 0.9,\n frequency_penalty: 0.1, // Reduz repetição\n presence_penalty: 0.1\n })\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n console.error('DeepSeek API Error:', response.status, errorData);\n \n return {\n statusCode: response.status === 401 ? 401 : 500,\n headers,\n body: JSON.stringify({\n error: 'Failed to get response from AI',\n message: response.status === 401 \n ? 'Invalid API key' \n : `API error: ${response.status}`\n })\n };\n }\n\n const data = await response.json();\n const aiResponse = data.choices?.[0]?.message?.content || 'Desculpe, não consegui processar sua solicitação.';\n\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify({\n response: aiResponse,\n mode: 'online',\n enabled: true,\n model: 'deepseek-chat',\n usage: data.usage || null\n })\n };\n\n } catch (error) {\n console.error('Error in AI Assistant function:', error);\n \n return {\n statusCode: 500,\n headers,\n body: JSON.stringify({\n error: 'Internal server error',\n message: 'An error occurred while processing your request'\n })\n };\n }\n};\n\n/**\n * Constrói o system prompt padrão\n */\nfunction buildDefaultSystemPrompt() {\n return `Você é um assistente especializado em procedimentos KYC (Know Your Customer).\nSua função é ajudar analistas a resolver problemas operacionais durante atendimentos.\n\nREGRAS IMPORTANTES:\n1. Baseie suas respostas APENAS nos artigos e procedimentos fornecidos no contexto\n2. Se não encontrar informação nos documentos, diga claramente \"Não encontrei informação específica nos procedimentos KYC\"\n3. Cite sempre a seção/artigo de referência\n4. Mantenha respostas objetivas e operacionais\n5. Não invente procedimentos, thresholds ou regras\n6. Não forneça informações sobre casos específicos de usuários\n7. Mantenha foco em troubleshooting operacional\n\nFORMATO DE RESPOSTA:\n- Identifique o problema principal\n- Liste passos de troubleshooting de forma clara e numerada\n- Indique quando escalar para equipe técnica ou fornecedor\n- Cite artigos relacionados quando relevante\n\nTOM DE VOZ:\n- Profissional e direto\n- Empático com o analista\n- Focado em solução prática`;\n}\n\n"}, "5b549d295e3b94ce96bf1e188060db266c8028cf": {"t": 1785754178.1765819, "n": 5451, "h": "20557b8c71b4b5a0", "c": "\n\n// Configuração - Mudar para true após configurar API key\nconst ENABLE_DEEPSEEK = true;\n\n// URL da API DeepSeek\nconst DEEPSEEK_API_URL = 'https://api.deepseek.com/v1/chat/completions';\n\n/**\n * Handler principal da função\n */\nexports.handler = async (event, context) => {\n // Headers CORS\n const headers = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Headers': 'Content-Type',\n 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',\n 'Content-Type': 'application/json'\n };\n\n // Handle preflight requests\n if (event.httpMethod === 'OPTIONS') {\n return { statusCode: 200, headers, body: '' };\n }\n\n // GET para health check, POST para chat\n if (event.httpMethod !== 'POST' && event.httpMethod !== 'GET') {\n return {\n statusCode: 405,\n headers,\n body: JSON.stringify({ error: 'Method Not Allowed' })\n };\n }\n\n try {\n // Health check via GET\n if (event.httpMethod === 'GET') {\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify({\n status: 'ok',\n enabled: ENABLE_DEEPSEEK,\n hasApiKey: !!process.env.DEEPSEEK_API_KEY,\n timestamp: new Date().toISOString()\n })\n };\n }\n\n // Parse do body\n const { query, systemPrompt, context: articlesContext } = JSON.parse(event.body);\n\n if (!query) {\n return {\n statusCode: 400,\n headers,\n body: JSON.stringify({ error: 'Query is required' })\n };\n }\n\n // Se DeepSeek não estiver habilitado, retorna erro amigável\n if (!ENABLE_DEEPSEEK) {\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify({\n response: `⚠️ **Integração com IA ainda não configurada**\n\nA integração com a DeepSeek API estará disponível em breve.\n\nEnquanto isso, utilize o modo offline do assistente que já está funcionando no frontend.\n\n**Para ativar a integração:**\n1. Configure a API key no Netlify\n2. Atualize a configuração para habilitar a API`,\n mode: 'offline',\n enabled: false\n })\n };\n }\n\n // Verificar se API key está configurada\n const apiKey = process.env.DEEPSEEK_API_KEY;\n if (!apiKey) {\n return {\n statusCode: 500,\n headers,\n body: JSON.stringify({\n error: 'DeepSeek API key not configured',\n message: 'Configure a variável de ambiente DEEPSEEK_API_KEY no Netlify'\n })\n };\n }\n\n // Construir prompt com contexto KYC\n const messages = [\n {\n role: 'system',\n content: systemPrompt || buildDefaultSystemPrompt()\n },\n {\n role: 'user',\n content: query\n }\n ];\n\n // Chamada à API DeepSeek\n const response = await fetch(DEEPSEEK_API_URL, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n model: 'deepseek-chat',\n messages: messages,\n temperature: 0.3, // Baixa temperatura para consistência\n max_tokens: 1024, // Limite de tokens\n top_p: 0.9,\n frequency_penalty: 0.1, // Reduz repetição\n presence_penalty: 0.1\n })\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n console.error('DeepSeek API Error:', response.status, errorData);\n \n return {\n statusCode: response.status === 401 ? 401 : 500,\n headers,\n body: JSON.stringify({\n error: 'Failed to get response from AI',\n message: response.status === 401 \n ? 'Invalid API key' \n : `API error: ${response.status}`\n })\n };\n }\n\n const data = await response.json();\n const aiResponse = data.choices?.[0]?.message?.content || 'Desculpe, não consegui processar sua solicitação.';\n\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify({\n response: aiResponse,\n mode: 'online',\n enabled: true,\n model: 'deepseek-chat',\n usage: data.usage || null\n })\n };\n\n } catch (error) {\n console.error('Error in AI Assistant function:', error);\n \n return {\n statusCode: 500,\n headers,\n body: JSON.stringify({\n error: 'Internal server error',\n message: 'An error occurred while processing your request'\n })\n };\n }\n};\n\n/**\n * Constrói o system prompt padrão\n */\nfunction buildDefaultSystemPrompt() {\n return `Você é um assistente especializado em procedimentos KYC (Know Your Customer).\nSua função é ajudar analistas a resolver problemas operacionais durante atendimentos.\n\nREGRAS IMPORTANTES:\n1. Baseie suas respostas APENAS nos artigos e procedimentos fornecidos no contexto\n2. Se não encontrar informação nos documentos, diga claramente \"Não encontrei informação específica nos procedimentos KYC\"\n3. Cite sempre a seção/artigo de referência\n4. Mantenha respostas objetivas e operacionais\n5. Não invente procedimentos, thresholds ou regras\n6. Não forneça informações sobre casos específicos de usuários\n7. Mantenha foco em troubleshooting operacional\n\nFORMATO DE RESPOSTA:\n- Identifique o problema principal\n- Liste passos de troubleshooting de forma clara e numerada\n- Indique quando escalar para equipe técnica ou fornecedor\n- Cite artigos relacionados quando relevante\n\nTOM DE VOZ:\n- Profissional e direto\n- Empático com o analista\n- Focado em solução prática`;\n}\n\n"}, "71fae2ad00c1760f83bba9cbaa59bb37ca44981e": {"t": 1785754179.4448857, "n": 5462, "h": "390fec5fba8f636d", "c": "\n\n// Configuração - Mudar para true após configurar API key\nconst ENABLE_DEEPSEEK = true;\n\n// URL da API DeepSeek\nconst DEEPSEEK_API_URL = 'https://api.deepseek.com/v1/chat/completions';\n\n/**\n * Handler principal da função\n */\nexports.handler = async (event, context) => {\n // Headers CORS\n const headers = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Headers': 'Content-Type',\n 'Access-Control-Allow-Methods': 'POST, OPTIONS',\n 'Content-Type': 'application/json'\n };\n\n // Handle preflight requests\n if (event.httpMethod === 'OPTIONS') {\n return { statusCode: 200, headers, body: '' };\n }\n\n // Apenas POST é permitido\n if (event.httpMethod !== 'POST') {\n return {\n statusCode: 405,\n headers,\n body: JSON.stringify({ error: 'Method Not Allowed' })\n };\n }\n\n try {\n // Parse do body\n const { query, systemPrompt, context: articlesContext } = JSON.parse(event.body);\n\n if (!query) {\n return {\n statusCode: 400,\n headers,\n body: JSON.stringify({ error: 'Query is required' })\n };\n }\n\n // Se DeepSeek não estiver habilitado, retorna erro amigável\n if (!ENABLE_DEEPSEEK) {\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify({\n response: `⚠️ **Integração com IA ainda não configurada**\n\nA integração com a DeepSeek API estará disponível em breve.\n\nEnquanto isso, utilize o modo offline do assistente que já está funcionando no frontend.\n\n**Para ativar a integração:**\n1. Configure a API key no Netlify\n2. Atualize a configuração para habilitar a API`,\n mode: 'offline',\n enabled: false\n })\n };\n }\n\n // Verificar se API key está configurada\n const apiKey = process.env.DEEPSEEK_API_KEY;\n if (!apiKey) {\n return {\n statusCode: 500,\n headers,\n body: JSON.stringify({\n error: 'DeepSeek API key not configured',\n message: 'Configure a variável de ambiente DEEPSEEK_API_KEY no Netlify'\n })\n };\n }\n\n // Construir prompt com contexto KYC\n const messages = [\n {\n role: 'system',\n content: systemPrompt || buildDefaultSystemPrompt()\n },\n {\n role: 'user',\n content: query\n }\n ];\n\n // Chamada à API DeepSeek\n const response = await fetch(DEEPSEEK_API_URL, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n model: 'deepseek-chat',\n messages: messages,\n temperature: 0.3, // Baixa temperatura para consistência\n max_tokens: 1024, // Limite de tokens\n top_p: 0.9,\n frequency_penalty: 0.1, // Reduz repetição\n presence_penalty: 0.1\n })\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n console.error('DeepSeek API Error:', response.status, errorData);\n \n return {\n statusCode: response.status === 401 ? 401 : 500,\n headers,\n body: JSON.stringify({\n error: 'Failed to get response from AI',\n message: response.status === 401 \n ? 'Invalid API key' \n : `API error: ${response.status}`\n })\n };\n }\n\n const data = await response.json();\n const aiResponse = data.choices?.[0]?.message?.content || 'Desculpe, não consegui processar sua solicitação.';\n\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify({\n response: aiResponse,\n mode: 'online',\n enabled: true,\n model: 'deepseek-chat',\n usage: data.usage || null\n })\n };\n\n } catch (error) {\n console.error('Error in AI Assistant function:', error);\n \n return {\n statusCode: 500,\n headers,\n body: JSON.stringify({\n error: 'Internal server error',\n message: 'An error occurred while processing your request'\n })\n };\n }\n};\n\n/**\n * Constrói o system prompt padrão\n */\nfunction buildDefaultSystemPrompt() {\n return `Você é um assistente especializado em procedimentos KYC (Know Your Customer).\nSua função é ajudar analistas a resolver problemas operacionais durante atendimentos.\n\nREGRAS IMPORTANTES:\n1. Baseie suas respostas APENAS nos artigos e procedimentos fornecidos no contexto\n2. Se não encontrar informação nos documentos, diga claramente \"Não encontrei informação específica nos procedimentos KYC\"\n3. Cite sempre a seção/artigo de referência\n4. Mantenha respostas objetivas e operacionais\n5. Não invente procedimentos, thresholds ou regras\n6. Não forneça informações sobre casos específicos de usuários\n7. Mantenha foco em troubleshooting operacional\n\nFORMATO DE RESPOSTA:\n- Identifique o problema principal\n- Liste passos de troubleshooting de forma clara e numerada\n- Indique quando escalar para equipe técnica ou fornecedor\n- Cite artigos relacionados quando relevante\n\nTOM DE VOZ:\n- Profissional e direto\n- Empático com o analista\n- Focado em solução prática`;\n}\n\n/**\n * Health check endpoint\n */\nexports.health = async (event, context) => {\n return {\n statusCode: 200,\n headers: {\n 'Access-Control-Allow-Origin': '*',\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n status: 'ok',\n enabled: ENABLE_DEEPSEEK,\n hasApiKey: !!process.env.DEEPSEEK_API_KEY,\n timestamp: new Date().toISOString()\n })\n };\n};\n"}, "0745a802883747a3c77eb5c968ff2527d02f1105": {"t": 1785754180.740319, "n": 5987, "h": "a1f954f5f64574af", "c": "/**\n * Netlify Function - AI Assistant para Guia KYC\n * \n * ESTA FUNÇÃO ESTÁ PRONTA PARA INTEGRAÇÃO COM DEEPSEEK API\n * \n * Passos para ativar:\n * 1. Criar conta na DeepSeek: https://platform.deepseek.com/\n * 2. Obter API Key\n * 3. Adicionar variável de ambiente no Netlify: DEEPSEEK_API_KEY\n * 4. Mudar ENABLE_DEEPSEEK para true abaixo\n * \n * Para configurar a variável de ambiente no Netlify:\n * - Acesse Netlify Dashboard > Site > Configuration > Environment variables\n * - Adicione: DEEPSEEK_API_KEY = \"sua-chave-aqui\"\n */\n\n// Configuração - Mudar para true após configurar API key\nconst ENABLE_DEEPSEEK = true;\n\n// URL da API DeepSeek\nconst DEEPSEEK_API_URL = 'https://api.deepseek.com/v1/chat/completions';\n\n/**\n * Handler principal da função\n */\nexports.handler = async (event, context) => {\n // Headers CORS\n const headers = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Headers': 'Content-Type',\n 'Access-Control-Allow-Methods': 'POST, OPTIONS',\n 'Content-Type': 'application/json'\n };\n\n // Handle preflight requests\n if (event.httpMethod === 'OPTIONS') {\n return { statusCode: 200, headers, body: '' };\n }\n\n // Apenas POST é permitido\n if (event.httpMethod !== 'POST') {\n return {\n statusCode: 405,\n headers,\n body: JSON.stringify({ error: 'Method Not Allowed' })\n };\n }\n\n try {\n // Parse do body\n const { query, systemPrompt, context: articlesContext } = JSON.parse(event.body);\n\n if (!query) {\n return {\n statusCode: 400,\n headers,\n body: JSON.stringify({ error: 'Query is required' })\n };\n }\n\n // Se DeepSeek não estiver habilitado, retorna erro amigável\n if (!ENABLE_DEEPSEEK) {\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify({\n response: `⚠️ **Integração com IA ainda não configurada**\n\nA integração com a DeepSeek API estará disponível em breve.\n\nEnquanto isso, utilize o modo offline do assistente que já está funcionando no frontend.\n\n**Para ativar a integração:**\n1. Configure a API key no Netlify\n2. Atualize a configuração para habilitar a API`,\n mode: 'offline',\n enabled: false\n })\n };\n }\n\n // Verificar se API key está configurada\n const apiKey = process.env.DEEPSEEK_API_KEY;\n if (!apiKey) {\n return {\n statusCode: 500,\n headers,\n body: JSON.stringify({\n error: 'DeepSeek API key not configured',\n message: 'Configure a variável de ambiente DEEPSEEK_API_KEY no Netlify'\n })\n };\n }\n\n // Construir prompt com contexto KYC\n const messages = [\n {\n role: 'system',\n content: systemPrompt || buildDefaultSystemPrompt()\n },\n {\n role: 'user',\n content: query\n }\n ];\n\n // Chamada à API DeepSeek\n const response = await fetch(DEEPSEEK_API_URL, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n model: 'deepseek-chat',\n messages: messages,\n temperature: 0.3, // Baixa temperatura para consistência\n max_tokens: 1024, // Limite de tokens\n top_p: 0.9,\n frequency_penalty: 0.1, // Reduz repetição\n presence_penalty: 0.1\n })\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n console.error('DeepSeek API Error:', response.status, errorData);\n \n return {\n statusCode: response.status === 401 ? 401 : 500,\n headers,\n body: JSON.stringify({\n error: 'Failed to get response from AI',\n message: response.status === 401 \n ? 'Invalid API key' \n : `API error: ${response.status}`\n })\n };\n }\n\n const data = await response.json();\n const aiResponse = data.choices?.[0]?.message?.content || 'Desculpe, não consegui processar sua solicitação.';\n\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify({\n response: aiResponse,\n mode: 'online',\n enabled: true,\n model: 'deepseek-chat',\n usage: data.usage || null\n })\n };\n\n } catch (error) {\n console.error('Error in AI Assistant function:', error);\n \n return {\n statusCode: 500,\n headers,\n body: JSON.stringify({\n error: 'Internal server error',\n message: 'An error occurred while processing your request'\n })\n };\n }\n};\n\n/**\n * Constrói o system prompt padrão\n */\nfunction buildDefaultSystemPrompt() {\n return `Você é um assistente especializado em procedimentos KYC (Know Your Customer).\nSua função é ajudar analistas a resolver problemas operacionais durante atendimentos.\n\nREGRAS IMPORTANTES:\n1. Baseie suas respostas APENAS nos artigos e procedimentos fornecidos no contexto\n2. Se não encontrar informação nos documentos, diga claramente \"Não encontrei informação específica nos procedimentos KYC\"\n3. Cite sempre a seção/artigo de referência\n4. Mantenha respostas objetivas e operacionais\n5. Não invente procedimentos, thresholds ou regras\n6. Não forneça informações sobre casos específicos de usuários\n7. Mantenha foco em troubleshooting operacional\n\nFORMATO DE RESPOSTA:\n- Identifique o problema principal\n- Liste passos de troubleshooting de forma clara e numerada\n- Indique quando escalar para equipe técnica ou fornecedor\n- Cite artigos relacionados quando relevante\n\nTOM DE VOZ:\n- Profissional e direto\n- Empático com o analista\n- Focado em solução prática`;\n}\n\n/**\n * Health check endpoint\n */\nexports.health = async (event, context) => {\n return {\n statusCode: 200,\n headers: {\n 'Access-Control-Allow-Origin': '*',\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n status: 'ok',\n enabled: ENABLE_DEEPSEEK,\n hasApiKey: !!process.env.DEEPSEEK_API_KEY,\n timestamp: new Date().toISOString()\n })\n };\n};"}, "2f3d1e97ca98d9791f55425acb78a7dd5ad0d7e2": {"t": 1785754182.181579, "n": 5460, "h": "1ee8d942144efee2", "c": "\n\n// Configuração - Mudar para true após configurar API key\nconst ENABLE_DEEPSEEK = true;\n\n// URL da API DeepSeek\nconst DEEPSEEK_API_URL = 'https://api.deepseek.com/v1/chat/completions';\n\n/**\n * Handler principal da função\n */\nexports.handler = async (event, context) => {\n // Headers CORS\n const headers = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Headers': 'Content-Type',\n 'Access-Control-Allow-Methods': 'POST, OPTIONS',\n 'Content-Type': 'application/json'\n };\n\n // Handle preflight requests\n if (event.httpMethod === 'OPTIONS') {\n return { statusCode: 200, headers, body: '' };\n }\n\n // Apenas POST é permitido\n if (event.httpMethod !== 'POST') {\n return {\n statusCode: 405,\n headers,\n body: JSON.stringify({ error: 'Method Not Allowed' })\n };\n }\n\n try {\n // Parse do body\n const { query, systemPrompt, context: articlesContext } = JSON.parse(event.body);\n\n if (!query) {\n return {\n statusCode: 400,\n headers,\n body: JSON.stringify({ error: 'Query is required' })\n };\n }\n\n // Se DeepSeek não estiver habilitado, retorna erro amigável\n if (!ENABLE_DEEPSEEK) {\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify({\n response: `⚠️ **Integração com IA ainda não configurada**\n\nA integração com a DeepSeek API estará disponível em breve.\n\nEnquanto isso, utilize o modo offline do assistente que já está funcionando no frontend.\n\n**Para ativar a integração:**\n1. Configure a API key no Netlify\n2. Atualize a configuração para habilitar a API`,\n mode: 'offline',\n enabled: false\n })\n };\n }\n\n // Verificar se API key está configurada\n const apiKey = process.env.DEESEEK_API_KEY;\n if (!apiKey) {\n return {\n statusCode: 500,\n headers,\n body: JSON.stringify({\n error: 'DeepSeek API key not configured',\n message: 'Configure a variável de ambiente DEEPSEEK_API_KEY no Netlify'\n })\n };\n }\n\n // Construir prompt com contexto KYC\n const messages = [\n {\n role: 'system',\n content: systemPrompt || buildDefaultSystemPrompt()\n },\n {\n role: 'user',\n content: query\n }\n ];\n\n // Chamada à API DeepSeek\n const response = await fetch(DEEPSEEK_API_URL, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n model: 'deepseek-chat',\n messages: messages,\n temperature: 0.3, // Baixa temperatura para consistência\n max_tokens: 1024, // Limite de tokens\n top_p: 0.9,\n frequency_penalty: 0.1, // Reduz repetição\n presence_penalty: 0.1\n })\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n console.error('DeepSeek API Error:', response.status, errorData);\n \n return {\n statusCode: response.status === 401 ? 401 : 500,\n headers,\n body: JSON.stringify({\n error: 'Failed to get response from AI',\n message: response.status === 401 \n ? 'Invalid API key' \n : `API error: ${response.status}`\n })\n };\n }\n\n const data = await response.json();\n const aiResponse = data.choices?.[0]?.message?.content || 'Desculpe, não consegui processar sua solicitação.';\n\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify({\n response: aiResponse,\n mode: 'online',\n enabled: true,\n model: 'deepseek-chat',\n usage: data.usage || null\n })\n };\n\n } catch (error) {\n console.error('Error in AI Assistant function:', error);\n \n return {\n statusCode: 500,\n headers,\n body: JSON.stringify({\n error: 'Internal server error',\n message: 'An error occurred while processing your request'\n })\n };\n }\n};\n\n/**\n * Constrói o system prompt padrão\n */\nfunction buildDefaultSystemPrompt() {\n return `Você é um assistente especializado em procedimentos KYC (Know Your Customer).\nSua função é ajudar analistas a resolver problemas operacionais durante atendimentos.\n\nREGRAS IMPORTANTES:\n1. Baseie suas respostas APENAS nos artigos e procedimentos fornecidos no contexto\n2. Se não encontrar informação nos documentos, diga claramente \"Não encontrei informação específica nos procedimentos KYC\"\n3. Cite sempre a seção/artigo de referência\n4. Mantenha respostas objetivas e operacionais\n5. Não invente procedimentos, thresholds ou regras\n6. Não forneça informações sobre casos específicos de usuários\n7. Mantenha foco em troubleshooting operacional\n\nFORMATO DE RESPOSTA:\n- Identifique o problema principal\n- Liste passos de troubleshooting de forma clara e numerada\n- Indique quando escalar para equipe técnica ou fornecedor\n- Cite artigos relacionados quando relevante\n\nTOM DE VOZ:\n- Profissional e direto\n- Empático com o analista\n- Focado em solução prática`;\n}\n\n/**\n * Health check endpoint\n */\nexports.health = async (event, context) => {\n return {\n statusCode: 200,\n headers: {\n 'Access-Control-Allow-Origin': '*',\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n status: 'ok',\n enabled: ENABLE_DEEPSEEK,\n hasApiKey: !!process.env.DEESEEK_API_KEY,\n timestamp: new Date().toISOString()\n })\n };\n};\n"}, "7ee01c6c1eea4e5eda9d2ba5840879f8f137c249": {"t": 1785754184.1833556, "n": 5985, "h": "e960894dcf5aaa44", "c": "/**\n * Netlify Function - AI Assistant para Guia KYC\n * \n * ESTA FUNÇÃO ESTÁ PRONTA PARA INTEGRAÇÃO COM DEEPSEEK API\n * \n * Passos para ativar:\n * 1. Criar conta na DeepSeek: https://platform.deepseek.com/\n * 2. Obter API Key\n * 3. Adicionar variável de ambiente no Netlify: DEEPSEEK_API_KEY\n * 4. Mudar ENABLE_DEEPSEEK para true abaixo\n * \n * Para configurar a variável de ambiente no Netlify:\n * - Acesse Netlify Dashboard > Site > Configuration > Environment variables\n * - Adicione: DEEPSEEK_API_KEY = \"sua-chave-aqui\"\n */\n\n// Configuração - Mudar para true após configurar API key\nconst ENABLE_DEEPSEEK = true;\n\n// URL da API DeepSeek\nconst DEEPSEEK_API_URL = 'https://api.deepseek.com/v1/chat/completions';\n\n/**\n * Handler principal da função\n */\nexports.handler = async (event, context) => {\n // Headers CORS\n const headers = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Headers': 'Content-Type',\n 'Access-Control-Allow-Methods': 'POST, OPTIONS',\n 'Content-Type': 'application/json'\n };\n\n // Handle preflight requests\n if (event.httpMethod === 'OPTIONS') {\n return { statusCode: 200, headers, body: '' };\n }\n\n // Apenas POST é permitido\n if (event.httpMethod !== 'POST') {\n return {\n statusCode: 405,\n headers,\n body: JSON.stringify({ error: 'Method Not Allowed' })\n };\n }\n\n try {\n // Parse do body\n const { query, systemPrompt, context: articlesContext } = JSON.parse(event.body);\n\n if (!query) {\n return {\n statusCode: 400,\n headers,\n body: JSON.stringify({ error: 'Query is required' })\n };\n }\n\n // Se DeepSeek não estiver habilitado, retorna erro amigável\n if (!ENABLE_DEEPSEEK) {\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify({\n response: `⚠️ **Integração com IA ainda não configurada**\n\nA integração com a DeepSeek API estará disponível em breve.\n\nEnquanto isso, utilize o modo offline do assistente que já está funcionando no frontend.\n\n**Para ativar a integração:**\n1. Configure a API key no Netlify\n2. Atualize a configuração para habilitar a API`,\n mode: 'offline',\n enabled: false\n })\n };\n }\n\n // Verificar se API key está configurada\n const apiKey = process.env.DEESEEK_API_KEY;\n if (!apiKey) {\n return {\n statusCode: 500,\n headers,\n body: JSON.stringify({\n error: 'DeepSeek API key not configured',\n message: 'Configure a variável de ambiente DEEPSEEK_API_KEY no Netlify'\n })\n };\n }\n\n // Construir prompt com contexto KYC\n const messages = [\n {\n role: 'system',\n content: systemPrompt || buildDefaultSystemPrompt()\n },\n {\n role: 'user',\n content: query\n }\n ];\n\n // Chamada à API DeepSeek\n const response = await fetch(DEEPSEEK_API_URL, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n model: 'deepseek-chat',\n messages: messages,\n temperature: 0.3, // Baixa temperatura para consistência\n max_tokens: 1024, // Limite de tokens\n top_p: 0.9,\n frequency_penalty: 0.1, // Reduz repetição\n presence_penalty: 0.1\n })\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n console.error('DeepSeek API Error:', response.status, errorData);\n \n return {\n statusCode: response.status === 401 ? 401 : 500,\n headers,\n body: JSON.stringify({\n error: 'Failed to get response from AI',\n message: response.status === 401 \n ? 'Invalid API key' \n : `API error: ${response.status}`\n })\n };\n }\n\n const data = await response.json();\n const aiResponse = data.choices?.[0]?.message?.content || 'Desculpe, não consegui processar sua solicitação.';\n\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify({\n response: aiResponse,\n mode: 'online',\n enabled: true,\n model: 'deepseek-chat',\n usage: data.usage || null\n })\n };\n\n } catch (error) {\n console.error('Error in AI Assistant function:', error);\n \n return {\n statusCode: 500,\n headers,\n body: JSON.stringify({\n error: 'Internal server error',\n message: 'An error occurred while processing your request'\n })\n };\n }\n};\n\n/**\n * Constrói o system prompt padrão\n */\nfunction buildDefaultSystemPrompt() {\n return `Você é um assistente especializado em procedimentos KYC (Know Your Customer).\nSua função é ajudar analistas a resolver problemas operacionais durante atendimentos.\n\nREGRAS IMPORTANTES:\n1. Baseie suas respostas APENAS nos artigos e procedimentos fornecidos no contexto\n2. Se não encontrar informação nos documentos, diga claramente \"Não encontrei informação específica nos procedimentos KYC\"\n3. Cite sempre a seção/artigo de referência\n4. Mantenha respostas objetivas e operacionais\n5. Não invente procedimentos, thresholds ou regras\n6. Não forneça informações sobre casos específicos de usuários\n7. Mantenha foco em troubleshooting operacional\n\nFORMATO DE RESPOSTA:\n- Identifique o problema principal\n- Liste passos de troubleshooting de forma clara e numerada\n- Indique quando escalar para equipe técnica ou fornecedor\n- Cite artigos relacionados quando relevante\n\nTOM DE VOZ:\n- Profissional e direto\n- Empático com o analista\n- Focado em solução prática`;\n}\n\n/**\n * Health check endpoint\n */\nexports.health = async (event, context) => {\n return {\n statusCode: 200,\n headers: {\n 'Access-Control-Allow-Origin': '*',\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n status: 'ok',\n enabled: ENABLE_DEEPSEEK,\n hasApiKey: !!process.env.DEESEEK_API_KEY,\n timestamp: new Date().toISOString()\n })\n };\n};"}}}}