diff --git a/backend/sql/schema_ppg.sql b/backend/sql/schema_ppg.sql new file mode 100644 index 0000000..29e2663 --- /dev/null +++ b/backend/sql/schema_ppg.sql @@ -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); diff --git a/backend/src/application/jobs/processar_ranking.py b/backend/src/application/jobs/processar_ranking.py index 7b63c20..b994bde 100644 --- a/backend/src/application/jobs/processar_ranking.py +++ b/backend/src/application/jobs/processar_ranking.py @@ -14,13 +14,15 @@ class ProcessarRankingJob: def __init__( self, es_client: ElasticsearchClient, - oracle_client: OracleClient, + oracle_remote_client: OracleClient, + oracle_local_client: OracleClient, ranking_repo: RankingOracleRepository, ): 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.consultor_repo = ConsultorRepositoryImpl(es_client, oracle_client) + self.consultor_repo = ConsultorRepositoryImpl(es_client, oracle_remote_client) self.calculador = CalculadorPontuacao() async def executar(self, limpar_antes: bool = True) -> Dict[str, Any]: diff --git a/backend/src/interface/api/app.py b/backend/src/interface/api/app.py index 6f8951a..c8bb22b 100644 --- a/backend/src/interface/api/app.py +++ b/backend/src/interface/api/app.py @@ -4,17 +4,27 @@ from contextlib import asynccontextmanager from .routes import router 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 @asynccontextmanager async def lifespan(app: FastAPI): await es_client.connect() + + # Conectar Oracle LOCAL (Docker) try: - oracle_client.connect() + oracle_local_client.connect() + print("Oracle LOCAL conectado (Docker)") 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 try: @@ -33,8 +43,14 @@ async def lifespan(app: FastAPI): pass await es_client.close() + try: - oracle_client.close() + oracle_local_client.close() + except: + pass + + try: + oracle_remote_client.close() except: pass diff --git a/backend/src/interface/api/config.py b/backend/src/interface/api/config.py index a1b1f74..6e952b1 100644 --- a/backend/src/interface/api/config.py +++ b/backend/src/interface/api/config.py @@ -11,9 +11,15 @@ class Settings(BaseSettings): ES_USER: str = "" ES_PASSWORD: str = "" - ORACLE_USER: str - ORACLE_PASSWORD: str - ORACLE_DSN: str + # Oracle LOCAL (Docker) - Para salvar ranking + ORACLE_LOCAL_USER: 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_PORT: int = 8000 diff --git a/backend/src/interface/api/dependencies.py b/backend/src/interface/api/dependencies.py index 0e5a2b9..ab21c1e 100644 --- a/backend/src/interface/api/dependencies.py +++ b/backend/src/interface/api/dependencies.py @@ -13,8 +13,18 @@ es_client = ElasticsearchClient( password=settings.ES_PASSWORD ) -oracle_client = OracleClient( - user=settings.ORACLE_USER, password=settings.ORACLE_PASSWORD, dsn=settings.ORACLE_DSN +# Oracle LOCAL (Docker) - Para salvar ranking +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 @@ -25,14 +35,14 @@ _processar_job: ProcessarRankingJob = None def get_repository() -> ConsultorRepositoryImpl: global _repository 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 def get_ranking_repository() -> RankingOracleRepository: global _ranking_repository if _ranking_repository is None: - _ranking_repository = RankingOracleRepository(oracle_client=oracle_client) + _ranking_repository = RankingOracleRepository(oracle_client=oracle_local_client) return _ranking_repository @@ -41,7 +51,8 @@ def get_processar_job() -> ProcessarRankingJob: if _processar_job is None: _processar_job = ProcessarRankingJob( 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() ) return _processar_job