feat: Implementa duas conexões Oracle simultâneas

- Oracle LOCAL (Docker): Para salvar TB_RANKING_CONSULTOR
- Oracle REMOTO (CAPES): Para ler SUCUPIRA_PAINEL.VM_COORDENADOR
- ConsultorRepositoryImpl usa oracle_remote para buscar PPG
- RankingRepository usa oracle_local para salvar ranking
- ProcessarRankingJob recebe ambos os clientes
- Componente B agora está preparado para funcionar

Nota: Elasticsearch precisa ser acessível da rede CAPES
This commit is contained in:
Frederico Castro
2025-12-10 04:21:17 -03:00
parent f69bcd928c
commit e11cdcd083
5 changed files with 70 additions and 15 deletions

View File

@@ -0,0 +1,20 @@
-- Schema para Coordenações de Programa (PPG)
-- Dados extraídos de SUCUPIRA_PAINEL via MCP
CREATE TABLE TB_COORDENACAO_PROGRAMA (
ID_PESSOA NUMBER(10) NOT NULL,
ID_PROGRAMA_SNPG NUMBER(10) NOT NULL,
NM_PROGRAMA VARCHAR2(500),
CD_PROGRAMA_PPG VARCHAR2(50),
NOTA_PPG VARCHAR2(10),
NM_PROGRAMA_MODALIDADE VARCHAR2(100),
NM_AREA_AVALIACAO VARCHAR2(200),
DT_INICIO_VIGENCIA DATE,
DT_FIM_VIGENCIA DATE,
DH_CARGA TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT PK_COORDENACAO_PROGRAMA PRIMARY KEY (ID_PESSOA, ID_PROGRAMA_SNPG, DT_INICIO_VIGENCIA)
);
CREATE INDEX IDX_COORD_PPG_PESSOA ON TB_COORDENACAO_PROGRAMA(ID_PESSOA);
CREATE INDEX IDX_COORD_PPG_PROGRAMA ON TB_COORDENACAO_PROGRAMA(ID_PROGRAMA_SNPG);
CREATE INDEX IDX_COORD_PPG_ATIVO ON TB_COORDENACAO_PROGRAMA(DT_FIM_VIGENCIA);

View File

@@ -14,13 +14,15 @@ class ProcessarRankingJob:
def __init__( def __init__(
self, self,
es_client: ElasticsearchClient, es_client: ElasticsearchClient,
oracle_client: OracleClient, oracle_remote_client: OracleClient,
oracle_local_client: OracleClient,
ranking_repo: RankingOracleRepository, ranking_repo: RankingOracleRepository,
): ):
self.es_client = es_client self.es_client = es_client
self.oracle_client = oracle_client self.oracle_remote_client = oracle_remote_client
self.oracle_local_client = oracle_local_client
self.ranking_repo = ranking_repo self.ranking_repo = ranking_repo
self.consultor_repo = ConsultorRepositoryImpl(es_client, oracle_client) self.consultor_repo = ConsultorRepositoryImpl(es_client, oracle_remote_client)
self.calculador = CalculadorPontuacao() self.calculador = CalculadorPontuacao()
async def executar(self, limpar_antes: bool = True) -> Dict[str, Any]: async def executar(self, limpar_antes: bool = True) -> Dict[str, Any]:

View File

@@ -4,17 +4,27 @@ from contextlib import asynccontextmanager
from .routes import router from .routes import router
from .config import settings from .config import settings
from .dependencies import es_client, oracle_client, get_processar_job from .dependencies import es_client, oracle_local_client, oracle_remote_client, get_processar_job
from ...application.jobs.scheduler import RankingScheduler from ...application.jobs.scheduler import RankingScheduler
@asynccontextmanager @asynccontextmanager
async def lifespan(app: FastAPI): async def lifespan(app: FastAPI):
await es_client.connect() await es_client.connect()
# Conectar Oracle LOCAL (Docker)
try: try:
oracle_client.connect() oracle_local_client.connect()
print("Oracle LOCAL conectado (Docker)")
except Exception as e: except Exception as e:
print(f"AVISO: Oracle não conectou: {e}. Sistema rodando sem Coordenação PPG.") print(f"AVISO: Oracle LOCAL não conectou: {e}")
# Conectar Oracle REMOTO (CAPES)
try:
oracle_remote_client.connect()
print("Oracle REMOTO conectado (CAPES/SUCUPIRA_PAINEL)")
except Exception as e:
print(f"AVISO: Oracle REMOTO não conectou: {e}. Sistema rodando sem Componente B (PPG).")
scheduler = None scheduler = None
try: try:
@@ -33,8 +43,14 @@ async def lifespan(app: FastAPI):
pass pass
await es_client.close() await es_client.close()
try: try:
oracle_client.close() oracle_local_client.close()
except:
pass
try:
oracle_remote_client.close()
except: except:
pass pass

