fix: Correções no cálculo de pontuação e extração de dados

- Refatora calculador para agrupar coordenações por tipo com hierarquia
- Corrige contagem de eventos separando SAE de consultorias
- Melhora extração de área de avaliação usando dadosConsultoria
- Ajusta pontuação de premiações conforme regras documentadas
- Usa alias ES em vez de índice específico
This commit is contained in:
Frederico Castro
2025-12-09 19:57:35 -03:00
parent 59ae516ee0
commit e7b34e33a8
3 changed files with 98 additions and 36 deletions

View File

@@ -63,33 +63,51 @@ class ConsultorRepositoryImpl(ConsultorRepository):
if not consultorias:
return None
datas_inicio = [
datas_inicio_consultoria = [
self._parse_date(c.get("inicio"))
for c in consultorias
]
datas_inicio = [d for d in datas_inicio if d]
datas_inicio_consultoria = [d for d in datas_inicio_consultoria if d]
datas_fim = [
self._parse_date(c.get("fim"))
for c in consultorias
]
datas_fim = [d for d in datas_fim if d]
if not datas_inicio:
if not datas_inicio_consultoria:
return None
limite_recente = datetime.now() - timedelta(days=730)
eventos_recentes = sum(1 for d in datas_fim if d >= limite_recente)
eventos_sae = [
a for a in atuacoes if a.get("tipo") == "Evento"
]
areas = list({c.get("areaAvaliacao", "N/A") for c in consultorias if c.get("areaAvaliacao")})
total_eventos = len(eventos_sae)
# considerar últimos 24 meses como janela de atividade
limite_recente = datetime.now() - timedelta(days=730)
eventos_recentes = 0
for ev in eventos_sae:
data_fim = self._parse_date(ev.get("fim")) or self._parse_date(ev.get("inicio"))
if data_fim and data_fim >= limite_recente:
eventos_recentes += 1
dados_consultoria = consultorias[0].get("dadosConsultoria", {}) or {}
areas = []
for c in consultorias:
dc = c.get("dadosConsultoria", {}) or {}
area = dc.get("areaAvaliacao") or c.get("areaAvaliacao")
if area:
areas.append(area)
areas = list(set(areas)) if areas else ["N/A"]
vezes_responsavel = sum(1 for c in consultorias if c.get("responsavel", False))
datas_fim_consultoria = [
self._parse_date(c.get("fim"))
for c in consultorias
]
datas_fim_consultoria = [d for d in datas_fim_consultoria if d]
return Consultoria(
total_eventos=len(consultorias),
total_eventos=total_eventos,
eventos_recentes=eventos_recentes,
primeiro_evento=min(datas_inicio),
ultimo_evento=max(datas_fim) if datas_fim else datetime.now(),
primeiro_evento=min(datas_inicio_consultoria),
ultimo_evento=max(datas_fim_consultoria) if datas_fim_consultoria else datetime.now(),
vezes_responsavel=vezes_responsavel,
areas=areas,
)
@@ -116,25 +134,46 @@ class ConsultorRepositoryImpl(ConsultorRepository):
tipo = self._inferir_tipo_coordenacao(coord)
fim = self._parse_date(coord.get("fim"))
dados_coord = coord.get("dadosCoordenacaoArea", {}) or {}
area_avaliacao_obj = dados_coord.get("areaAvaliacao", {}) or {}
area_avaliacao = area_avaliacao_obj.get("nome") if isinstance(area_avaliacao_obj, dict) else coord.get("areaAvaliacao", "N/A")
if not area_avaliacao:
area_avaliacao = coord.get("descricao", "N/A").split(" - ")[0] if coord.get("descricao") else "N/A"
resultado.append(
CoordenacaoCapes(
tipo=tipo,
area_avaliacao=coord.get("areaAvaliacao", "N/A"),
area_avaliacao=area_avaliacao,
periodo=Periodo(inicio=inicio, fim=fim),
areas_adicionais=[],
ja_coordenou_antes=False,
ja_coordenou_antes=len(resultado) > 0,
)
)
return resultado
def _inferir_tipo_coordenacao(self, coord: Dict[str, Any]) -> str:
nome = coord.get("nome", "").lower()
if "câmara" in nome or "camara" in nome:
dados_coord = coord.get("dadosCoordenacaoArea", {}) or {}
tipo_coord = dados_coord.get("tipo", "").lower()
if "câmara" in tipo_coord or "camara" in tipo_coord:
return "CAM"
elif "mestrado profissional" in nome:
elif "adjunt" in tipo_coord:
if "profissional" in tipo_coord or "mestrado" in tipo_coord:
return "CAJ-MP"
return "CAJ"
elif "coordenador de área" in tipo_coord:
return "CA"
descricao = coord.get("descricao", "").lower()
nome = coord.get("nome", "").lower()
texto = f"{descricao} {nome}"
if "câmara" in texto or "camara" in texto:
return "CAM"
elif "mestrado profissional" in texto:
return "CAJ-MP"
elif "adjunta" in nome:
elif "adjunt" in texto:
return "CAJ"
else:
return "CA"
@@ -148,6 +187,7 @@ class ConsultorRepositoryImpl(ConsultorRepository):
"Premiação Prêmio",
"Avaliação Prêmio",
"Inscrição Prêmio",
"Premiação",
]
]
@@ -169,10 +209,12 @@ class ConsultorRepositoryImpl(ConsultorRepository):
return premiacoes
def _calcular_pontos_premiacao(self, tipo: str) -> int:
# Aproximação das regras (D) seguindo .claude/rules/ranking-consultores-capes.md
mapa = {
"Premiação Prêmio": 60,
"Premiação Prêmio": 150,
"Premiação": 150,
"Avaliação Prêmio": 40,
"Inscrição Prêmio": 20,
"Inscrição Prêmio": 10,
}
return mapa.get(tipo, 0)
@@ -186,9 +228,9 @@ class ConsultorRepositoryImpl(ConsultorRepository):
premiacoes = self._extrair_premiacoes(atuacoes)
coordenacoes_programas_raw = []
if self.oracle_client.is_connected:
if self.oracle_client and self.oracle_client.is_connected:
try:
coordenacoes_programas_raw = self.oracle_client.buscar_coordenacoes_programa(id_pessoa)
coordenacoes_programas_raw = self.oracle_client.buscar_coordenacoes_programa(int(id_pessoa))
except Exception as e:
print(f"AVISO Oracle: erro ao buscar coordenacoes do programa para {id_pessoa}: {e}")
coordenacoes_programas = [