438 lines
14 KiB
Markdown
438 lines
14 KiB
Markdown
# Sistema de Ranking de Consultores CAPES
|
||
|
||
Sistema completo de ranking de consultores CAPES baseado na Minuta Técnica, desenvolvido com arquitetura DDD (Domain-Driven Design).
|
||
|
||
## Arquitetura
|
||
|
||
### Backend (Python + FastAPI + DDD)
|
||
- **Domain Layer**: Entities, Value Objects, Domain Services
|
||
- **Application Layer**: Use Cases, DTOs, Jobs, Mappers, Services
|
||
- **Infrastructure Layer**: Repositories, Elasticsearch Client, Oracle Client, Cache
|
||
- **Interface Layer**: FastAPI Routes, Schemas, Dependencies
|
||
|
||
### Frontend (React + Vite)
|
||
- Interface moderna com componentes reutilizáveis
|
||
- Comparação lado a lado de consultores
|
||
- Sugestão de consultores por tema
|
||
- Exportação de fichas em PDF
|
||
- Integração com API via Axios
|
||
- Design responsivo
|
||
|
||
## Estrutura do Projeto
|
||
|
||
```
|
||
ranking/
|
||
├── backend/
|
||
│ ├── src/
|
||
│ │ ├── domain/
|
||
│ │ │ ├── entities/
|
||
│ │ │ │ ├── consultor.py
|
||
│ │ │ │ └── consultor_ranking.py
|
||
│ │ │ ├── value_objects/
|
||
│ │ │ │ ├── criterios_pontuacao.py
|
||
│ │ │ │ ├── periodo.py
|
||
│ │ │ │ └── pontuacao.py
|
||
│ │ │ ├── repositories/
|
||
│ │ │ │ └── consultor_repository.py
|
||
│ │ │ └── services/
|
||
│ │ │ └── calculador_pontuacao.py
|
||
│ │ ├── application/
|
||
│ │ │ ├── dtos/
|
||
│ │ │ │ └── consultor_dto.py
|
||
│ │ │ ├── jobs/
|
||
│ │ │ │ ├── job_status.py
|
||
│ │ │ │ ├── processar_ranking.py
|
||
│ │ │ │ ├── popular_componente_b_job.py
|
||
│ │ │ │ └── scheduler.py
|
||
│ │ │ ├── mappers/
|
||
│ │ │ │ └── ranking_mapper.py
|
||
│ │ │ ├── services/
|
||
│ │ │ │ └── pdf_service.py
|
||
│ │ │ └── use_cases/
|
||
│ │ │ ├── obter_ranking.py
|
||
│ │ │ └── obter_consultor.py
|
||
│ │ ├── infrastructure/
|
||
│ │ │ ├── cache/
|
||
│ │ │ │ └── ranking_cache.py
|
||
│ │ │ ├── elasticsearch/
|
||
│ │ │ │ └── client.py
|
||
│ │ │ ├── oracle/
|
||
│ │ │ │ ├── client.py
|
||
│ │ │ │ └── ranking_repository.py
|
||
│ │ │ ├── repositories/
|
||
│ │ │ │ └── consultor_repository_impl.py
|
||
│ │ │ └── ranking_store.py
|
||
│ │ └── interface/
|
||
│ │ ├── api/
|
||
│ │ │ ├── app.py
|
||
│ │ │ ├── routes.py
|
||
│ │ │ ├── config.py
|
||
│ │ │ └── dependencies.py
|
||
│ │ └── schemas/
|
||
│ │ ├── consultor_schema.py
|
||
│ │ └── ranking_schema.py
|
||
│ ├── scripts/
|
||
│ ├── sql/
|
||
│ ├── static/
|
||
│ ├── tests/
|
||
│ ├── requirements.txt
|
||
│ ├── Dockerfile
|
||
│ └── .env.example
|
||
│
|
||
├── frontend/
|
||
│ ├── src/
|
||
│ │ ├── components/
|
||
│ │ │ ├── Header.jsx
|
||
│ │ │ ├── ConsultorCard.jsx
|
||
│ │ │ ├── CompararModal.jsx
|
||
│ │ │ ├── FiltroSelos.jsx
|
||
│ │ │ ├── BlocoCriteriosModal.jsx
|
||
│ │ │ ├── RawDataModal.jsx
|
||
│ │ │ └── SugerirConsultores.jsx
|
||
│ │ ├── services/
|
||
│ │ │ └── api.js
|
||
│ │ ├── App.jsx
|
||
│ │ ├── App.css
|
||
│ │ ├── main.jsx
|
||
│ │ └── index.css
|
||
│ ├── package.json
|
||
│ ├── vite.config.js
|
||
│ └── Dockerfile
|
||
│
|
||
├── scripts/
|
||
├── tools/
|
||
├── docker-compose.yml
|
||
├── .env.example
|
||
├── .gitignore
|
||
└── README.md
|
||
```
|
||
|
||
## Critérios de Pontuação
|
||
|
||
> Baseado na Minuta Técnica - Ranking AtuaCAPES
|
||
|
||
### Bloco A: Coordenação CAPES
|
||
|
||
| Código | Função | Base | Tempo | Teto Tempo | Bônus Atualidade | Bônus Retorno | Teto |
|
||
|--------|--------|------|-------|------------|------------------|---------------|------|
|
||
| **CA** | Coordenador de Área | 200 | 10 pts/ano | 100 | +30 | +20 | 450 |
|
||
| **CAJ** | Coordenador Adjunto | 150 | 8 pts/ano | 80 | +20 | +15 | 370 |
|
||
| **CAJ_MP** | Coord. Adjunto MP | 120 | 6 pts/ano | 60 | +15 | +10 | 315 |
|
||
| **CAM** | Câmara Temática | 100 | 5 pts/ano | 50 | +20 | +10 | 280 |
|
||
|
||
**Regras:**
|
||
- Tempo = anos completos × multiplicador (respeitando teto)
|
||
- Bônus Atualidade: apenas se mandato vigente
|
||
- Bônus Retorno: se houve retorno após período de inatividade
|
||
|
||
### Bloco B: Consultoria (máx 230 pts)
|
||
|
||
| Código | Situação | Base | Tempo | Teto Tempo | Bônus Atualidade | Continuidade 8a+ | Retorno | Teto |
|
||
|--------|----------|------|-------|------------|------------------|------------------|---------|------|
|
||
| **CONS_ATIVO** | Ativo | 150 | 5 pts/ano | 50 | +20 | +20 | +15 | 230 |
|
||
| **CONS_HIST** | Histórico | 100 | 5 pts/ano | 50 | - | +20 | +20 | 230 |
|
||
| **CONS_FALECIDO** | Falecido | 100 | 5 pts/ano | 50 | - | +20 | - | 230 |
|
||
|
||
**Regras:**
|
||
- Bônus Continuidade: aplicado se >= 8 anos consecutivos
|
||
- Bônus Retorno: se houve reativação após período de inatividade
|
||
|
||
### Bloco C: Inscrições, Avaliações, Premiações e Orientações
|
||
|
||
#### Inscrições
|
||
|
||
| Código | Descrição | Base | Teto | Bônus Recorrência |
|
||
|--------|-----------|------|------|-------------------|
|
||
| **INSC_AUTOR** | Autoinscrição | 10 | 20 | +2/participação (máx 10) |
|
||
| **INSC_INST_AUTOR** | Inscrição Institucional | 20 | 50 | +5/participação (máx 10) |
|
||
|
||
#### Avaliação de Comissão
|
||
|
||
| Código | Descrição | Base | Teto | Bônus Recorrência |
|
||
|--------|-----------|------|------|-------------------|
|
||
| **AVAL_COMIS_PREMIO** | Avaliador Prêmio | 30 | 60 | +2/ano (máx 15) |
|
||
| **AVAL_COMIS_GP** | Avaliador Grande Prêmio | 40 | 80 | +3/ano (máx 20) |
|
||
|
||
#### Coordenação de Comissão
|
||
|
||
| Código | Descrição | Base | Teto | Bônus Recorrência |
|
||
|--------|-----------|------|------|-------------------|
|
||
| **COORD_COMIS_PREMIO** | Coord. Comissão Prêmio | 40 | 100 | +4/ano (máx 20) |
|
||
| **COORD_COMIS_GP** | Coord. Comissão GP | 50 | 120 | +6/ano (máx 20) |
|
||
|
||
#### Premiações Recebidas (Autor)
|
||
|
||
| Código | Descrição | Base | Teto |
|
||
|--------|-----------|------|------|
|
||
| **PREMIACAO_GP_AUTOR** | Grande Prêmio CAPES (Autor) | 100 | 300 |
|
||
| **PREMIACAO_AUTOR** | Prêmio CAPES de Tese (Autor) | 50 | 150 |
|
||
| **MENCAO_AUTOR** | Menção Honrosa (Autor) | 30 | 90 |
|
||
|
||
#### Orientações e Bancas (apenas selos, sem pontuação direta)
|
||
|
||
| Código | Descrição | Gera Selo |
|
||
|--------|-----------|-----------|
|
||
| **ORIENT_POS_DOC** | Orientação Pós-Doc | Sim |
|
||
| **ORIENT_TESE** | Orientação Tese | Sim |
|
||
| **ORIENT_DISS** | Orientação Dissertação | Sim |
|
||
| **CO_ORIENT_POS_DOC** | Co-Orientação Pós-Doc | Sim |
|
||
| **CO_ORIENT_TESE** | Co-Orientação Tese | Sim |
|
||
| **CO_ORIENT_DISS** | Co-Orientação Dissertação | Sim |
|
||
| **MB_BANCA_POS_DOC** | Banca Pós-Doc | Sim |
|
||
| **MB_BANCA_TESE** | Banca Tese | Sim |
|
||
| **MB_BANCA_DISS** | Banca Dissertação | Sim |
|
||
|
||
> **Nota**: Orientações e bancas de trabalhos premiados geram selos especiais (ex: ORIENT_TESE_PREM)
|
||
|
||
### Bloco D: Bolsas e Participações
|
||
|
||
#### Bolsas CNPq
|
||
|
||
| Código | Descrição | Base | Teto |
|
||
|--------|-----------|------|------|
|
||
| **BOL_BPQ_NIVEL** | Bolsista PQ (qualquer nível) | 30 | 60 |
|
||
|
||
#### Participações
|
||
|
||
| Código | Descrição | Base | Teto | Bônus Recorrência |
|
||
|--------|-----------|------|------|-------------------|
|
||
| **EVENTO** | Participação em Evento | 1 | 5 | +1/participação (máx 10) |
|
||
| **PROJ** | Participação em Projeto | 10 | 30 | +2/participação (máx 10) |
|
||
|
||
### Bloco E: Coordenação PPG
|
||
|
||
| Código | Descrição | Base | Bônus Atualidade | Bônus Retorno | Continuidade 8a+ |
|
||
|--------|-----------|------|------------------|---------------|------------------|
|
||
| **PPG_COORD** | Coordenador de Programa | 0 | +15 | +10 | +15 |
|
||
|
||
> **Nota**: PPG_COORD gera selo visual mas não pontua diretamente (dados incompletos no AtuaCAPES)
|
||
|
||
### Selos Visuais
|
||
|
||
Indicadores visuais que aparecem no card do consultor:
|
||
|
||
| Selo | Descrição |
|
||
|------|-----------|
|
||
| Coord. PPG | Coordenador de Programa |
|
||
| Bolsista PQ | Bolsista de Produtividade CNPq |
|
||
| Grande Prêmio | Autor de Grande Prêmio |
|
||
| Prêmio | Autor de Prêmio |
|
||
| Menção Honrosa | Autor de Menção Honrosa |
|
||
| Orientador Pós-Doc/Tese/Diss | Orientou trabalho |
|
||
| Coorientador Pós-Doc/Tese/Diss | Coorientou trabalho |
|
||
| Banca Pós-Doc/Tese/Diss | Participou de banca |
|
||
| Idioma Bilíngue/Multilíngue | Proficiência em idiomas |
|
||
| Titulação | Mestre/Doutor/Pós-Doutor |
|
||
|
||
### Fórmula de Cálculo
|
||
|
||
```
|
||
Score_Atuação = min(Base + Tempo + Bônus, Teto)
|
||
Score_Total = Bloco_A + Bloco_B + Bloco_C + Bloco_D + Bloco_E
|
||
```
|
||
|
||
## Requisitos
|
||
|
||
- Python 3.11+
|
||
- Node.js 18+
|
||
- Docker e Docker Compose (opcional)
|
||
- Acesso ao Elasticsearch (ATUACAPES)
|
||
- Acesso ao Oracle
|
||
|
||
## Setup Local
|
||
|
||
### Backend
|
||
|
||
1. Entre no diretório do backend:
|
||
```bash
|
||
cd backend
|
||
```
|
||
|
||
2. Crie ambiente virtual e instale dependências:
|
||
```bash
|
||
python -m venv venv
|
||
source venv/bin/activate
|
||
pip install -r requirements.txt
|
||
```
|
||
|
||
3. Configure as variáveis de ambiente:
|
||
```bash
|
||
cp .env.example .env
|
||
```
|
||
|
||
4. Edite `.env` com suas credenciais:
|
||
```
|
||
ES_URL=http://seu-elasticsearch:9200
|
||
ES_INDEX=atuacapes
|
||
ES_USER=seu_usuario_elastic
|
||
ES_PASSWORD=sua_senha_elastic
|
||
ORACLE_LOCAL_USER=seu_usuario
|
||
ORACLE_LOCAL_PASSWORD=sua_senha
|
||
ORACLE_LOCAL_DSN=host:1521/service_name
|
||
```
|
||
|
||
5. Execute o backend:
|
||
```bash
|
||
python -m uvicorn src.interface.api.app:app --host 0.0.0.0 --port 8000 --reload
|
||
```
|
||
|
||
A API estará disponível em `http://localhost:8000`
|
||
|
||
### Frontend
|
||
|
||
1. Entre no diretório do frontend:
|
||
```bash
|
||
cd frontend
|
||
```
|
||
|
||
2. Instale dependências:
|
||
```bash
|
||
npm install
|
||
```
|
||
|
||
3. Execute em modo desenvolvimento:
|
||
```bash
|
||
npm run dev
|
||
```
|
||
|
||
O frontend estará disponível em `http://localhost:5173`
|
||
|
||
## Setup com Docker
|
||
|
||
1. Crie a rede compartilhada (apenas uma vez):
|
||
```bash
|
||
docker network create shared_network
|
||
```
|
||
|
||
2. Configure as variáveis de ambiente:
|
||
```bash
|
||
cp .env.example .env
|
||
```
|
||
|
||
3. Edite `.env` com suas credenciais
|
||
|
||
4. Execute com Docker Compose:
|
||
```bash
|
||
docker-compose up -d
|
||
```
|
||
|
||
- Backend: `http://localhost:8010`
|
||
- Frontend: `http://localhost:5173`
|
||
- Oracle local: `localhost:1521`
|
||
|
||
## Endpoints da API
|
||
|
||
### Ranking
|
||
|
||
| Método | Endpoint | Descrição |
|
||
|--------|----------|-----------|
|
||
| GET | `/api/v1/ranking` | Ranking resumido |
|
||
| GET | `/api/v1/ranking/paginado` | Ranking paginado com detalhes |
|
||
| GET | `/api/v1/ranking/detalhado` | Ranking completo |
|
||
| GET | `/api/v1/ranking/busca?nome=X` | Busca por nome |
|
||
| GET | `/api/v1/ranking/estatisticas` | Estatísticas do ranking |
|
||
| GET | `/api/v1/ranking/status` | Status do job de processamento |
|
||
| GET | `/api/v1/ranking/selos` | Lista de selos disponíveis |
|
||
| GET | `/api/v1/ranking/posicao/{id}` | Posição de um consultor |
|
||
| POST | `/api/v1/ranking/processar` | Dispara reprocessamento |
|
||
|
||
### Consultor
|
||
|
||
| Método | Endpoint | Descrição |
|
||
|--------|----------|-----------|
|
||
| GET | `/api/v1/consultor/{id}` | Detalhes do consultor |
|
||
| GET | `/api/v1/consultor/{id}/raw` | Documento ES completo |
|
||
| GET | `/api/v1/consultor/{id}/lattes` | Dados do Lattes |
|
||
| GET | `/api/v1/consultor/{id}/pdf` | Exportar ficha em PDF |
|
||
|
||
### Sugestões
|
||
|
||
| Método | Endpoint | Descrição |
|
||
|--------|----------|-----------|
|
||
| GET | `/api/v1/consultores/sugerir?tema=X` | Sugerir consultores por tema |
|
||
| GET | `/api/v1/consultores/areas-avaliacao` | Listar áreas de avaliação |
|
||
| POST | `/api/v1/equipe/pdf` | Gerar PDF de equipe |
|
||
|
||
### Utilitários
|
||
|
||
| Método | Endpoint | Descrição |
|
||
|--------|----------|-----------|
|
||
| GET | `/api/v1/health` | Health check |
|
||
| GET | `/` | Info da API |
|
||
|
||
## Fontes de Dados
|
||
|
||
### Elasticsearch (ATUACAPES)
|
||
- Índice: `atuacapes`
|
||
- Campos: `id`, `dadosPessoais`, `atuacoes`, `idiomas`, `formacoes`, `titulacoes`, `identificadorLattes`
|
||
- Tipos de atuação:
|
||
- Coordenação de Área de Avaliação
|
||
- Histórico de Coordenação de Área de Avaliação
|
||
- Consultor
|
||
- Histórico de Consultoria
|
||
- Premiação Prêmio
|
||
- Avaliação Prêmio
|
||
- Inscrição Prêmio
|
||
- Docência
|
||
- Orientação
|
||
- Bolsista CNPq
|
||
|
||
### Oracle Local (Ranking)
|
||
- Tabela: `TB_RANKING_CONSULTOR`
|
||
- Armazena ranking pré-calculado para performance
|
||
- ~350.000 consultores
|
||
|
||
### Oracle CAPES (SUCUPIRA_PAINEL)
|
||
- Tabela: `VM_COORDENADOR`
|
||
- JOIN com: `VM_PROGRAMA_SUCUPIRA`, `VM_AREA_CONHECIMENTO`, `VM_AREA_AVALIACAO`
|
||
|
||
## Documentação da API
|
||
|
||
Após iniciar o backend, acesse:
|
||
- Swagger UI: `http://localhost:8000/docs`
|
||
- ReDoc: `http://localhost:8000/redoc`
|
||
|
||
## Desenvolvimento
|
||
|
||
### Testes
|
||
```bash
|
||
cd backend
|
||
pytest
|
||
```
|
||
|
||
### Linting
|
||
```bash
|
||
black src/
|
||
ruff check src/
|
||
```
|
||
|
||
### Build para Produção
|
||
|
||
**Backend:**
|
||
```bash
|
||
docker build -t ranking-capes-backend ./backend
|
||
```
|
||
|
||
**Frontend:**
|
||
```bash
|
||
cd frontend
|
||
npm run build
|
||
```
|
||
|
||
## Funcionalidades do Frontend
|
||
|
||
- **Ranking Paginado**: Navegação por páginas com 10-500 registros por página
|
||
- **Busca por Nome**: Localiza consultor e navega para sua posição
|
||
- **Comparação**: Selecione 2 consultores para comparar lado a lado
|
||
- **Sugestão por Tema**: Busca consultores por área de conhecimento/pesquisa
|
||
- **Filtro por Selos**: Filtra por tipos de atuação
|
||
- **Exportação PDF**: Gera ficha individual ou de equipe
|
||
- **Detalhes Expandidos**: Card expansível com todas as atuações
|
||
- **Integração Lattes**: Exibe dados do currículo Lattes
|
||
|
||
## Referências
|
||
|
||
- Documentação dos critérios: `.claude/rules/ranking-consultores-capes.md`
|
||
- Queries e mapeamentos: `.claude/rules/ranking-queries-elasticsearch.md`
|
||
- Queries implementadas: `.claude/rules/ranking-queries-implementadas.md`
|