feat: extrair docencias PPG e simplificar blocos de pontuacao

Backend:
- Adicionar entidade DocenciaPPG para dados de docencia
- Extrair docencias do Elasticsearch (tipo "Docência")
- Serializar docencias no JSON de detalhes do consultor
- Aumentar batch size de 500 para 2000 para melhor performance

Frontend:
- Remover Bloco B (Coord. PPG) - reservado para V2
- Simplificar formula para: Bloco A + Bloco C + Bloco D
- Filtrar orientacoes/bancas da listagem (sao apenas selos)
- Atualizar Header com nota que PPG_COORD e apenas indicador
- Exibir pontuacao base nos modais de orientacao/banca
This commit is contained in:
Frederico Castro
2025-12-23 04:27:36 -03:00
parent d33695ed65
commit 8799a68c30
11 changed files with 154 additions and 123 deletions

View File

@@ -12,7 +12,7 @@ class RankingOracleRepository:
def inserir_batch(self, consultores: List[Dict[str, Any]]) -> int:
"""
Insere ou atualiza um batch de consultores usando MERGE.
Insere batch de consultores usando executemany (muito mais rápido).
Retorna o número de registros processados.
"""
import oracledb
@@ -20,68 +20,39 @@ class RankingOracleRepository:
if not consultores:
return 0
merge_sql = """
MERGE INTO TB_RANKING_CONSULTOR t
USING (
SELECT
:id_pessoa AS ID_PESSOA,
:nome AS NOME,
:pontuacao_total AS PONTUACAO_TOTAL,
:componente_a AS COMPONENTE_A,
:componente_b AS COMPONENTE_B,
:componente_c AS COMPONENTE_C,
:componente_d AS COMPONENTE_D,
:ativo AS ATIVO,
:anos_atuacao AS ANOS_ATUACAO,
TO_CLOB(:json_detalhes) AS JSON_DETALHES
FROM DUAL
) s
ON (t.ID_PESSOA = s.ID_PESSOA)
WHEN MATCHED THEN
UPDATE SET
t.NOME = s.NOME,
t.PONTUACAO_TOTAL = s.PONTUACAO_TOTAL,
t.COMPONENTE_A = s.COMPONENTE_A,
t.COMPONENTE_B = s.COMPONENTE_B,
t.COMPONENTE_C = s.COMPONENTE_C,
t.COMPONENTE_D = s.COMPONENTE_D,
t.ATIVO = s.ATIVO,
t.ANOS_ATUACAO = s.ANOS_ATUACAO,
t.DT_CALCULO = CURRENT_TIMESTAMP,
t.JSON_DETALHES = s.JSON_DETALHES
WHEN NOT MATCHED THEN
INSERT (
ID_PESSOA, NOME, PONTUACAO_TOTAL,
COMPONENTE_A, COMPONENTE_B, COMPONENTE_C, COMPONENTE_D,
ATIVO, ANOS_ATUACAO, JSON_DETALHES, DT_CALCULO
)
VALUES (
s.ID_PESSOA, s.NOME, s.PONTUACAO_TOTAL,
s.COMPONENTE_A, s.COMPONENTE_B, s.COMPONENTE_C, s.COMPONENTE_D,
s.ATIVO, s.ANOS_ATUACAO, s.JSON_DETALHES, CURRENT_TIMESTAMP
)
insert_sql = """
INSERT INTO TB_RANKING_CONSULTOR (
ID_PESSOA, NOME, PONTUACAO_TOTAL,
COMPONENTE_A, COMPONENTE_B, COMPONENTE_C, COMPONENTE_D,
ATIVO, ANOS_ATUACAO, JSON_DETALHES, DT_CALCULO
) VALUES (
:id_pessoa, :nome, :pontuacao_total,
:componente_a, :componente_b, :componente_c, :componente_d,
:ativo, :anos_atuacao, :json_detalhes, CURRENT_TIMESTAMP
)
"""
batch_data = []
for consultor in consultores:
json_str = json.dumps(consultor, ensure_ascii=False)
batch_data.append({
"id_pessoa": int(consultor["id_pessoa"]),
"nome": str(consultor.get("nome", ""))[:500],
"pontuacao_total": int(consultor.get("pontuacao_total") or 0),
"componente_a": int(consultor.get("bloco_a") or consultor.get("componente_a") or 0),
"componente_b": int(consultor.get("bloco_b") or consultor.get("componente_b") or 0),
"componente_c": int(consultor.get("bloco_c") or consultor.get("componente_c") or 0),
"componente_d": int(consultor.get("bloco_d") or consultor.get("componente_d") or 0),
"ativo": "S" if consultor.get("ativo") else "N",
"anos_atuacao": float(consultor.get("anos_atuacao") or 0),
"json_detalhes": json_str
})
with self.client.get_connection() as conn:
cursor = conn.cursor()
try:
for consultor in consultores:
json_str = json.dumps(consultor, ensure_ascii=False)
cursor.setinputsizes(json_detalhes=oracledb.DB_TYPE_CLOB)
params = {
"id_pessoa": consultor["id_pessoa"],
"nome": consultor["nome"],
"pontuacao_total": consultor["pontuacao_total"],
"componente_a": consultor.get("bloco_a") or consultor.get("componente_a", 0),
"componente_b": consultor.get("bloco_b") or consultor.get("componente_b", 0),
"componente_c": consultor.get("bloco_c") or consultor.get("componente_c", 0),
"componente_d": consultor.get("bloco_d") or consultor.get("componente_d", 0),
"ativo": "S" if consultor.get("ativo") else "N",
"anos_atuacao": consultor.get("anos_atuacao", 0),
"json_detalhes": json_str
}
cursor.execute(merge_sql, params)
cursor.setinputsizes(json_detalhes=oracledb.DB_TYPE_CLOB)
cursor.executemany(insert_sql, batch_data)
conn.commit()
return len(consultores)
except Exception as e:
@@ -372,14 +343,18 @@ class RankingOracleRepository:
"""
Limpa todos os registros da tabela de ranking.
Usar apenas quando for reprocessar do zero.
TRUNCATE é muito mais rápido que DELETE para grandes volumes.
"""
with self.client.get_connection() as conn:
cursor = conn.cursor()
try:
cursor.execute("DELETE FROM TB_RANKING_CONSULTOR")
conn.commit()
cursor.execute("TRUNCATE TABLE TB_RANKING_CONSULTOR")
except Exception as e:
conn.rollback()
raise RuntimeError(f"Erro ao limpar tabela: {e}")
try:
cursor.execute("DELETE FROM TB_RANKING_CONSULTOR")
conn.commit()
except Exception as e2:
conn.rollback()
raise RuntimeError(f"Erro ao limpar tabela: {e2}")
finally:
cursor.close()