Files
LerNota/openspec/changes/categoria/proposal.md
T

5.0 KiB

Why

Hoje o LerNotaFiscal extrai fornecedor, data e valor de cada nota fiscal, mas não classifica a despesa por categoria (ex.: Alimentação, Transporte, Saúde). Sem categoria, o usuário não consegue entender para onde o dinheiro está indo pelo Dashboard, apenas por fornecedor ou período. Precisamos categorizar automaticamente cada nota no momento da extração, com uma regra de negócio clara (AI primeiro, palavra-chave como fallback) e sem risco de gerar custo descontrolado de tokens de IA.

What Changes

  • Criar tabela categoria (id, categoria, palavra_chave) para mapear palavras-chave a categorias, usada como fallback e administrável pelo usuário. O registro id = 1 é reservado pelo sistema para a categoria "Não Encontrado" e é garantido automaticamente na inicialização do schema; o usuário é responsável por cadastrar as demais categorias/palavras-chave pela tela de CRUD.
  • Adicionar coluna categoria_id (FK para categoria) em fiscal_documents para persistir a classificação. Documentos processados pelo novo fluxo sempre recebem um categoria_id válido (nunca ficam nulos); apenas documentos já existentes antes desta mudança (não reprocessados) permanecem com categoria_id nulo ("Sem categoria").
  • Implementar fluxo de categorização automática:
    1. Ao processar uma nota, pedir à IA (mesma chamada de extração ou chamada dedicada) para sugerir a categoria a partir do nome do fornecedor.
    2. Se a IA não retornar uma categoria válida/reconhecida, buscar na tabela categoria por correspondência de palavra_chave no supplier_name e usar a categoria encontrada.
    3. Se a IA não conseguir categorizar e nenhuma palavra_chave corresponder, gravar categoria_id = 1 ("Não Encontrado") sem bloquear o processamento.
  • Ajustar o Dashboard (app/templates/dashboard.html + dashboard_routes.py) para exibir gastos agrupados por categoria (gráfico/lista) e permitir filtrar os dados exibidos por categoria, na mesma linha dos filtros de fornecedor/período já existentes na tela de documentos.
  • Criar tela administrativa de CRUD (Create, Read, Update, Delete) para a tabela categoria, seguindo exatamente o mesmo layout/padrão já usado em "Documentos" (documents_list.html + document_form.html, mesmo base.html, mesmas classes CSS de app/static/styles.css, mesmo padrão de rotas GET/POST /categorias, /categorias/new, /categorias/{id}/edit, POST /categorias/{id}/delete com CSRF), para que o usuário possa cadastrar/editar/remover categorias e palavras-chave sem precisar de acesso direto ao banco.
  • Criar mecanismo de segurança contra loop infinito / consumo excessivo de tokens ao acionar a IA para categorização:
    • Limite de tentativas de chamada de IA por nota (ex.: no máximo 1 tentativa de categorização por nota, sem retry automático).
    • Cache/memória de categorização por fornecedor (se já categorizamos "Fornecedor X" antes, não chamar a IA de novo — reusar resultado ou usar a tabela categoria).
    • Circuit breaker/limite global (ex.: máximo de N chamadas de categorização por lote de importação ou por janela de tempo), com log e interrupção segura (fallback para palavra-chave) ao atingir o limite.

Capabilities

New Capabilities

  • expense-categorization: Classificação automática de notas fiscais por categoria, com IA como fonte primária e a tabela categoria (palavra-chave) como fallback determinístico.
  • categorization-safety-limits: Limites e proteções (retries, cache, circuit breaker) para chamadas de IA usadas na categorização, evitando loops e consumo excessivo de tokens.

Modified Capabilities

  • (nenhuma capability existente com spec.md hoje — projeto ainda não possui specs em openspec/specs/)

Impact

  • Banco de dados (app/database.py): nova tabela categoria; nova coluna categoria_id em fiscal_documents (e possivelmente detected_documents); nova migração aditiva no SCHEMA/executescript.
  • IA (app/ai_extraction.py ou novo módulo app/categorization.py): nova função/chamada para sugerir categoria a partir do supplier_name; ajuste no fluxo de extract_with_ai ou chamada adicional pós-extração.
  • Ingestão (ingestion.py): aplicar a lógica de categorização (IA → palavra-chave → categoria_id = 1 "Não Encontrado") ao confirmar/criar fiscal_documents.
  • Rotas/Dashboard (app/routes/dashboard_routes.py, app/templates/dashboard.html): novo agrupamento e filtro por categoria.
  • Nova rota de administração (app/routes/categoria_routes.py, registrada em app/main.py; novos templates app/templates/categorias_list.html e app/templates/categoria_form.html, reaproveitando base.html): CRUD completo da tabela categoria, no mesmo padrão das rotas/telas de "Documentos".
  • Rotas de documentos (app/routes/documents_routes.py): opcionalmente permitir filtrar/editar categoria manualmente por nota.
  • Configuração (app/config.py): novos parâmetros para limites de segurança (ex.: CATEGORIZATION_MAX_CALLS_PER_BATCH, cache TTL).