Sites Latam · Sistema Interno

OMNI-PROD
Documentação do Sistema

Plataforma web para gestão de contratos de telecom — calculadora de reajustes, conciliação financeira VIVO/CLARO, extração automática de PDFs e base cadastral de contratos.

code FastAPI + SQLAlchemy + MySQL web SPA HTML/CSS/JS Vanilla table_chart openpyxl + xlsxwriter picture_as_pdf pdfplumber + Robot calendar_today Atualizado: Maio 2026
Resumo Executivo

O que é o OMNI-PROD?

Uma visão direta e objetiva do sistema — ideal para novos usuários ou gestores.

O OMNI-PROD é o sistema web interno da Sites Latam para gestão financeira de contratos de telecom. Roda localmente via Python/FastAPI e é acessado pelo navegador em omni.cobra.ninja.

calculate

Calculadora de Reajustes

Calcula reajustes contratuais aplicando índices IPCA, IGP-M ou INPC com múltiplos períodos, exceções e visão mensal/anual. Exporta Excel com memória de cálculo.

compare_arrows

Conciliação VIVO

Cruza automaticamente o extrato SAP (FBL5N) com a Composição de Pagamento VIVO. Gera Excel com status de baixa linha a linha e resumo gráfico consolidado.

compare_arrows

Conciliação CLARO

Mesmo fluxo da VIVO, adaptado para o padrão CLARO. Usa normalização inteligente de colunas (Raio-X) e match em cascata em 2 níveis para cobrir divergências.

picture_as_pdf

Robot — Extração de PDFs

Lê PDFs de contratos e extrai automaticamente valor mensal, índice, vigência, dados do locador e cláusulas financeiras. Gera planilha com score de confiança por arquivo.

database

Database

Cadastro mestre de contratos (De-Para Financeiro). Gerencia siglas VIVO e CLARO, dados de OCR por ID TBSA, auditoria completa de ações e lookup para a calculadora.

admin_panel_settings

Administração

Gestão completa de usuários: criar, bloquear, resetar senha e excluir. Controle de acesso em 3 perfis: admin, analista e cliente.

person

Perfis de Acesso

Admin — acesso total. Analista — calculadora, conciliação, database, robot. Cliente — visualização das próprias análises (inputs congelados).

Fluxo típico de uso — Conciliação

Analista faz login
Seleciona VIVO ou CLARO
Upload FBL5N + Composição
Robô processa (9 etapas)
Baixa Excel resultado

Como acessar o sistema

terminal
Execute no terminal: & "C:\Users\LucasGomesMoura\anaconda3\python.exe" -m uvicorn main:app --reload --use-colors a partir do diretório do projeto. Acesse em http://localhost:8000.
Infraestrutura

Stack Técnica

Tecnologias usadas em cada camada do sistema.

FastAPI

Framework backend — rotas REST + SSE

SQLAlchemy

ORM + gerenciamento de conexões MySQL

MySQL (PyMySQL)

Banco de dados — db_pythonExtract_mysql

Pandas

Normalização e cruzamento de dados Excel

openpyxl

Leitura de arquivos Excel (.xlsx)

xlsxwriter

Geração do Excel de resultado com gráficos

Vanilla JS

Frontend SPA (fetch API + EventSource SSE)

Outfit® / Brand

Tipografia única — Manual de Marca 2022

Uvicorn

Servidor ASGI — execução local (Anaconda)

pdfplumber

Extração de texto nativo de PDFs (Robot Manual)

Identidade Visual — Variáveis CSS obrigatórias

