Brasil
Posts

Dia 3: De Simulação Fake para IA Real - Como Construí um Sistema Completo de Análise! 🤖💰

June 5, 2025
E aí, pessoal! 👋 Depois de um Dia 1 criando o esqueleto da extensão e um Dia 2 corrigindo vulnerabilidades de segurança, chegou a hora da verdade: transformar aquela simulação fake de análise em IA de verdade! 🤖 E cara... foi uma montanha-russa! Saí de uma extensão que "fingia" analisar PDFs para um sistema full-stack completo com backend Python, IA real, sistema de créditos e processamento robusto de documentos. Vem comigo nessa jornada! 🚀 Lembram daquela análise fake do Dia 1? Aqueles setTimeout() simulando processamento e resultados "mockados"? Pois é... chegou a hora de aposentar e colocar IA de verdade para trabalhar! Mas rapidamente percebi que isso não seria só "trocar uma API fake por uma real". Precisava de:
  • 🔧 Backend robusto para processar PDFs pesados
  • 🧠 Integração com IA (OpenAI/LangChain)
  • 💳 Sistema de créditos (afinal, IA custa dinheiro!)
  • 🔐 Segurança em múltiplas camadas
  • 📊 Banco de dados para histórico
Foi aí que pensei: "Peraí... isso vai ser bem mais complexo que imaginei!" 😅 Frontend: Chrome Extension (que vocês já conhecem) Backend: Python FastAPI (o coração da operação) Database: Supabase PostgreSQL (com RLS para segurança) IA: OpenAI + LangChain (o cérebro que analisa) Auth: JWT + Google OAuth (do Dia 2)
# Estrutura do backend que emergiu:
📁 startlar-api/
├── 🚀 main.py (servidor FastAPI)
├── 📊 routers/
│   ├── documents.py (upload/análise)
│   ├── credits.py (sistema de créditos)
│   └── auth.py (autenticação)
├── 🧠 services/
│   ├── ai_service.py (OpenAI + LangChain)
│   ├── pdf_service.py (processamento PDFs)
│   └── supabase_service.py (database)
└── 🔐 middleware/
  └── auth_middleware.py (segurança JWT)
Antes (Dia 1): Usuário clica → Simulação fake → Resultados inventados Agora (Dia 3):
  1. Usuário clica → Validação de créditos
  2. Upload seguro do PDF → Backend FastAPI
  3. Extração de texto → PyPDF2/PDFplumber
  4. Processamento IA → OpenAI GPT-4
  5. Análise estruturada → Salva no Supabase
  6. Resultados reais → Exibe na extensão
O desafio mais interessante foi ensinar a IA a "entender" editais de leilão. Depois de muita iteração, cheguei neste prompt estruturado:
# O prompt que faz a mágica acontecer:
SYSTEM_PROMPT = """
Você é um especialista em análise de editais de leilão da Caixa Econômica Federal.
Analise o documento e identifique:

1. RISCOS JURÍDICOS: Ações judiciais, penhoras, restrições
2. RISCOS FINANCEIROS: Débitos, impostos, condomínio em atraso  
3. RISCOS FÍSICOS: Estado do imóvel, ocupação irregular
4. OPORTUNIDADES: Localização, potencial de valorização
5. ALERTAS CRÍTICOS: Informações que podem inviabilizar o negócio

Responda em JSON estruturado com score de 0-10 para cada categoria.
"""

# Exemplo de resposta estruturada que a IA retorna:
{
"score_geral": 7.5,
"riscos_juridicos": {
  "score": 8,
  "detalhes": ["Sem ações judiciais pendentes", "Matrícula limpa"]
},
"riscos_financicos": {
  "score": 6,
  "detalhes": ["IPTU em dia", "Condomínio com 3 meses de atraso"]
},
"oportunidades": {
  "score": 9,
  "detalhes": ["Localização valorizada", "Potencial para locação"]
}
}
Um dos aprendizados foi que PDFs da Caixa são... digamos... "criativos" na formatação! Implementei um pipeline com fallbacks:
async def extract_pdf_text(pdf_file):
  """Pipeline robusto para PDFs malformados"""
  text = None
  
  # Método 1: PyPDF2 (mais rápido)
  try:
      text = extract_with_pypdf2(pdf_file)
      if len(text) > 100:  # Validação básica
          return text
  except Exception as e:
      log_warning(f"PyPDF2 falhou: {e}")
  
  # Método 2: PDFplumber (mais preciso)
  try:
      text = extract_with_pdfplumber(pdf_file)
      if len(text) > 100:
          return text
  except Exception as e:
      log_warning(f"PDFplumber falhou: {e}")
  
  # Método 3: OCR (último recurso)
  try:
      text = extract_with_ocr(pdf_file)
      return text
  except Exception as e:
      raise Exception("Falha em todos os métodos de extração")