View File

@@ -11,9 +11,15 @@ class Settings(BaseSettings):
ES_USER: str = "" ES_USER: str = ""
ES_PASSWORD: str = "" ES_PASSWORD: str = ""
ORACLE_USER: str # Oracle LOCAL (Docker) - Para salvar ranking
ORACLE_PASSWORD: str ORACLE_LOCAL_USER: str
ORACLE_DSN: str ORACLE_LOCAL_PASSWORD: str
ORACLE_LOCAL_DSN: str
# Oracle REMOTO (CAPES) - Para ler SUCUPIRA_PAINEL
ORACLE_REMOTE_USER: str
ORACLE_REMOTE_PASSWORD: str
ORACLE_REMOTE_DSN: str
API_HOST: str = "0.0.0.0" API_HOST: str = "0.0.0.0"
API_PORT: int = 8000 API_PORT: int = 8000

View File

@@ -13,8 +13,18 @@ es_client = ElasticsearchClient(
password=settings.ES_PASSWORD password=settings.ES_PASSWORD
) )
oracle_client = OracleClient( # Oracle LOCAL (Docker) - Para salvar ranking
user=settings.ORACLE_USER, password=settings.ORACLE_PASSWORD, dsn=settings.ORACLE_DSN oracle_local_client = OracleClient(
user=settings.ORACLE_LOCAL_USER,
password=settings.ORACLE_LOCAL_PASSWORD,
dsn=settings.ORACLE_LOCAL_DSN
)
# Oracle REMOTO (CAPES) - Para ler SUCUPIRA_PAINEL
oracle_remote_client = OracleClient(
user=settings.ORACLE_REMOTE_USER,
password=settings.ORACLE_REMOTE_PASSWORD,
dsn=settings.ORACLE_REMOTE_DSN
) )
_repository: ConsultorRepositoryImpl = None _repository: ConsultorRepositoryImpl = None
@@ -25,14 +35,14 @@ _processar_job: ProcessarRankingJob = None
def get_repository() -> ConsultorRepositoryImpl: def get_repository() -> ConsultorRepositoryImpl:
global _repository global _repository
if _repository is None: if _repository is None:
_repository = ConsultorRepositoryImpl(es_client=es_client, oracle_client=oracle_client) _repository = ConsultorRepositoryImpl(es_client=es_client, oracle_client=oracle_remote_client)
return _repository return _repository
def get_ranking_repository() -> RankingOracleRepository: def get_ranking_repository() -> RankingOracleRepository:
global _ranking_repository global _ranking_repository
if _ranking_repository is None: if _ranking_repository is None:
_ranking_repository = RankingOracleRepository(oracle_client=oracle_client) _ranking_repository = RankingOracleRepository(oracle_client=oracle_local_client)
return _ranking_repository return _ranking_repository
@@ -41,7 +51,8 @@ def get_processar_job() -> ProcessarRankingJob:
if _processar_job is None: if _processar_job is None:
_processar_job = ProcessarRankingJob( _processar_job = ProcessarRankingJob(
es_client=es_client, es_client=es_client,
oracle_client=oracle_client, oracle_remote_client=oracle_remote_client,
oracle_local_client=oracle_local_client,
ranking_repo=get_ranking_repository() ranking_repo=get_ranking_repository()
) )
return _processar_job return _processar_job