Backend: - Adiciona Scroll API no cliente Elasticsearch para processar todos os 300k+ consultores - Cria tabela TB_RANKING_CONSULTOR no Oracle para ranking pré-calculado - Implementa job de processamento com APScheduler (diário às 3h) - Adiciona endpoints: /ranking/paginado, /ranking/status, /ranking/processar, /ranking/estatisticas - Repository Oracle com paginação eficiente via ROW_NUMBER - Status do job com progresso em tempo real (polling) - Leitura automática de LOBs no OracleClient Frontend: - Componente RankingPaginado com paginação completa - Barra de progresso do job em tempo real - Botão para reprocessar ranking - Alternância entre Top N (rápido) e Ranking Completo (300k) Infraestrutura: - Docker compose com depends_on para garantir Oracle disponível - Schema SQL com procedure SP_ATUALIZAR_POSICOES - Índices otimizados para paginação
110 lines
4.7 KiB
SQL
110 lines
4.7 KiB
SQL
-- Schema para Ranking de Consultores CAPES
|
|
-- Versão: 1.0
|
|
-- Data: 2025-01-15
|
|
|
|
-- Tabela principal de ranking
|
|
CREATE TABLE TB_RANKING_CONSULTOR (
|
|
ID_PESSOA NUMBER(10) NOT NULL,
|
|
NOME VARCHAR2(200) NOT NULL,
|
|
POSICAO NUMBER(10),
|
|
PONTUACAO_TOTAL NUMBER(10,2) NOT NULL,
|
|
COMPONENTE_A NUMBER(10,2) DEFAULT 0,
|
|
COMPONENTE_B NUMBER(10,2) DEFAULT 0,
|
|
COMPONENTE_C NUMBER(10,2) DEFAULT 0,
|
|
COMPONENTE_D NUMBER(10,2) DEFAULT 0,
|
|
ATIVO CHAR(1) DEFAULT 'N',
|
|
ANOS_ATUACAO NUMBER(5,1) DEFAULT 0,
|
|
DT_CALCULO TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
JSON_DETALHES CLOB,
|
|
CONSTRAINT PK_RANKING_CONSULTOR PRIMARY KEY (ID_PESSOA),
|
|
CONSTRAINT CHK_ATIVO CHECK (ATIVO IN ('S', 'N'))
|
|
);
|
|
|
|
-- Índices para performance
|
|
CREATE INDEX IDX_RANKING_POSICAO ON TB_RANKING_CONSULTOR(POSICAO);
|
|
CREATE INDEX IDX_RANKING_PONTUACAO ON TB_RANKING_CONSULTOR(PONTUACAO_TOTAL DESC);
|
|
CREATE INDEX IDX_RANKING_ATIVO ON TB_RANKING_CONSULTOR(ATIVO);
|
|
CREATE INDEX IDX_RANKING_DT_CALCULO ON TB_RANKING_CONSULTOR(DT_CALCULO DESC);
|
|
|
|
-- Procedure para atualizar posições após processamento
|
|
CREATE OR REPLACE PROCEDURE SP_ATUALIZAR_POSICOES AS
|
|
BEGIN
|
|
MERGE INTO TB_RANKING_CONSULTOR t
|
|
USING (
|
|
SELECT ID_PESSOA,
|
|
ROW_NUMBER() OVER (ORDER BY PONTUACAO_TOTAL DESC, ID_PESSOA) AS NOVA_POSICAO
|
|
FROM TB_RANKING_CONSULTOR
|
|
) s
|
|
ON (t.ID_PESSOA = s.ID_PESSOA)
|
|
WHEN MATCHED THEN UPDATE SET t.POSICAO = s.NOVA_POSICAO;
|
|
COMMIT;
|
|
END SP_ATUALIZAR_POSICOES;
|
|
/
|
|
|
|
-- View para estatísticas do ranking
|
|
CREATE OR REPLACE VIEW VW_RANKING_ESTATISTICAS AS
|
|
SELECT
|
|
COUNT(*) AS TOTAL_CONSULTORES,
|
|
COUNT(CASE WHEN ATIVO = 'S' THEN 1 END) AS TOTAL_ATIVOS,
|
|
COUNT(CASE WHEN ATIVO = 'N' THEN 1 END) AS TOTAL_INATIVOS,
|
|
MAX(DT_CALCULO) AS ULTIMA_ATUALIZACAO,
|
|
AVG(PONTUACAO_TOTAL) AS PONTUACAO_MEDIA,
|
|
MAX(PONTUACAO_TOTAL) AS PONTUACAO_MAXIMA,
|
|
MIN(PONTUACAO_TOTAL) AS PONTUACAO_MINIMA,
|
|
AVG(COMPONENTE_A) AS MEDIA_COMP_A,
|
|
AVG(COMPONENTE_B) AS MEDIA_COMP_B,
|
|
AVG(COMPONENTE_C) AS MEDIA_COMP_C,
|
|
AVG(COMPONENTE_D) AS MEDIA_COMP_D
|
|
FROM TB_RANKING_CONSULTOR;
|
|
|
|
-- View para distribuição por faixas de pontuação
|
|
CREATE OR REPLACE VIEW VW_RANKING_DISTRIBUICAO AS
|
|
SELECT
|
|
CASE
|
|
WHEN PONTUACAO_TOTAL >= 800 THEN '800+'
|
|
WHEN PONTUACAO_TOTAL >= 600 THEN '600-799'
|
|
WHEN PONTUACAO_TOTAL >= 400 THEN '400-599'
|
|
WHEN PONTUACAO_TOTAL >= 200 THEN '200-399'
|
|
ELSE '0-199'
|
|
END AS FAIXA,
|
|
COUNT(*) AS QUANTIDADE,
|
|
ROUND(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM TB_RANKING_CONSULTOR), 2) AS PERCENTUAL
|
|
FROM TB_RANKING_CONSULTOR
|
|
GROUP BY
|
|
CASE
|
|
WHEN PONTUACAO_TOTAL >= 800 THEN '800+'
|
|
WHEN PONTUACAO_TOTAL >= 600 THEN '600-799'
|
|
WHEN PONTUACAO_TOTAL >= 400 THEN '400-599'
|
|
WHEN PONTUACAO_TOTAL >= 200 THEN '200-399'
|
|
ELSE '0-199'
|
|
END
|
|
ORDER BY
|
|
CASE
|
|
WHEN FAIXA = '800+' THEN 1
|
|
WHEN FAIXA = '600-799' THEN 2
|
|
WHEN FAIXA = '400-599' THEN 3
|
|
WHEN FAIXA = '200-399' THEN 4
|
|
ELSE 5
|
|
END;
|
|
|
|
-- Comentários nas tabelas e colunas
|
|
COMMENT ON TABLE TB_RANKING_CONSULTOR IS 'Tabela de ranking pré-calculado de consultores CAPES';
|
|
COMMENT ON COLUMN TB_RANKING_CONSULTOR.ID_PESSOA IS 'ID da pessoa no sistema AtuaCAPES';
|
|
COMMENT ON COLUMN TB_RANKING_CONSULTOR.NOME IS 'Nome completo do consultor';
|
|
COMMENT ON COLUMN TB_RANKING_CONSULTOR.POSICAO IS 'Posição no ranking (1 = primeiro lugar)';
|
|
COMMENT ON COLUMN TB_RANKING_CONSULTOR.PONTUACAO_TOTAL IS 'Pontuação total calculada (soma dos 4 componentes)';
|
|
COMMENT ON COLUMN TB_RANKING_CONSULTOR.COMPONENTE_A IS 'Pontuação do Componente A (Coordenação CAPES)';
|
|
COMMENT ON COLUMN TB_RANKING_CONSULTOR.COMPONENTE_B IS 'Pontuação do Componente B (Coordenação PPG)';
|
|
COMMENT ON COLUMN TB_RANKING_CONSULTOR.COMPONENTE_C IS 'Pontuação do Componente C (Consultoria)';
|
|
COMMENT ON COLUMN TB_RANKING_CONSULTOR.COMPONENTE_D IS 'Pontuação do Componente D (Premiações)';
|
|
COMMENT ON COLUMN TB_RANKING_CONSULTOR.ATIVO IS 'Indicador se o consultor está ativo (S/N)';
|
|
COMMENT ON COLUMN TB_RANKING_CONSULTOR.ANOS_ATUACAO IS 'Anos de atuação do consultor';
|
|
COMMENT ON COLUMN TB_RANKING_CONSULTOR.DT_CALCULO IS 'Data/hora do último cálculo';
|
|
COMMENT ON COLUMN TB_RANKING_CONSULTOR.JSON_DETALHES IS 'Dados completos do consultor em JSON para exibição';
|
|
|
|
-- Grant de permissões para o usuário de aplicação (ajustar conforme necessário)
|
|
-- GRANT SELECT, INSERT, UPDATE, DELETE ON TB_RANKING_CONSULTOR TO app_user;
|
|
-- GRANT SELECT ON VW_RANKING_ESTATISTICAS TO app_user;
|
|
-- GRANT SELECT ON VW_RANKING_DISTRIBUICAO TO app_user;
|
|
-- GRANT EXECUTE ON SP_ATUALIZAR_POSICOES TO app_user;
|