IA custa dinheiro (principalmente GPT-4), então precisava de um modelo sustentável. A solução foi um sistema de créditos justo:
  • 🆓 3 créditos gratuitos para testar
  • 💰 1 crédito = 1 análise completa
  • 🛡️ Falha = crédito não consumido (UX primeiro!)
async def process_analysis_with_credits(user_id: str, document_id: str):
  """Controle rigoroso de créditos"""
  
  # 1. Validar créditos ANTES de processar
  if not await user_has_credits(user_id):
      raise HTTPException(status_code=402, detail="Créditos insuficientes")
  
  # 2. Criar registro de análise
  analysis_id = await create_analysis_record(user_id, document_id)
  
  try:
      # 3. Consumir crédito APENAS quando começar processamento
      await consume_credit(user_id, analysis_id)
      
      # 4. Processar com IA (aqui pode falhar)
      results = await ai_service.analyze_document(document_id)
      
      # 5. Salvar resultados
      await save_analysis_results(analysis_id, results)
      
  except Exception as e:
      # 6. Se falhar, RESTITUIR o crédito!
      await restore_credit(user_id, analysis_id)
      raise
  
  return results
Depois das vulnerabilidades do Dia 2, implementei segurança em todas as camadas: Frontend: Validação antes de enviar Backend: JWT obrigatório em TODOS os endpoints Database: RLS (Row Level Security) ativo IA: Sanitização de dados antes do processamento
# Exemplo de endpoint 100% seguro:
@router.post("/upload", dependencies=[Depends(get_current_user)])
async def upload_document(
  file: UploadFile,
  current_user: dict = Depends(get_current_user)
):
  # Validações de segurança
  validate_file_type(file)      # Apenas PDFs
  validate_file_size(file)      # Máximo 10MB
  validate_user_credits(current_user['id'])  # Tem créditos?
  
  # Upload com propriedade controlada
  document_id = await save_with_owner(file, current_user['id'])
  
  # Processamento automático e seguro
  await queue_analysis(document_id, current_user['id'])
  
  return {"document_id": document_id, "status": "uploaded"}
Um usuário jamais consegue acessar documentos ou análises de outro usuário:
async def validate_document_ownership(document_id: str, user_id: str):
  """Garante isolamento total entre usuários"""
  
  document = await supabase.table("documents")\
      .select("user_id")\
      .eq("id", document_id)\
      .single()
  
  if not document:
      log_security_event("document_not_found", user_id, {"doc": document_id})
      raise HTTPException(status_code=404, detail="Document not found")
  
  if document['user_id'] != user_id:
      log_security_event("unauthorized_access", user_id, {
          "attempted_doc": document_id,
          "real_owner": document['user_id']
      })
      raise HTTPException(status_code=403, detail="Access denied")
  
  return document
  • Upload: ~2 segundos para PDFs até 5MB
  • Extração de texto: 3-8 segundos (dependendo do PDF)
  • Análise IA: 15-45 segundos (GPT-4 é preciso, mas não rápido)
  • Storage: ~500KB por análise no Supabase
O maior desafio UX foi o tempo de processamento. Implementei polling progressivo com feedback visual:
async function pollAnalysisStatus(analysisId) {
  const maxAttempts = 60; // 5 minutos timeout
  
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
      const status = await checkAnalysisStatus(analysisId);
      
      // Análise concluída!
      if (status.completed) {
          return status.results;
      }
      
      // Feedback visual progressivo
      const messages = [
          "🔍 Extraindo texto do PDF...",
          "🧠 Enviando para análise de IA...", 
          "⚡ Processando com GPT-4...",
          "📊 Estruturando resultados...",
          "✅ Finalizando análise..."
      ];
      
      const message = messages[Math.floor(attempt / 12)] || 
                     `⏳ Analisando... (${attempt}/60)`;
      updateProgressUI(message);
      
      // Intervalo progressivo: 2s → 5s → 10s
      const delay = Math.min(2000 + (attempt * 100), 10000);
      await sleep(delay);
  }
  
  throw new Error("Timeout na análise");
}
Testei com um edital real da Caixa e os resultados foram impressionantes: Resumo da Análise:
  • Data: 05/06/2025, 19:15:09
  • Tipo: EDITAL
  • Tempo de processamento: 46 segundos
  • Perguntas respondidas: 5/6
  • Confiança média: 80%
  • Resultados de alta confiança: 5
  • Resultados de baixa confiança: 1