/* Manual de Marca Sites Latam 2022 */ :root { --brand-red: #EB0045; /* Rojo Grana */ --brand-blue: #003E52; /* Azul Prusia */ --brand-gray: #C1C5C8; /* Gris Perla */ --font-family: 'Outfit', sans-serif; }
warning
Proibições da Marca: Nunca usar outra fonte além de Outfit®. Nunca usar variações de cor fora da paleta. Nunca usar vermelho como fundo de tela inteira.
info
Ícones: Material Symbols Outlined (Google Fonts) — 24px, FILL=0, GRAD=0.
Técnico

Arquitetura do Sistema

Estrutura de arquivos e responsabilidade de cada componente.

Arquivo Responsabilidade Tamanho
main.py Entrypoint FastAPI — 29 rotas (auth, análises, índices, admin, conciliação). Configura CORS, SSE e serve arquivos estáticos. ~527 linhas
database.py Engine SQLAlchemy com MySQL (pool_pre_ping=True, pool_recycle=3600s, base=5, overflow=10). Factory de sessão get_db(). ~40 linhas
models.py 11 modelos ORM ativos: Usuario, IndiceFinanceiro, Analise, DadoRobo, LogAcesso, DeparaFinanceiro, SiglasVivo, SiglasClaro, LogBaseTotal, HistoricoConciliacao. Legado mantido temporariamente: DimBaseTotal, MapVivo, MapClaro. ~230 linhas
routers/base_total.py 20 rotas para CRUD de DIM/VIVO/CLARO, importação em lote otimizada, logs de auditoria e lookup para a calculadora. ~761 linhas
routers/conciliacao_vivo.py Robô VIVO — 9 etapas de processamento: leitura, normalização, match Seguro (ID+Sigla+Mês) + Flexível (valor ±0.05), geração Excel com 7 abas. ~594 linhas
routers/conciliacao_claro.py Robô CLARO — 9 etapas: Raio-X de colunas, match em cascata (Macro→Micro→Salva-vidas), geração Excel com 8 abas. ~755 linhas
routers/robot_manual.py Módulo Robot — processamento paralelo de PDFs, SSE de progresso, histórico por sessão, re-exportação Excel. ~400 linhas
Robov22/extractor.py Core de extração de PDFs via regex — reutilizado pelo Robot Manual. NÃO alterar sem alinhar com robot_manual.py. ~600 linhas
index.html SPA completa — 8 views, 100+ funções JS, sistema de autenticação, upload de arquivos, progresso SSE, tabelas paginadas, modais e drawers. ~256 KB
.env Credenciais do banco MySQL (não versionado). DATABASE_URL e configurações de ambiente.

Fluxo de requisição completo

Navegador
(index.html)
fetch() / EventSource
FastAPI
(main.py)
Router
específico
SQLAlchemy
ORM
MySQL
db_pythonExtract
Banco de Dados

Tabelas e Modelos

Estrutura completa do banco MySQL — modelos ORM definidos em models.py.

check_circle
Arquitetura atual: a tabela depara_financeiro é a base única de cruzamento para VIVO e CLARO. As tabelas legadas dim_base_total, map_vivo e map_claro permanecem no banco por compatibilidade mas não são mais utilizadas pelos robôs.

Tabelas do sistema

person usuarios — Autenticação e perfis
usuarios PK: email
PKemailVARCHAR(100)Identificador único — usado em todas as rotas de autenticação
nomeVARCHAR(100)Nome de exibição
senha_hashTEXT⚠️ Atualmente armazenada em texto puro (backlog de segurança: implementar bcrypt)
perfilENUMadmin | analista | cliente
ativoBOOLEANFalse = usuário bloqueado (não consegue logar)
id_cliente_vinculadoINTEGERPara perfil cliente — filtra análises visíveis
ultimo_acessoDATETIMEAtualizado no heartbeat de sessão
trending_up indices_financeiros — IPCA, IGP-M, INPC
indices_financeiros PK: id
PKidINTEGERAuto increment
nome_indiceVARCHAR(20)IPCA | IGP-M | INPC | IGP-DI | IPCA-E | IPC-BRASIL | IPC-SP
mes_referenciaVARCHAR(7)Formato: YYYY-MM (ex: 2024-01)
valorFLOATVariação percentual mensal (ex: 0.52 = 0,52%)
info
Sincronizado automaticamente com o SGS do Banco Central (BACEN) via POST /api/sincronizar-indices. Usado pela calculadora para calcular acumulados de 12 meses.
folder_open analises — Memórias de cálculo salvas
analises PK: id
PKidINTEGERAuto increment
nome_contratoTEXTIdentificador do contrato (ex: nome do site)
email_usuarioVARCHAR(100)Quem salvou a análise
id_clienteINTEGERPara filtrar por cliente vinculado
dados_jsonTEXT (JSON)Objeto completo da memória de cálculo serializada
criado_emDATETIMETimestamp de criação

Tabelas — Data Base

hub depara_financeiro — Tabela mestra única de cruzamento
info
Base única utilizada por VIVO e CLARO. VIVO busca por contrato_re_cliente (RE da VIVO na Composição). CLARO filtra por sub_grupo = 'CLARO' e cruza por contrato_re_cliente.
depara_financeiro PK: id · UK: contrato_re_cliente
PKidINTEGERAuto increment
UKcontrato_re_clienteVARCHAR(50)Código RE da operadora — chave de match nos robôs
contrato_re_sapVARCHAR(50)Nº do contrato SAP correspondente
sub_grupoVARCHAR(100)Operadora / agrupamento (ex: CLARO, VIVO)
nome_clienteVARCHAR(200)Nome do cliente / locador
id_tbsaVARCHAR(50)ID interno Sites Latam
id_clienteVARCHAR(50)ID do cliente no sistema interno
portfolioVARCHAR(50)Portfólio padronizado (ex: VIVO_LEGADO, VIVO_COLLO)
criado_porVARCHAR(100)Email do usuário que importou o registro
criado_em / atualizado_emDATETIMETimestamps de criação e última atualização
swap_horiz siglas_vivo + siglas_claro — De-Para de tipos (editável)
edit
Ambas as tabelas são editáveis pelo analista diretamente pelo módulo Data Base (abas Siglas VIVO / Siglas CLARO), sem necessidade de acesso ao banco. Alterações refletem imediatamente nos robôs.
siglas_vivo UK: denom_tipo_condicao
PKidINTEGERAuto increment
UKdenom_tipo_condicaoVARCHAR(200)Denominação exata como aparece na Composição VIVO
siglaVARCHAR(10)Sigla SAP correspondente (ex: RJ, RH, RF)
ref_tbsaVARCHAR(50)Referência interna opcional
atualizado_emDATETIMEÚltima edição pelo analista
siglas_claro PK: id
PKidINTEGERAuto increment
tipoVARCHAR(100)Categoria do tipo de movimentação
tipo_de_condicaoVARCHAR(200)Condição da movimentação CLARO
denom_tipo_movVARCHAR(200)Denominação exata como aparece na Composição CLARO
siglaVARCHAR(10)Sigla SAP correspondente
atualizado_emDATETIMEÚltima edição pelo analista
picture_as_pdf robot_manual — Resultados de extração de PDFs
robot_manual PK: id
PKidINTEGERAuto increment
session_idVARCHAR(36)UUID que agrupa todos os arquivos de uma mesma execução
email_usuarioVARCHAR(100)Analista que fez o upload
nome_arquivoTEXTNome do PDF processado
tipo_contratoVARCHAR(100)Ex: locação, aditivo, renovação
valor_mensalFLOATValor mensal extraído do contrato
indiceVARCHAR(20)Índice de reajuste identificado (IPCA, IGP-M, INPC…)
vigencia_inicio / vigencia_fimVARCHAR(20)Período de vigência do contrato
score_confiancaINTEGERScore de 0 a 100 calculado pelo extractor
acao_sugeridaVARCHAR(50)✅ LIBERADO | 🟡 REVISAR | 🔴 PRIORITÁRIA
alertas_tecnicosTEXTCampos não encontrados ou fora dos limites esperados
criado_emDATETIMETimestamp de processamento
history historico_conciliacao + log_base_total — Auditoria
info
Os campos qtd_divergente_totais e val_divergente_totais já estão definidos no model e são criados automaticamente via metadata.create_all() ao iniciar o servidor.
CampoDescrição
tipo_roboVIVO ou CLARO
statusSUCESSO ou ERRO
qtd_baixar / val_baixarQuantidade e valor com status BAIXAR
qtd_baixar_pos / val_baixar_posBaixar com Saldo Positivo
qtd_baixa_parc / val_baixa_parcBaixa Parcial (falta pagamento)
qtd_conf_sap / val_conf_sapConferir — não achou no SAP
qtd_conf_depara / val_conf_deparaConferir — sem De-Para
qtd_divergente_totais / val_divergente_totais⚠️ Exclusivo CLARO — Divergente no SAP

log_base_total registra toda ação na base: INSERT, UPDATE, DELETE, TENTATIVA_DUPLICADA, IMPORTACAO_LOTE — com usuario, tabela, campo alterado e valores antes/depois.

Módulo

Calculadora de Reajustes

Cálculo mensal de reajustes contratuais com múltiplos índices e períodos.

O que faz

Calcula o valor atualizado de um contrato mês a mês, aplicando IPCA, IGP-M ou INPC sobre um valor base. Suporta múltiplos períodos contratuais (mudança de índice/valor no meio do contrato) e exceções/acordos pontuais.

Fluxo de cálculo

1

Entrada de dados

Analista informa: ID TBSA, períodos (data início, mês base do índice, índice IPCA/IGP-M/INPC, valor, quantidade) e eventuais exceções.

2

Lookup automático

Ao digitar o ID TBSA, verificarRobo() consulta /api/base-total/lookup/{idTbsa} e exibe o contrato SAP, cliente e portfólio automaticamente.

3

Cálculo mensal

calcularMemoria() aplica o acumulado dos índices mês a mês via getIndiceAcumulado(), que busca os 12 meses anteriores no cacheIndices.

4

Visualização e exportação

Resultado exibido em visão mensal ou anual. Exportação via exportarExcel() gera XLSX com duas abas: Memória Vertical e Visão Corrida.

Índices disponíveis (7)

ÍndiceFonteCadência
IPCAIBGE via BACEN SGSMensal
IGP-MFGV via BACEN SGSMensal
INPCIBGE via BACEN SGSMensal
IGP-DIFGV via BACEN SGSMensal
IPCA-EIBGE via BACEN SGSMensal
IPC-BRASILFIPE via BACEN SGSMensal
IPC-SPFIPE via BACEN SGSMensal

Controle de acesso

lock
Perfil cliente visualiza as próprias análises mas com inputs congelados — não pode editar os parâmetros do contrato.

Principais funções JS

FunçãoDescrição
calcularMemoria()Executa o cálculo e preenche dadosMemoriaAtual
getIndiceAcumulado()Retorna acumulado de 12 meses do índice selecionado
renderizarTabela()Exibe resultado em tabela mensal ou anual
alternarVisao(modo)Alterna entre 'mensal' e 'anual'
exportarExcel()Gera e baixa XLSX com Memória Vertical + Visão Corrida
carregarFormulario(id)Carrega análise salva do banco pelo ID
Módulo

Robô de Conciliação VIVO

Cruzamento automático do extrato SAP (FBL5N) com a Composição de Pagamento VIVO. Arquivo: routers/conciliacao_vivo.py

Entradas

ArquivoCampo-chave
FBL5N.xlsxChvRefer.(cabeç.) 1 = ID TBSA
Composição de Pagamento.xlsxContrato VIVO + tipo de movimentação

Status de saída

BAIXAR BAIXAR (+ SALDO POSITIVO) BAIXA PARCIAL (FALTA PAGAMENTO) CONFERIR (NÃO ACHOU NO SAP) CONFERIR (SEM DE-PARA)

Abas do Excel gerado (7)

#AbaConteúdo
1Resumo Geral ★4 gráficos grid 2×2 + tabelas por status/tipo/portfólio
2comp formatadaResultado linha a linha com status colorido
3Glossário do RobôExplicação de cada status e tipo
4Template SAPColunas: Núm.Documento, Ano, Montante, Núm.Contrato, Atribuição, Cliente
5FBL5NCópia do arquivo original
6ComposiçãoCópia do arquivo original
7_ref (oculta)Dados auxiliares para os gráficos — nunca remover

Etapas de processamento

1

Leitura e validação

Abre FBL5N e Composição. Verifica presença das colunas obrigatórias. Carrega dicionário de siglas via SiglasVivo em runtime.

2

Preparação FBL5N

Extrai Nº do contrato, tipo de documento, data e montante. Normaliza contratos (remove .0 e zeros à esquerda). Gera Chave = contrato + tipo + data.

3

Preparação Composição

Identifica colunas. Busca De-Para em depara_financeiro por contrato_re_cliente. Traduz denominações → siglas SAP. Gera Chave = contrato_re + sigla + calc_de.

4

Cruzamento Nível 1 — Chave Exata

Agrupa FBL5N e Composição por Chave e soma montantes (SOMASE). Calcula DIF = Comp − FBL. Se |DIF| ≤ 0,05BAIXAR. Sem match → Conferir Data.

5

Cruzamento Nível 2 — Aba Em Aberto

Para linhas "Conferir Data" (sem correspondência na FBL), aplica 2Chave = contrato_re + denominação original. Captura Montante Real e Nº Documento e reavalia diferença. Resultado: Maior na FBL / Menor na FBL.

6

Geração do Excel

Gera arquivo com 7 abas completas, 4 gráficos (pizza de status, tipos, saúde financeira, ticket médio) e formatação condicional por cor de status.

De-Para de tipos (VIVO → SAP)

O De-Para de tipos é mantido na tabela siglas_vivo e gerenciado pelo analista diretamente no módulo Data Base → aba Siglas VIVO. Exemplo básico de como a tabela deve estar preenchida:

Denominação (Composição VIVO)Sigla SAP
KL - ALUGUELRJ
KL - INFRA-ESTRUTUR / BASE FEERH
KL - INFRA ADICIONALRF
KL - REEMBOLSO ENERGRI
KL - DESCONTONI
KL - TAXA REFORÇORL

A coluna "Denominação" deve ser a cópia exata do valor que aparece na Composição de Pagamento — incluindo maiúsculas, traços e espaços.

edit
Como editar: acesse Data Base → Siglas VIVO, clique no ícone de edição na linha desejada, altere a sigla SAP e salve. A alteração reflete imediatamente na próxima execução do robô — sem necessidade de reiniciar o servidor.
warning
Se uma denominação da Composição não tiver correspondência em siglas_vivo, a linha receberá status CONFERIR (SEM DE-PARA) no Excel de resultado.
Módulo

Robô de Conciliação CLARO

Cruzamento com normalização inteligente de colunas e match em cascata de 3 níveis. Arquivo: routers/conciliacao_claro.py

Diferenças em relação ao VIVO

AspectoVIVOCLARO
Chave de matchID TBSA (campo ChvRefer)Nº do contrato SAP
Normalização de colunasPadrãoRaio-X (NFKD + regex)
Algoritmo de matchSeguro + FlexívelCascata: Macro→Micro→Salva-vidas
Status exclusivoDIVERGENTE NO SAP
Abas Excel78 (+ Auditoria CLARO)

Status de saída (6)

BAIXAR Maior na FBL Menor na FBL Conferir FBL Divergente (Totais) Sem De-Para

Raio-X — Normalização de Colunas

biotech
O SAP exporta colunas com nomes inconsistentes (acentos, espaços extras, pontos). O Raio-X normaliza antes de qualquer busca.
# Normaliza para ASCII uppercase sem espaços def _norm_col(c): c = unicodedata.normalize('NFKD', str(c)) c = ''.join(ch for ch in c if not unicodedata.combining(ch)) return re.sub(r'[^A-Z0-9]', '', c.upper()) # Busca tolerante a variações de nome def _find_col(colunas, *chaves): normed = {_norm_col(c): c for c in colunas} for chave in chaves: if _norm_col(chave) in normed: return normed[_norm_col(chave)] return None

Match em 2 Níveis

key

Nível 1 — Chave Exata

Gera a Chave na Composição: contrato_re + sigla + valor + calc_de. Cruza com a Chave da FBL5N (contrato + tipo + valor + data). Match exato → BAIXAR. Senão, segue ao Nível 2.

search

Nível 2 — 3Chave (Contrato + Tipo)

Para linhas sem match: usa 3Chave = contrato + tipo, ignorando valor e data. Busca na FBL5N e captura o Montante Real. Calcula DIF = Comp − FBL e atribui status final.

calculate

Auditoria de Diferenças

Se |DIF| ≤ 0,05BAIXAR. Se FBL maior → Maior na FBL. Se FBL menor → Menor na FBL. Se totalização diverge → Divergente (Totais). Sem De-Para → Sem De-Para.

Abas do Excel gerado (8)

#AbaConteúdo
1Resumo Geral ★4 gráficos grid 2×2 + tabelas de consolidação da saúde financeira
2comp formatadaResultado linha a linha com status colorido (Nível 1)
3Auditoria CLAROCasos Sem De-Para, anomalias e divergências de chave
4Em AbertoAnálise Nível 2 — divergências financeiras com 3Chave
5Template SAPLinhas aptas a BAIXAR prontas para lançamento no SAP
6Glossário do RobôExplicação de cada status e parâmetro
7FBL5NCópia do arquivo original
8Composição/P1Cópia do arquivo original
Módulo

Robot — Extração de Contratos PDF

Leitura automática de PDFs de contratos: extrai dados financeiros, identifica cláusulas e gera planilha com score de confiança por arquivo. Arquivo: routers/robot_manual.py

Como funciona

1

Upload dos PDFs

Analista seleciona um ou mais arquivos PDF no módulo Robot. O sistema processa até 2 arquivos em paralelo.

2

Extração de texto

O pdfplumber extrai o texto nativo do PDF (sem OCR). Arquivos com menos de 50 caracteres legíveis são sinalizados como não processáveis.

3

Análise inteligente

O motor de extração busca cada campo usando âncoras, regex e dicionários de negócio. Cada campo extraído contribui para o Score de Confiança (0–100).

4

Validação de sanidade

Valor mensal aceito: R$500 a R$500.000. Vigência aceita: 12 a 120 meses. Valores fora desses limites geram alertas técnicos.

5

Resultado e exportação

Salva em robot_manual e gera Excel colorido: verde = LIBERADO, amarelo = REVISAR, vermelho = PRIORITÁRIA.

Ação sugerida por score

ScoreAçãoSignificado
Alto✅ LIBERADODados completos, valores dentro dos limites esperados
Médio🟡 REVISARUm ou mais campos faltando ou fora do padrão — conferir manualmente
Baixo🔴 PRIORITÁRIAMúltiplos campos ausentes ou inválidos — requer atenção imediata

Campos extraídos por contrato

CampoDescrição
Tipo_ContratoLocação, aditivo, renovação, rescisão, sublocação
Valor_MensalValor financeiro mensal do contrato
IndiceÍndice de reajuste identificado (IPCA, IGP-M, INPC…)
Percentual_ReajustePercentual de reajuste contratual
Data_Base_ReajusteData de referência para o reajuste
Vigencia_InicioData de início da vigência
Vigencia_FimData de fim da vigência
Tem_RenovatoriaSe há cláusula de renovação automática
GarantiaTipo de garantia: caução, fiador, seguro fiança
Multa_RescisaoPercentual de multa por rescisão
Locador_NomeNome do locador extraído do texto
Locador_CPF_CNPJCPF ou CNPJ do locador
Banco / Agencia / ContaDados bancários para pagamento
Score_ConfiancaNota de 0 a 100 calculada pelo robô
Alertas_TecnicosLista de campos não encontrados ou fora do limite
history
O histórico de sessões fica disponível no módulo Robot — cada execução agrupa todos os PDFs de um mesmo upload por session_id. É possível re-exportar o Excel de qualquer sessão anterior.
Módulo

Database

Cadastro mestre e De-Para de contratos. Arquivo: routers/base_total.py

Abas do módulo

Aba (painel)TabelaFinalidade
De-Para Financeirodepara_financeiroBase mestra — importação/exportação/busca por contrato_re_cliente
Siglas VIVOsiglas_vivoDe-Para de tipos VIVO → sigla SAP, editável por linha
Siglas CLAROsiglas_claroDe-Para de tipos CLARO → sigla SAP, editável por linha
Robô (OCR)dados_roboResultados de OCR legado por ID TBSA — editável via drawer
Logslog_base_totalAuditoria de todas as ações — exportável em Excel

Importação De-Para — como funciona

1

Upload do Excel

Analista seleciona arquivo na aba De-Para Financeiro. Colunas esperadas: contrato_re_cliente, contrato_re_sap, sub_grupo, nome_cliente, id_tbsa, id_cliente, portfolio.

2

Leitura e normalização

Backend normaliza colunas, faz strip de strings e trata o bug .0 (pandas converte inteiros para float).

3

Upsert por contrato_re_cliente

Carrega chaves existentes em memória (set). Cada linha: se existe → update; se não → insert. Nunca 1 query por linha.

4

bulk_save_objects()

Salva tudo em uma única operação. Registra IMPORTACAO_LOTE em log_base_total com contagem de inserções e atualizações.

Lookup para a Calculadora

search
Ao digitar o ID TBSA na calculadora, GET /api/base-total/lookup/{id_tbsa} busca todos os contratos vinculados em depara_financeiro e retorna contrato SAP, nome do cliente, portfólio e sub_grupo. Aparece como tooltip abaixo do campo.

Portfólios VIVO padronizados

VIVO_LEGADO VIVO_COLLO VIVO_GARLIAVA VIVO_EMBRATEL VIVO_NX VIVO_GVT

Fix crítico — bug do .0

bug_report
Pandas converte inteiros em float ao ler Excel: 1234 vira 1234.0. O código faz .split('.')[0] ou .replace('.0', '') antes de salvar no banco.

Auditoria completa

Toda ação é registrada em log_base_total com: usuário, tabela, ação (EDITAR / IMPORTACAO_LOTE / EXPORTAR), dados enviados em JSON e mensagem de resultado.

Módulo

Administração de Usuários

Gestão completa de usuários com controle de acesso em 3 perfis.

Perfis de acesso

PerfilAcesso
adminAcesso total a todos os módulos + gestão de usuários + logs
analistaCalculadora, conciliação, base total. Vê apenas as próprias análises.
clienteApenas visualização — análises do próprio cliente com inputs congelados

Operações disponíveis

  • Criar usuário (email + nome + perfil + id_cliente_vinculado)
  • Bloquear / Desbloquear (ativo = false/true)
  • Resetar senha (admin define nova senha)
  • Excluir usuário permanentemente
  • Visualizar usuários online (heartbeat dos últimos 30s)

Heartbeat de sessão

O frontend envia um ping para GET /api/usuarios/{email}/status periodicamente. O campo ultimo_acesso é atualizado. A rota GET /api/admin/logs retorna usuários com acesso nos últimos 30 segundos.

Sincronização de Índices

sync
POST /api/sincronizar-indices consulta o SGS do BACEN para cada série (IPCA: 433, IGP-M: 189, INPC: 188) e atualiza a tabela indices_financeiros com os valores mais recentes.
lock
O acesso ao sistema é feito por email e senha. Perfis analista e cliente possuem acesso restrito — cada um vê apenas seus próprios dados e funcionalidades permitidas.
Referência

Rotas da API

Todas as rotas REST expostas pelo FastAPI em http://localhost:8000/api/.

Autenticação e Sessão
POST/api/loginAutenticação — retorna dados do usuário
GET/api/usuarios/{email}/statusHeartbeat — atualiza ultimo_acesso
PATCH/api/usuarios/{email}/senhaUsuário altera a própria senha
Análises (Calculadora)
GET/api/analisesLista análises filtradas por perfil/cliente
POST/api/analisesSalva nova memória de cálculo
DEL/api/analises/{id}Remove análise pelo ID
Índices Financeiros
GET/api/indicesLista todos os índices IPCA/IGP-M/INPC
POST/api/sincronizar-indicesSincroniza com BACEN SGS
Database — De-Para Financeiro
GET/api/base-total/depara-financeiroLista com filtros (sub_grupo, id_tbsa, busca por contrato/cliente)
POST/api/base-total/depara-financeiro/importarImportação em lote — upsert por contrato_re_cliente
GET/api/base-total/depara-financeiro/exportarExporta base completa para Excel
Database — Siglas
GET/api/base-total/siglas-vivoLista siglas VIVO (busca por denom ou sigla)
PATCH/api/base-total/siglas-vivo/{id}Edita sigla VIVO por linha — registra em log
GET/api/base-total/siglas-claroLista siglas CLARO
PATCH/api/base-total/siglas-claro/{id}Edita sigla CLARO por linha — registra em log
Database — Logs, Lookup e OCR
GET/api/base-total/logsAuditoria completa (tabela, ação, usuário, limit, offset)
GET/api/base-total/logs/exportarExporta logs de auditoria para Excel
GET/api/base-total/lookup/{id_tbsa}Lookup para auto-preenchimento na calculadora
GET/api/base-total/roboConsulta dados OCR legado por id_tbsa
GET/api/base-total/robo/exportarExporta dados OCR para Excel
Robot — Extração de PDFs
POST/api/robot/processarUpload de N PDFs → processa, salva no banco e retorna Excel
GET/api/robot/progresso/{job_id}SSE — acompanha progresso em tempo real por job_id
GET/api/robot/sessao/{session_id}Resultados de uma sessão específica
GET/api/robot/historicoLista sessões agrupadas — admin vê todas, analista vê as suas
GET/api/robot/exportar/{session_id}Re-gera Excel de uma sessão histórica
Conciliação
POST/api/conciliacao/vivo/processarProcessa robô VIVO — Form: fbl5n, composicao, email_usuario, job_id
POST/api/conciliacao/claro/processarProcessa robô CLARO — Form: fbl5n, composicao, email_usuario, job_id
GET/api/conciliacao/progresso/{job_id}SSE — progresso em tempo real (chave: UUID gerado no frontend)
GET/api/conciliacao/historicoHistórico de execuções (admin vê tudo, analista vê as suas)
Administração de Usuários
GET/api/admin/usuariosLista todos os usuários
POST/api/admin/usuariosCria novo usuário
PATCH/api/admin/usuarios/{email}/statusAtiva / bloqueia usuário
PATCH/api/admin/usuarios/{email}/reset-senhaAdmin redefine senha do usuário
DEL/api/admin/usuarios/{email}Exclui usuário permanentemente
GET/api/admin/logsUsuários online (ultimo_acesso nos últimos 30s)
Frontend

Frontend SPA — index.html

Single Page Application completa em um único arquivo HTML. Toda lógica de UI, autenticação e requisições API está em Vanilla JS.

Telas (Views)

ID da ViewTítuloPerfilDescrição
viewHubIníciotodosCards de navegação para todos os módulos
viewAnalisesAnálisestodosGrid de análises salvas com opções de carregar/excluir
viewCalcCalculadoraanalista/adminCalculadora interativa de reajustes contratuais
viewConciliacaoConciliaçãoanalista/adminUpload + processamento VIVO/CLARO + histórico
viewBaseTotaDatabaseanalista/adminAbas De-Para/Siglas/Robô OCR/Logs com CRUD e importação
viewRobotManualRobotanalista/adminUpload de PDFs, resultados com score, histórico de sessões
viewAdminAdministraçãoadminGestão de usuários + estatísticas + chips de online
viewPerfilMeu PerfiltodosDados do usuário + alteração de senha

Variáveis globais de estado

// Sessão let usuarioAtual = null; // { email, perfil, id, id_cliente_vinculado } // Cache de dados let cacheIndices = {}; let contratos = []; let dadosMemoriaAtual = []; let modoVisaoAtual = 'mensal'; // Base Total let abaBaseTotalAtiva = 'dim'; const PAGE_SIZE = 50; // Conciliação — PERSISTEM entre navegações let _arquivoFbl5n = null; let _arquivosComposicao = null; let _bytesResultado = null; let _clienteResultado = null;

Funções-chave de navegação

FunçãoDescrição
navegarPara(view)Troca de tela, atualiza sidebar highlight
fazerLogin(event)Autentica via /api/login, salva sessão em localStorage
fazerLogout()Limpa sessão e retorna para tela de login
toggleSidebar()Colapsa/expande sidebar (240px ↔ 64px)

Comportamento da Conciliação

  • _bytesResultado persiste entre navegações — chip verde "Resultado disponível" fica visível até resetar
  • resetarConciliacao() limpa tudo: arquivos + resultado + progresso
  • O job_id é um UUID gerado via crypto.randomUUID() — evita colisão entre execuções paralelas
  • Barra de progresso simulada (0→95%) enquanto o backend processa — não usa SSE diretamente
Referência Técnica

Regras Críticas de Desenvolvimento

Restrições e decisões técnicas que devem ser respeitadas em todo novo código.

block

Nunca usar merge_cells

O openpyxl com merge_cells em arquivos com gráficos dinâmicos causa erro de reparo no Excel. Solução: layouts sem mesclagem de células.

visibility_off

Dados de gráficos na aba _ref

Dados usados pelos gráficos ficam na aba _ref com sheet_state='hidden'. Colunas ocultas na mesma aba quebram os gráficos no Excel.

loop

iterrows() — nunca itertuples()

Colunas do SAP têm espaços nos nomes. O itertuples() renomeia automaticamente essas colunas. Sempre usar iterrows() nos robôs.

pin

Fix do .0 em contratos

Pandas converte inteiros para float ao ler Excel: 1234 → 1234.0. Sempre fazer str(val).replace('.0', '') antes de salvar contratos no banco.

storage

Pool de conexões MySQL

pool_pre_ping=True + pool_recycle=3600 no database.py evita o erro "Lost connection to MySQL server". Nunca remover essas configurações.

bolt

Bulk operations em importações

Nunca fazer 1 query por linha. Preparar lista em memória com verificação de duplicatas via set e usar db.bulk_save_objects() para inserção.

sort

Ordem de abas Excel

Usar wb._sheets = [wb[nome] for nome in lista_ordem] + wb.active = wb['Resumo Geral'] antes do save(). Nunca confiar na ordem de criação das abas.

biotech

Raio-X para colunas SAP

O SAP exporta colunas com nomes inconsistentes (acentos, espaços, pontos). Sempre usar _norm_col() + _find_col() do conciliacao_claro.py.

key

Progresso SSE usa job_id

A chave do progresso_global é o job_id (UUID), não o email do usuário. Garante que VIVO e CLARO rodando simultaneamente não conflitem.

label

Labels de gráficos — DataLabelList

Para exibir % em pizzas e valores em barras, usar DataLabelList de openpyxl.chart.label. Sem isso, os gráficos gerados saem sem anotações visíveis.