From d215e9ac76888c902e9faac4bf090342c4f4c319 Mon Sep 17 00:00:00 2001 From: Frederico Castro Date: Mon, 15 Dec 2025 12:21:54 -0300 Subject: [PATCH] =?UTF-8?q?feat(backend):=20adicionar=20valida=C3=A7=C3=A3?= =?UTF-8?q?o=20de=20selos=20ao=20script?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Verifica se bolsas, premiações e orientações do DB batem com ES - Valida top 50 consultores por padrão - Integra validação de selos no fluxo principal (passo 4/5) --- backend/scripts/validar_ranking.py | 69 +++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/backend/scripts/validar_ranking.py b/backend/scripts/validar_ranking.py index a4157c8..f926df7 100644 --- a/backend/scripts/validar_ranking.py +++ b/backend/scripts/validar_ranking.py @@ -17,6 +17,7 @@ Saída: import asyncio import argparse import csv +import json import os import sys from datetime import datetime @@ -308,6 +309,59 @@ async def validar_pontuacao_amostra( return resultados +async def validar_selos(oracle: OracleClient, es_client: ElasticsearchClient, limite: int = 50) -> Tuple[bool, List[str]]: + result = oracle.executar_query(f''' + SELECT ID_PESSOA, NOME, JSON_DETALHES + FROM TB_RANKING_CONSULTOR + WHERE POSICAO <= {limite} + ORDER BY POSICAO + ''') + + erros = [] + for r in result: + id_pessoa = r['ID_PESSOA'] + nome = r['NOME'] + detalhes = json.loads(r['JSON_DETALHES']) + + db_bolsas = len(detalhes.get('bolsas_cnpq', [])) + db_prem = len(detalhes.get('premiacoes', [])) + db_orient = len(detalhes.get('orientacoes', [])) + + doc = await es_client.buscar_por_id(id_pessoa) + if not doc: + erros.append(f'{nome}: Não encontrado no ES') + continue + + atuacoes = doc.get('atuacoes', []) + + es_bolsas = sum(1 for a in atuacoes + if 'bolsista' in str(a.get('tipo', '')).lower() + and 'cnpq' in str(a.get('tipo', '')).lower()) + + es_prem = sum(1 for a in atuacoes if a.get('tipo') == 'Premiação Prêmio') + + es_orient = 0 + for a in atuacoes: + if a.get('tipo') == 'Orientação de Discentes': + dados = a.get('dadosOrientacaoDiscente', {}) + es_orient += (dados.get('totalOrientacaoFinalizadaMestrado') or 0) + es_orient += (dados.get('totalOrientacaoFinalizadaDoutorado') or 0) + es_orient += (dados.get('totalAcompanhamentoPosDoutorado') or 0) + + diffs = [] + if db_bolsas != es_bolsas: + diffs.append(f'Bolsas DB:{db_bolsas} ES:{es_bolsas}') + if db_prem != es_prem: + diffs.append(f'Prem DB:{db_prem} ES:{es_prem}') + if db_orient != es_orient: + diffs.append(f'Orient DB:{db_orient} ES:{es_orient}') + + if diffs: + erros.append(f'{nome}: {" | ".join(diffs)}') + + return len(erros) == 0, erros + + def gerar_amostra_ids(oracle: OracleClient, tamanho: int = 100) -> List[int]: ids = [] @@ -434,7 +488,16 @@ async def main(): for erro in gaps_erros: print(f" - {erro}") - print("\n[4/4] Validando pontuação da amostra...") + print("\n[4/5] Validando selos (top 50)...") + selos_ok, selos_erros = await validar_selos(oracle, es_client, limite=50) + if selos_ok: + print("✓ Selos validados com sucesso") + else: + print(f"✗ {len(selos_erros)} divergência(s) nos selos:") + for erro in selos_erros[:5]: + print(f" - {erro}") + + print("\n[5/5] Validando pontuação da amostra...") if args.id: ids = [int(x.strip()) for x in args.id.split(",")] @@ -482,7 +545,7 @@ async def main(): print("RESUMO DA VALIDAÇÃO") print("=" * 70) - tudo_ok = criterios_ok and ordem_ok and dup_ok and gaps_ok and divergente_count == 0 + tudo_ok = criterios_ok and ordem_ok and dup_ok and gaps_ok and selos_ok and divergente_count == 0 if tudo_ok: print("✓ RANKING VÁLIDO - Todas as verificações passaram") @@ -496,6 +559,8 @@ async def main(): print(f" - Posições duplicadas") if not gaps_ok: print(f" - Gaps nas posições") + if not selos_ok: + print(f" - {len(selos_erros)} divergência(s) nos selos") if divergente_count > 0: print(f" - {divergente_count} pontuação(ões) divergente(s)")