# Arquitetura do FinancePro

## Estado documentado

Esta documentação descreve o código da versão 0.9.6/0.9.6.1 encontrado no repositório. O FinancePro é um monólito PHP com MVC próprio, MySQL e interface renderizada no servidor. As decisões de arquitetura futura estão registadas em `docs/decisions/` e não devem ser confundidas com funcionalidades já implementadas.

## Stack real

- PHP `>= 8.1`, namespaces `App\\` e autoload PSR-4 pelo Composer.
- MySQL 8, acedido por PDO.
- `vlucas/phpdotenv` para configuração e `dompdf/dompdf` para exportação PDF.
- Bootstrap 5, Flaticon e JavaScript sem framework.
- `pdftotext` e Tesseract como processos externos para PDF/OCR.
- Sessões PHP para autenticação e permissões.

## Topologia

```text
Browser
  -> index.php
  -> routes/web.php
  -> App\\Core\\Router
       -> Auth + Permission
       -> Controller
            -> PDO direto, ou
            -> Service -> PDO / parser / exportador
       -> App\\Core\\View
            -> modules/<modulo>/*.php
            -> shared/layouts + shared/partials
  -> HTML/PDF/redirect
```

Não existem API HTTP, container de dependências, ORM, fila, scheduler ativo ou framework externo. Esses itens estão pendentes quando necessários.

## Bootstrap da aplicação

`index.php` ativa a exibição de todos os erros, carrega `vendor/autoload.php`, lê `.env`, inicia a sessão, define timezone, inclui `routes/web.php` e entrega método/URI ao Router. A raiz e `/login` são públicas; qualquer outra URI requer autenticação.

O Router suporta apenas GET e POST e correspondência exata de URI. Não suporta parâmetros, grupos, middlewares declarativos, 405, tratamento global de exceções ou respostas tipadas.

## Fluxo MVC real

1. Uma rota associa método e URI a um callable ou `[Controller, método]`.
2. `Router::dispatch()` verifica a sessão e consulta `Permission::routeRule()`.
3. O controller lê diretamente `$_GET`, `$_POST`, `$_FILES` e `$_SESSION`.
4. O controller consulta PDO diretamente ou chama um Service.
5. `View::render()` aplica `extract()` aos dados, inclui a view de `modules/`, captura HTML e inclui o layout.
6. Escritas terminam normalmente com `redirect()`.

É um MVC parcial: `app/Models/` está vazio, não há Repositories e vários controllers acumulam HTTP, SQL, validação e coordenação de negócio.

## Camadas e responsabilidades atuais

### Core

- `Router`: registo e dispatch de rotas.
- `Database`: ligação PDO singleton por processo.
- `Auth`: login, sessão e logout.
- `Permission` e `ACL`: autorização por módulo/ação.
- `Controller`: helpers de view, autorização e auditoria.
- `View`: composição de view e layout.
- `Audit`: gravação tolerante ao esquema da tabela `auditoria`; não está chamada pelos fluxos atuais.

### Controllers

São 13 controllers. Alguns são finos (`DashboardController`), enquanto outros contêm SQL e regras extensas (`FinanceiroController`, `ReceberController`, `ConciliacaoController`). O padrão alvo para novos trabalhos está em `coding-standards.md` e nos ADRs.

### Services

Existem Services ativos para dashboard, fluxo de caixa, relatórios, exportação PDF, permissões, OCR, regras fiscais, leitura/importação bancária e conciliação. Services ainda acedem PDO diretamente; não há abstração de persistência.

### Views

`modules/` contém páginas e modais PHP. `shared/` contém layouts e partials. Algumas páginas incorporam grande volume de CSS e JavaScript. Escape HTML é feito pelo helper `e()`, mas o uso não é uniforme.

## Contexto SaaS, tenant e empresa ativa

O tenant é `clientes.id`; empresas são unidades operacionais dentro desse tenant. `TenantMiddleware` resolve a identidade do cliente e, em seguida, `CompanyMiddleware` resolve as empresas disponíveis e a seleção operacional da requisição.

Admin, `admin_cliente` e superadmin recebem todas as empresas ativas do cliente atual. Gestor, financeiro, OCR e demais perfis recebem somente empresas atribuídas em `usuario_empresa`. Com várias empresas, a ausência de seleção explícita representa “Todas as Empresas”; a escolha é persistida em `current_company_mode` e `current_company_id`, separada da chave legada usada pelo fluxo de autenticação.

Dashboard, financeiro, bancos, fluxo, OCR, conciliação e relatórios aplicam o conjunto de empresas selecionadas. Escritas exigem uma empresa específica autorizada. Categorias continuam pertencendo ao cliente e são compartilhadas entre suas empresas, conforme o esquema atual.

## Dependências entre domínios

```text
Cliente
  -> Utilizadores -> ACL
  -> Empresas
       -> Categorias (por cliente)
       -> Centros de custo
       -> Contas a pagar / receber
       -> Contas bancárias
            -> Extratos bancários
                 -> Movimentos bancários
                      -> Conciliações -> contas a pagar/receber
       -> Documentos OCR -> regras fiscais

Dashboard / Fluxo de caixa / Relatórios
  -> agregam empresas, contas financeiras, contas bancárias,
     movimentos e conciliações
```

### Área Superadmin SaaS

`/superadmin` é uma fronteira administrativa global separada da navegação e dashboard do tenant. O Router exige o tipo literal `superadmin` antes de resolver contextos tenant/empresa; `admin` mantém somente o bypass ACL de módulos operacionais. `SuperadminController -> SuperadminService -> PDO` administra clientes e planos, enquanto `PlanLimitService` é chamado no fluxo de criação de empresa dentro da transação existente.

## Dependências externas e operacionais

- Composer precisa de `vendor/autoload.php`.
- OCR e PDF dependem da presença dos binários do sistema.
- Bootstrap e ícones dependem de CDNs externas.
- Dompdf gera relatórios na própria requisição.
- Importações e OCR são síncronos; filas e workers estão pendentes.

## Limitações arquiteturais conhecidas

- ACL de rota duplicada entre `routes/web.php` e `Permission::routeRule()`.
- Ausência de tenant scope central, Repositories, DTOs e validação central.
- Dependência ampla de superglobais e métodos estáticos.
- Escritas por GET e ausência de CSRF.
- Ausência de testes automatizados, CI e análise estática.
- Queries repetidas no dashboard/relatórios e listagens sem paginação.
- Tratamento de erro voltado a desenvolvimento.
- Dumps, uploads e artefactos operacionais estão misturados ao repositório.

## Fonte de verdade

- Rotas: `routes/web.php`.
- ACL efetiva: `App\\Core\\Permission` e `App\\Services\\Usuarios\\PermissaoService`.
- Estrutura de dados: `database/financepro.sql` mais `database/migrations/`.
- Módulos executáveis: controllers, services e views efetivamente ligados por rota.
- Estruturas sem rota/controller devem ser marcadas como **Pendente de implementação**.
