Skip to content

Ilannildo/lumi-api

Repository files navigation

Lumi API

API responsável pelo processamento, armazenamento e análise de faturas de energia elétrica.

O sistema recebe PDFs de contas de energia, extrai automaticamente as informações via LLM, persiste os dados estruturados e disponibiliza endpoints para listagem e visualização de indicadores de consumo e economia.


Funcionalidades

Processamento de faturas

  • Upload de PDF de conta de energia
  • Extração automática dos dados da fatura via LLM multimodal
  • Criação automática de cliente (caso não exista)
  • Criação da fatura e seus itens
  • Cálculo de consumo total, energia compensada e economia de geração distribuída
  • Detecção de duplicidade por número do documento

Listagem de faturas

Permite visualizar faturas já processadas com paginação e filtros.

Filtros disponíveis:

  • Número do cliente
  • Mês de referência

Informações retornadas:

  • Consumo total
  • Energia compensada
  • Valor sem GD
  • Economia GD
  • Itens detalhados da fatura

Dashboard de Energia

Agrega dados históricos de consumo.

Retorna:

  • Consumo total (kWh)
  • Energia compensada total (kWh)
  • Quantidade de faturas
  • Série temporal mensal contendo:
    • mês de referência
    • consumo
    • energia compensada
    • quantidade de faturas

Objetivo: análise de comportamento energético do cliente.


Dashboard Financeiro

Agrega dados financeiros da geração distribuída.

Retorna:

  • Total gasto sem GD
  • Economia total gerada pela GD
  • Quantidade de faturas
  • Série temporal mensal contendo:
    • mês de referência
    • valor sem GD
    • economia gerada
    • quantidade de faturas

Objetivo: análise de retorno financeiro da geração solar.


LLM e Processamento Multimodal

O processamento da fatura não utiliza OCR tradicional baseado em coordenadas fixas.

A API utiliza um modelo multimodal (Google Gemini) capaz de interpretar diretamente o PDF como documento visual + textual, permitindo:

  • leitura de layouts variáveis de concessionárias
  • interpretação semântica dos campos
  • identificação de blocos tarifários
  • extração robusta mesmo com mudanças de formatação

Fluxo de extração

  1. O PDF é enviado para a API
  2. O arquivo é convertido para base64
  3. O modelo recebe:
    • instruções (prompt estruturado)
    • documento multimodal
  4. O modelo retorna JSON estruturado
  5. O JSON é validado por schema
  6. Somente dados válidos são persistidos

Validação estruturada (anti-alucinação)

A resposta da LLM não é confiada diretamente.

Ela passa por um schema validator:

  • JSON inválido → rejeitado
  • Tipos incorretos → rejeitado
  • Campos obrigatórios ausentes → rejeitado

Isso garante previsibilidade no domínio e impede persistência de dados alucinados.


Tratamento de erros da IA

A API separa erros em categorias:

Tipo Significado
LLM API Error falha de comunicação / timeout / provider
Parse Error retorno não é JSON
Validation Error retorno não corresponde ao schema
Business Error não é uma fatura válida

Essa separação permite observabilidade e métricas reais da qualidade do modelo.


Endpoints

Upload de fatura

POST /invoices

Recebe um PDF e inicia o processamento.

Request: multipart/form-data file: pdf

Response:

  • id
  • fileName
  • status
  • message

Listar faturas

GET /invoices

Query params:

  • page (obrigatório)
  • limit (obrigatório)
  • customerNumber (opcional)
  • referenceMonth (opcional)

Dashboard Energia

GET /dashboard/energy

Query params:

  • customerNumber (opcional)

Dashboard Financeiro

GET /dashboard/finance

Query params:

  • customerNumber (opcional)

Stack utilizada

A arquitetura foi pensada para lidar com três desafios principais do domínio:

  • documentos com layout variável
  • uso de IA não determinística
  • dados financeiros que exigem consistência

O objetivo não foi apenas “fazer funcionar”, mas garantir previsibilidade do sistema mesmo dependendo de um provider externo.


NestJS

A aplicação segue o padrão Use Cases + Repositories + Gateways.

Motivos:

  • separação clara entre domínio e integrações externas
  • facilidade de testar sem depender de LLM ou banco
  • tratamento padronizado de erros
  • estrutura estável para crescer sem virar código acoplado

Como a IA pode falhar, a estrutura do sistema precisa ser totalmente previsível.


Prisma + PostgreSQL

Os dados manipulados são financeiros e agregados históricos. Por isso, a camada mais confiável do sistema precisa ser o banco.

Prisma

  • tipagem forte nas queries
  • migrations versionadas
  • menor risco ao evoluir o schema

PostgreSQL

  • precisão decimal confiável
  • integridade relacional
  • bom suporte a agregações mensais e relatórios

A LLM interpreta o documento — o backend valida e calcula.


Google Gemini - LLM Multimodal

Faturas não possuem padrão fixo entre concessionárias. Um OCR tradicional exigiria manutenção por layout.

O Gemini foi usado como leitor semântico, capaz de entender tabelas e contexto tarifário independentemente do formato.

Para garantir confiabilidade:

nenhuma resposta da IA é salva sem validação de schema

O sistema assume que a IA pode errar.


Validação de Schema

A IA não é tratada como fonte de verdade.

Fluxo:

  1. LLM extrai dados
  2. resposta é validada
  3. domínio recalcula valores
  4. só então persiste

Assim o resultado final permanece determinístico.


Docker

Permite subir o projeto completo com um comando e evita diferenças entre ambientes locais.


Kubernetes (k3s)

Chamadas para LLM podem ser lentas ou falhar.

O deploy considera:

  • containers stateless
  • reinício automático em falhas externas
  • escalabilidade horizontal

k3s foi suficiente para um cenário leve sem complexidade operacional.


Variáveis de ambiente

Crie um arquivo .env:

NODE_ENV="development"
PORT=8000
APP_NAME="lumi"
APP_BASE_URL="http://localhost:8000"

# Database
DATABASE_HOST=127.0.0.1
DATABASE_PORT=5460
DATABASE_USER=lumi
DATABASE_PASS=lumi
DATABASE_NAME=lumi
DATABASE_URL="postgresql://lumi:lumi@localhost:5460/lumi?schema=public"

LLM_API_KEY="<your_gemini_api_key>"
LLM_MODEL="<gemini_model>" #Ex: gemini-2.5-flash

Executando localmente

1. Subir banco via Docker

docker compose up -d

2. Instalar dependências

pnpm install

3. Rodar migrations

pnpm prisma migrate dev

4. Iniciar aplicação

pnpm start:dev

Swagger: https://api.lumi.ilannildo.com.br/docs


Fluxo resumido

  1. Usuário envia PDF
  2. LLM interpreta documento multimodal
  3. Resposta é validada por schema
  4. Dados estruturados são persistidos
  5. Sistema disponibiliza relatórios e dashboards

Ambiente de Produção

Deploy preparado para Kubernetes (k3s)

Características:

  • containers stateless
  • banco externo
  • variáveis via secrets
  • escalável horizontalmente

Observações

O sistema foi projetado priorizando:

  • separação por camadas (use cases + repositories)
  • previsibilidade de domínio
  • tolerância a erros de IA
  • independência de provider de LLM
  • testes unitários e e2e

About

API para processamento automático de faturas de energia: recebe PDFs, extrai dados via LLM multimodal (Gemini), valida por schema e gera dashboards de consumo e economia. NestJS + Prisma + PostgreSQL + Docker + Kubernetes.

Topics

Resources

Stars

Watchers

Forks

Contributors