# Registro de Decisões Arquiteturais

## ADR-001 — PHP sem framework

**Status:** aceito.  
**Decisão:** PHP 8.3, núcleo próprio, Apache e MySQL. Composer somente para autoload e bibliotecas pontuais.  
**Consequência:** controle e compatibilidade elevados; segurança, roteamento, migrations e organização precisam de disciplina e testes próprios.

## ADR-002 — Monólito modular

**Status:** aceito.  
**Decisão:** uma aplicação implantável com módulos de domínio delimitados.  
**Consequência:** operações locais simples e transacionais; limites devem ser aplicados por código e revisão.

## ADR-003 — Multiempresa em banco compartilhado

**Status:** aceito para início.  
**Decisão:** tabelas compartilhadas com `group_id` obrigatório e escopos adicionais.  
**Consequência:** relatórios consolidados eficientes; qualquer esquecimento de filtro é crítico, portanto Policy, contexto e testes são obrigatórios.

## ADR-004 — Ledger de estoque

**Status:** aceito.  
**Decisão:** movimentos imutáveis são a fonte de verdade; saldos são projeções reconciliáveis.  
**Consequência:** maior rastreabilidade e segurança; implementação exige transações e idempotência.

## ADR-005 — Outbox e filas

**Status:** aceito.  
**Decisão:** efeitos externos ocorrem após commit por eventos persistidos.  
**Consequência:** consistência eventual visível e necessidade de monitoramento/reprocessamento.

## ADR-006 — Server-rendered com melhoria progressiva

**Status:** aceito.  
**Decisão:** HTML/PHP, Bootstrap, jQuery e JavaScript, sem SPA/framework JS.  
**Consequência:** menor complexidade de build e operação; componentes dinâmicos devem continuar organizados e acessíveis.

## ADR-007 — Mercado Livre primeiro

**Status:** aceito.  
**Decisão:** primeiro canal externo será Mercado Livre; adapters preservam expansão.  
**Consequência:** validar arquitetura omnichannel sem assumir que APIs futuras são idênticas.

## ADR-008 — NF-e após núcleo comercial/marketplace

**Status:** aceito.  
**Decisão:** estrutura fiscal nasce desde o catálogo, mas autorização NF-e entra após os fluxos centrais.  
**Consequência:** dados fiscais devem existir cedo; regras e NFePHP entram com validação contábil.

## ADR-009 — Módulos por empresa

**Status:** aceito.  
**Decisão:** habilitação por empresa, com dependências e bloqueio de backend.  
**Consequência:** histórico preservado e fluxo cruzado precisa tratar módulo ausente explicitamente.

## ADR-010 — Produção interna e externa no mesmo modelo de rastreabilidade

**Status:** aceito.  
**Decisão:** OP e industrialização externa compartilham catálogo, estoque, lotes, custos e genealogia, mas possuem processos próprios.  
**Consequência:** permite tecido/tinturaria, componentes e outras transformações sem simular como simples transferência.

## ADR-011 — Assistente de suporte com IA do próprio cliente

**Status:** aceito (29/09/2026).  
**Decisão:** o assistente do botão Ajuda usa a conta do cliente na Anthropic ou na OpenAI, com chave cifrada por grupo (AES-256-GCM com a `APP_KEY`) e limite mensal de tokens. Antes de chamar a IA, consulta uma base própria (`assistant_knowledge`): trechos do manual, reindexados quando o arquivo muda, e respostas que o grupo marcou como "Resolveu". A IA recebe só a pergunta, a tela e esses trechos, sem dados operacionais da empresa. A Anthropic é chamada pelo SDK oficial PHP (`anthropic-ai/sdk`, com `guzzlehttp/guzzle` como cliente HTTP). A OpenAI é chamada por HTTP direto (curl).  
**Consequência:** primeira dependência de runtime além da NFePHP. As bibliotecas só são carregadas quando alguém pergunta, sem custo nas demais telas. A publicação passa a exigir `composer install --no-dev -o` quando o `composer.lock` mudar. Consultar dados reais da empresa (ex.: motivo de rejeição de uma nota específica) fica para uma etapa futura, com ferramentas de leitura restritas por permissão.

## ADR-012 — Cobrança por API bancária no lugar de remessa/retorno

**Status:** aceito (01/10/2026).  
**Decisão:** banco que oferece API de cobrança (primeiro o Banco Inter, Boleto com PIX, API Cobrança v3) é integrado por API, sem arquivo CNAB. Credenciais, certificado e chave mTLS ficam cifrados por conta (AES-256-GCM com a `APP_KEY`). A emissão é por parcela (`bank_charges`). O aviso do banco chega numa rota pública `/webhooks/inter/{token}`, com um token aleatório por integração. O aviso só aciona uma consulta: a cobrança é sempre lida na API antes da baixa, cada aviso é registrado uma vez (`bank_charge_events`), e falha de processamento responde 500 e libera o aviso para o banco reenviar, como na integração PIX do NoLet. A rotina `finance:inter-sync` confere as cobranças em aberto para não depender só do aviso. A baixa usa o motivo "Retorno bancário" na conta da integração e separa juros/multa do principal.  
**Consequência:** CNAB continua para bancos sem API. O certificado de webhook (CA do Inter) é opcional: a segurança não depende dele, porque nada é baixado sem consulta à API.

**Revisão (01/10/2026) — vários bancos:**
- O núcleo é neutro quanto ao banco: `BankBillingService`, as tabelas, as telas (**Financeiro > Cobrança por API**), o aviso em `/webhooks/banco/{banco}/{token}`, a baixa e a rotina `finance:bank-sync`.
- O que muda por banco fica em `App\Modules\Finance\Application\{Banco}`:
  - um `BankBillingProvider`, com código, nome, código de compensação, agência padrão, validação do pedido e leitura do aviso;
  - um `BankBillingGateway`, que traduz `BankChargeRequest` e `BankChargeSnapshot` para a API do banco.
- Incluir um banco = criar esses dois e registrar em `BankBillingProviders`, sem mexer no núcleo.
- `bank_billing_integrations.provider` virou VARCHAR. `bank_charges.auto_settle` guarda se o banco confirmou recebimento que baixa sozinho; assim a conferência não depende do código de situação de um banco.
- Compatibilidade: o endereço `/webhooks/inter/{token}`, a tela `/financeiro/inter` (redireciona) e o comando `finance:inter-sync` continuam valendo.
- As credenciais assumem o padrão OAuth `client_credentials` com certificado mTLS, usado pelas APIs de cobrança dos bancos brasileiros. Um banco com outro tipo de credencial exige estender o cadastro da integração.

## Decisões ainda necessárias

1. PDO ou mysqli: recomendação PDO, aguardando confirmação se houver preferência.
2. Estratégia de SKU: único no grupo ou por empresa.
3. Estoque negativo: bloqueado globalmente ou exceção parametrizada.
4. Política de propriedade de catálogo compartilhado.
5. Provedor de armazenamento de objetos no início.
6. Formato/agente de impressão local.
7. Política de arredondamento por unidade e moeda.
8. Cenários fiscais e naturezas com contador.
9. Processo de assinatura/licenciamento dos módulos.
10. Primeira empresa piloto e volume esperado.

