feat: adicionar sistema de sugestao de consultores por tema

- Novo endpoint GET /api/v1/consultores/sugerir com busca por tema
- Busca inteligente em areas de avaliacao, conhecimento e pesquisa
- Filtro por consultores ativos e area de avaliacao especifica
- Endpoint GET /api/v1/consultores/areas-avaliacao com lista de areas
- Novo componente SugerirConsultores no frontend
- Botao 'Sugerir por Tema' integrado na interface principal
- Score de match baseado em relevancia do tema e experiencia
This commit is contained in:
Frederico Castro
2025-12-20 07:35:03 -03:00
parent f7557831eb
commit 45ab7412fe
8 changed files with 917 additions and 0 deletions

View File

@@ -24,6 +24,9 @@ from ..schemas.ranking_schema import (
ProcessarRankingResponseSchema,
ConsultaNomeSchema,
PosicaoRankingSchema,
SugestaoConsultorSchema,
SugerirConsultoresResponseSchema,
AreaAvaliacaoSchema,
)
from .dependencies import get_repository, get_ranking_store, get_processar_job, get_es_client
from ...infrastructure.elasticsearch.client import ElasticsearchClient
@@ -410,3 +413,99 @@ async def exportar_ficha_pdf(
"Content-Disposition": f'attachment; filename="{nome_arquivo}"'
}
)
@router.get("/consultores/sugerir", response_model=SugerirConsultoresResponseSchema)
async def sugerir_consultores(
tema: str = Query(..., min_length=2, description="Tema ou assunto para buscar consultores"),
area_avaliacao: Optional[str] = Query(None, description="Filtrar por area de avaliacao especifica"),
apenas_ativos: bool = Query(True, description="Filtrar apenas consultores ativos"),
quantidade: int = Query(20, ge=1, le=100, description="Quantidade maxima de sugestoes"),
es_client: ElasticsearchClient = Depends(get_es_client),
store = Depends(get_ranking_store),
):
try:
resultados = await es_client.sugerir_consultores(
tema=tema,
area_avaliacao=area_avaliacao,
apenas_ativos=apenas_ativos,
size=quantidade
)
consultores = []
for doc in resultados:
id_pessoa = doc.get("id")
nome = doc.get("dadosPessoais", {}).get("nome", "")
score_match = doc.get("_score_match", 0)
areas_avaliacao = set()
areas_conhecimento = set()
linhas_pesquisa = set()
situacao = ""
ies = None
foi_coordenador = False
foi_premiado = False
for atuacao in doc.get("atuacoes", []):
tipo = atuacao.get("tipo", "")
if tipo == "Consultor":
dados = atuacao.get("dadosConsultoria", {})
situacao = dados.get("situacaoConsultoria", "")
if dados.get("ies"):
ies = dados["ies"].get("sigla") or dados["ies"].get("nome")
for area in dados.get("areaConhecimentoPos", []):
if area.get("nome"):
areas_conhecimento.add(area["nome"])
area_aval = area.get("areaAvaliacao", {})
if area_aval and area_aval.get("nome"):
areas_avaliacao.add(area_aval["nome"])
for pesq in dados.get("areaPesquisa", []):
if pesq.get("descricao"):
linhas_pesquisa.add(pesq["descricao"])
elif "Coordenação" in tipo:
foi_coordenador = True
elif "Premiação" in tipo:
foi_premiado = True
posicao_ranking = None
if store.is_ready():
entry = store.get_by_id(id_pessoa)
if entry:
posicao_ranking = entry.posicao
consultores.append(SugestaoConsultorSchema(
id_pessoa=id_pessoa,
nome=nome,
score_match=score_match,
areas_avaliacao=list(areas_avaliacao),
areas_conhecimento=list(areas_conhecimento),
linhas_pesquisa=list(linhas_pesquisa),
situacao=situacao,
ies=ies,
foi_coordenador=foi_coordenador,
foi_premiado=foi_premiado,
))
return SugerirConsultoresResponseSchema(
tema_buscado=tema,
total_encontrados=len(consultores),
consultores=consultores
)
except Exception as e:
raise HTTPException(status_code=500, detail=f"Erro ao sugerir consultores: {str(e)}")
@router.get("/consultores/areas-avaliacao", response_model=List[AreaAvaliacaoSchema])
async def listar_areas_avaliacao(
es_client: ElasticsearchClient = Depends(get_es_client),
):
try:
areas = await es_client.listar_areas_avaliacao()
return [AreaAvaliacaoSchema(**a) for a in areas]
except Exception as e:
raise HTTPException(status_code=500, detail=f"Erro ao listar areas de avaliacao: {str(e)}")