Cerne
Arquitetura — Backend PHP 8.2 · PSR-4 manual (namespace App\ → src/)
Estilo arquitetural
Clean Architecture (adaptada)

Sem framework, sem container de injeção de dependência — as camadas são separadas por pasta em vez de por pacote/módulo.

PHP 8.2 sem framework, dividido em quatro camadas. A dependência flui numa direção só: View chama Domain, Domain chama Infrastructure. Core é transversal e pode ser usado por qualquer camada.

Camadas e fluxo de dependência

flowchart TD
    V["View — Pages & Components"] --> D["Domain — Importers · Reports · Security · Services · Validation"]
    D --> I["Infrastructure — Database · Elasticsearch · External · Storage"]
    C["Core — HookManager · PluginLoader · Anonymizer"] -.-> V
    C -.-> D
    C -.-> I
                    
CamadaPastaResponsabilidade
Coresrc/Core/Infraestrutura transversal: Anonymizer, HookManager, PluginLoader
Domainsrc/Domain/Regras de negócio: Importers (Lattes), Reports (CAPES), Security (Auth, LGPD), Services, Validation
Infrastructuresrc/Infrastructure/Adaptadores externos: Database, Elasticsearch, External (ORCID/OpenAlex/BrCris), Storage
Viewsrc/View/Componentes (Navbar, Footer, HeroSection) e páginas (Auth, Dashboard, Search, Static)

Classes críticas

ClasseCaminhoPapel
AuthManagerDomain/Security/Login, BCrypt, brute-force, sessão segura
LattesImporterDomain/Importers/Importação de XML do Lattes, com validação anti-XXE
ElasticsearchServiceInfrastructure/Elasticsearch/Cliente ES 8.x, com fallback automático para MySQL
LgpdComplianceServiceDomain/Security/DPIA, status de conformidade — exposto em admin.php
ExportServiceDomain/Services/BibTeX, RIS, CSV, JSON, XML

Fluxo de autenticação

flowchart TD
    L["LoginPage: usuário + senha"] --> AM["AuthManager::login()"]
    AM --> CHK{"Senha confere e conta não bloqueada?"}
    CHK -- sim --> SESS["iniciarSessaoSegura(): regenera ID, timeout 2h"]
    SESS --> OK["Redireciona ao painel"]
    CHK -- não --> CNT["Incrementa tentativas em log_login"]
    CNT --> BLK{"5 tentativas?"}
    BLK -- sim --> LOCK["Bloqueio de 15min"]
    BLK -- não --> RETRY["Retorna erro, permite nova tentativa"]
                    
Convenção obrigatória: todo método de serviço retorna ['sucesso' => bool, 'mensagem' => string, 'dados' => mixed]. Prepared statements sempre; nunca concatenar SQL. filter_input() em toda entrada externa.
Essa página foi útil?
Obrigado pelo feedback! 💬 Comentar / relatar problema