Principais Achados Identificados pela IA: 🏠 Responsabilidade por Dívidas Condominiais (100% - Página 19)
"Com base no conteúdo do edital, as dívidas condominiais são de responsabilidade exclusiva do adquirente."
💰 Responsabilidade por IPTU e Tributos (100% - Página 10)
"Com base no documento fornecido, a responsabilidade pelas dívidas de IPTU, tributos (como o ITR) é do arrematante..."
⚡ Dívidas de Consumo - Água, Luz, Gás (80%)
"O edital não menciona explicitamente dívidas de consumo como água, energia elétrica ou gás. Não há indicação..."
A IA consegue extrair informações críticas com referências exatas às páginas e níveis de confiança para cada resposta, permitindo que o investidor tome decisões baseadas em dados precisos e verificáveis. A interface da extensão também evoluiu muito:
  • 💳 Contador de créditos em tempo real
  • 📊 Progress bar durante análise
  • 🎯 Checklist visual com scores coloridos
  • 📱 Design responsivo que se adapta ao widget
  • Estados visuais claros (loading, success, error)
Alguns editais têm formatação... criativa. A solução foi esse pipeline robusto com 3 fallbacks que mencionei. Content scripts não têm acesso direto aos tokens JWT. Solução: sistema de mensagens entre componentes da extensão. Levou várias iterações para a IA "entender" editais. O prompt final tem 847 caracteres e foi testado com 50+ editais reais. GPT-4 é preciso mas caro. GPT-3.5 é rápido mas menos preciso. Solução: uso GPT-4 para análise crítica e GPT-3.5 para sumarização.
  1. FastAPI: Documentação automática salvou horas de integração
  2. Supabase: Auth + Database + RLS em minutos, não dias
  3. Sistema de créditos: Modelo sustentável desde o início
  4. Segurança first: Implementar desde o começo é mais fácil
  1. Depuração de extensões: DevTools limitado para service workers
  2. Variabilidade de PDFs: Cada edital é um mundo diferente
  3. Custos de IA: GPT-4 é caro, precisa otimizar chamadas
  4. Testes de integração: Simular fluxo completo com dados reais
  1. TDD desde o início: Testes salvam tempo a longo prazo
  2. Logs estruturados: JSON logs desde o primeiro commit
  3. Monitoring: Métricas de performance desde o deploy
  4. Cache inteligente: Redis para otimizar chamadas repetidas
O Startlar agora está completo:
  • IA real analisando editais de verdade
  • Sistema de créditos funcionando e testado
  • Backend robusto com FastAPI + Supabase
  • Segurança em múltiplas camadas
  • Performance otimizada para uso real
  • Interface profissional e responsiva
  • Dashboard web para histórico de análises
  • Notificações push para novos editais
  • Analytics de uso e performance
  • Otimização de custos de IA
  • Chrome Web Store - disponibilizar publicamente
  • Modelos especializados - treinar IA específica para editais
  • API pública - permitir integrações
  • Monitoramento proativo de novos leilões
Esse Dia 3 foi o mais desafiador tecnicamente, mas também o mais gratificante! Ver a extensão evoluir de uma simulação fake para um sistema full-stack completo que realmente ajuda pessoas foi incrível. A jornada me ensinou que desenvolver produtos reais envolve muito mais que só código - é sobre arquitetura, segurança, modelo de negócio, UX e sustentabilidade. Cada decisão técnica impacta diretamente a experiência do usuário. Lição mais valiosa: A IA é poderosa, mas precisa ser cuidadosamente orquestrada. Não basta jogar texto no GPT e esperar magia - precisa de prompt engineering, validação, fallbacks e controle de custos. O Startlar agora é uma ferramenta completa que resolve um problema real de forma segura, eficiente e sustentável. Mission accomplished! 🎯
E vocês? Já desenvolveram algo que começou simples e virou um sistema complexo? Como lidam com a evolução de MVPs para produtos completos? Próximo capítulo: vamos explorar analytics, otimizações e talvez... publicação na Chrome Web Store! Stay tuned! 📈