Cerne
Arquitetura — Extração de Dados Os motores que alimentam o Prodmais: Lattes, OpenAlex, ORCID, BrCris

O sistema consome dados de quatro fontes externas, cada uma com um motor (classe) e uma forma de acesso diferente. Nenhuma delas roda "magicamente" — cada uma tem um gatilho específico, documentado abaixo.

Os quatro motores

MotorClasseAcessoO que trazQuando roda
Lattes (CNPq) LattesImporter + LattesParser Upload manual de XML Pesquisador, produções, projetos, orientações Admin faz upload, ou em lote via bin/indexer.php
OpenAlex OpenAlexFetcher REST público (sem chave, e-mail por cortesia) Citações, DOI, conceitos — enriquece a produção já indexada Automático após indexação em lote, com cache local por DOI
ORCID OrcidFetcher REST (Consórcio CAPES-ORCID) Perfil, obras, formação, vínculos empregatícios Sob demanda — não roda em lote automaticamente
BrCris BrCrisIntegration REST institucional Sincronização de dados de programa com a plataforma nacional ⚠️ Implementada, mas ainda não conectada a nenhum endpoint/rota
Gap conhecido: BrCrisIntegration existe e funciona isoladamente (tem syncInstitutionData(), validateRecord(), etc.), mas nenhuma página ou endpoint a instancia hoje. Antes de expor essa integração, alguém precisa decidir o gatilho (manual? agendado?) e criar a rota.

Upload de Lattes — passo a passo

flowchart TD
    ADM["Admin: upload de XML (.xml)"] --> UP["upload_and_index.php"]
    UP --> LI["LattesImporter::importFromXML()"]
    LI --> VAL["Validação anti-XXE: bloqueia DOCTYPE, LIBXML_NONET"]
    VAL --> EXT["extractPesquisadorData / extractProducoes / extractProjetos"]
    EXT --> IDX["indexPesquisador / indexProducoes / indexProjetos"]
    IDX --> ES["Elasticsearch"]
                    

Enriquecimento em lote — OpenAlex

flowchart TD
    BATCH["bin/indexer.php (lote)"] --> LP["LattesParser::parse()"]
    LP --> OA["OpenAlexFetcher::enrichProduction()"]
    OA --> CACHE{"Já existe cache local do DOI?"}
    CACHE -- sim --> ENR["Produção enriquecida"]
    CACHE -- não --> REQ["Chamada à API OpenAlex"] --> SAVE["Salva no cache local"] --> ENR
    ENR --> ES2["Elasticsearch"]
                    

Perfil ORCID — sob demanda

flowchart LR
    REQ2["Requisição sob demanda"] --> OF["OrcidFetcher::getCompleteProfile()"]
    OF --> P["getProfile()"]
    OF --> W["getWorks()"]
    OF --> E["getEducation()"]
    OF --> EMP["getEmployments()"]
    P --> N["normalizeProfileData()"] --> OUT["Perfil normalizado"]
    W --> OUT
    E --> OUT
    EMP --> OUT
                    
Essa página foi útil?
Obrigado pelo feedback! 💬 Comentar / relatar problema