# Relatório de verificação

## Atualização — 01/10/2026 — Pendências da entrega P0/P1

- **E-mail do sistema:** `MailerFactory` passou a usar SMTP pelo `.env` (`MAIL_HOST`, `MAIL_PORT`, `MAIL_ENCRYPTION`, `MAIL_USERNAME`, `MAIL_PASSWORD`). Teste local apontando para uma porta sem servidor: a mensagem ficou FALHOU com o erro real do SMTP. Os avisos de vencimento saem pelo e-mail de envio da empresa quando houver e contam enviados e falhas separadamente (`ServerPaymentReminderSmoke` ajustado e aprovado). Não testado: envio real, que depende das credenciais do servidor de e-mail.
- **Senha no e-mail de boas-vindas:** o e-mail não leva mais a senha. A migration 0090 troca a linha "Senha inicial: …" das mensagens já gravadas por "[removida]", conferida com texto real de várias linhas.
- **Cancelamento de pedido** (`SalesOrderCancellationService`), com transação e trava do pedido. `ServerOrderConfirmationSmoke` subiu para 25 verificações:
  - motivo obrigatório;
  - nota autorizada impede o cancelamento;
  - reserva liberada, título e comissão cancelados;
  - repetir não libera o estoque duas vezes.
- Seletor com pesquisa também em NF-e/NFC-e, PDV, cheques, extrato e filtro da baixa. Quantidade e desconto dos itens de orçamento/pedido aparecem sem zeros à direita (`120`, não `120.000000`). PDV conferido pela leitura do código: já formatava e interpretava o preço corretamente.
- Suíte: 218 testes aprovados.

## Atualização — 01/10/2026 — Correções P0 (cadastro, e-mails, pedidos, painel), rodapé do impresso e melhorias P1

Executado em MySQL 8.0.40 local (banco novo: migrate, seed, `demo:showcase` e `demo:extend`) e servidor PHP local. Nada foi executado no servidor de produção.

- **Rodapé do orçamento/pedido:** o texto da Aparência sai em linha própria, acima de "Documento gerado pelo N4STi Gestão em …". Conferido em PDF gerado pelo Edge headless com o texto de exemplo da Rheys (2 linhas da empresa + frase fixa; "Página 1 de 1" sem quebra).
- **P0 — cliente/fornecedor inativo:** `PartyStatusInputTest` (3). Passeio HTTP: salvar sem o campo "Ativo" grava `inactive`; marcar de novo grava `active`; rótulo "Ativo".
- **P0 — e-mails:** recuperação de senha pelo HTTP local (sem servidor de e-mail do sistema) ficou como `failed` com "Não enviado: servidor de e-mail do sistema não configurado", não mais como enviado. Rótulos ENVIADO, PENDENTE e FALHOU. Não testado: envio SMTP real (depende de conta configurada).
- **P0 — confirmação de pedido:** `SalesOrderConfirmationTest` (6, regra de crédito em centavos). `ServerOrderConfirmationSmoke` (novo, 18 verificações, com rollback): confirmação completa, repetição sem duplicar reserva, título nem comissão, título existente reaproveitado, recusa por estoque, falha do financeiro, crédito bloqueado e isolamento de grupo. Fora do smoke, com commit no banco local descartável: falha real no financeiro (pedido de valor zero) deixou o pedido em rascunho sem movimentos de estoque; dois processos confirmando o mesmo pedido ao mesmo tempo geraram 1 título e 2 movimentos (uma reserva).
- **P0 — painel:** `DashboardStatsTest` (integração): estoque conta só os depósitos da empresa atual; Empresas e Usuários somem sem permissão de ver o cadastro.
- **P1:**
  - `ListingSupportTest` (9): paginação, período em dias de Brasília convertido para UTC, pesquisa por CPF/CNPJ com e sem máscara (inclusive alfanumérico), nome fantasia com recurso à razão social e tipos por extenso;
  - `AuditEventCatalogTest` (5): todo código fixo gravado por `AuditLogger::record()` no sistema tem tradução; campos alterados com valores legíveis; senhas e tokens nunca aparecem;
  - `CatalogSettingsTest` (+3): preço no campo de digitação com as casas da empresa, sem separador de milhar, sem perder casas gravadas a mais;
  - passeio HTTP local: listagem de clientes/fornecedores (filtros, máscara, ATIVO/INATIVO, paginação), pesquisa JSON (`52419873` e `52.419.873/0001` acham o mesmo cadastro), e-mails filtrados por situação e período, auditoria filtrada por período, central de configurações, preço do produto `0,12` (antes `0.1200`) e `data-price` dos itens de orçamento;
  - seletor de cliente com pesquisa testado no Edge headless: digitar `524198` listou "Estilo Vivo · 52.419.873/0001-37", a escolha preencheu o cliente e o campo mostrou o nome fantasia;
  - capturas de tela conferidas: auditoria com detalhes, clientes/fornecedores, e-mails e configurações.
- `demo:extend`: fornecedor inativado pelo formulário e texto no rodapé do orçamento. A segunda execução não repetiu nada.
- Suíte local: 218 testes aprovados, com os de integração. Smokes locais aprovados: confirmação de pedido, negócio, financeiro, comissões, avisos de vencimento e configurações de vendas. `ServerPlatformSmoke` falha no banco local, também sem estas alterações, porque procura o administrador da plataforma de produção.
- Botão **Voltar**: no Edge headless, abrir `/produtos?busca=tec&pagina=1` e ir ao produto na mesma aba deixou o botão apontando para `/produtos?busca=tec&pagina=1`. Verificado só pela leitura do código: a presença do botão nas outras 40 telas de detalhe/formulário e os toasts de endereço, telefone e condições comerciais.

## Atualização — 01/10/2026 — Cobrança por API preparada para vários bancos

- Refatoração (ADR-012, revisão):
  - o núcleo ficou neutro quanto ao banco, com o Inter como adaptador (`InterProvider` + `InterBillingGateway`);
  - migration 0089: `provider` VARCHAR e `bank_charges.auto_settle`, preenchido para os boletos do Inter já recebidos;
  - telas e menu em **Financeiro > Cobrança por API**, aviso em `/webhooks/banco/{banco}/{token}`.
- `BankBillingTest` (novo, 4 testes): divisão principal/juros, registro de bancos e o adaptador do Inter (pedido → corpo da API; situação → recebido com baixa automática; marcado como recebido sem baixa; motivo padrão do cancelamento). `InterChargeRulesTest` ajustado ao pedido neutro. Suíte: 191 testes.
- `ServerInterBillingSmoke`: 32 verificações. O fluxo completo agora passa pelo adaptador real do Inter com a API simulada. Novos casos: aviso de outro banco ignorado e endereço do aviso por banco.
- Migration 0089 aplicada sobre um banco local com dados (boleto pago marcado com `auto_settle`). Banco novo do zero: migrate, seed, demonstração e `demo:extend` com o exemplo do Inter (boleto recebido e baixado, outro cancelado).
- Passeio HTTP local:
  - `/financeiro/inter` redireciona (301) para `/financeiro/cobranca-api`;
  - o aviso funciona pelo endereço novo e pelo antigo (200); banco que não é o da integração recebe 404;
  - tela, título, menu e central de configurações aparecem com os nomes novos;
  - `finance:inter-sync` e `finance:bank-sync` executam.

## Atualização — 01/10/2026 — Banco Inter: cadastro antes da liberação e manual para a IA

- O atalho em Configurações levava a uma tela sem formulário quando a empresa não tinha conta financeira. **Corrigido:**
  - a tela cria a conta "Banco Inter" (agência 0001);
  - a integração pode ser salva aguardando credenciais (migration 0088);
  - só a integração com Client ID, Client Secret, certificado e chave testa a conexão, cadastra o aviso e emite;
  - menu próprio **Financeiro > Banco Inter (Boleto/PIX)**.
- `ServerInterBillingSmoke`: 31 verificações. As 7 novas cobrem a criação da conta, a integração pendente sem emissão nem teste de conexão e o preenchimento parcial sem duplicar a integração. `InterChargeRulesTest`: +1 (credenciais faltantes). Suíte: 188 testes.
- Passeio HTTP local: salvar sem credenciais, selo "aguardando credenciais" com a lista do que falta, item de menu ativo e status na central de configurações.
- Manual reescrito em subtítulos (integrar, cadastro no sistema, emitir, baixa automática, recorrência do Inter, erros comuns). A busca da IA de suporte foi conferida no MySQL local:
  - "como integrar com o Banco Inter os boletos" e "como faço integração do banco inter" trazem os trechos de integração;
  - "baixa automática do boleto inter não aconteceu" traz o roteiro de conferência em 1º;
  - "boleto recorrente do inter vai dar baixa automática" traz o trecho da recorrência em 2º, dentro dos 5 trechos enviados à IA.

## Atualização — 01/10/2026 — Banco Inter: Boleto com PIX por API

- `InterChargeRulesTest` (novo, 8 testes) cobre:
  - montagem do corpo da emissão: pagador PJ/PF, telefone, multa e juros, limite de dias e recusa de cadastro incompleto e de valor abaixo de R$ 2,50;
  - tradução das situações do Inter e quais delas baixam sozinhas;
  - separação entre principal e juros;
  - leitura da consulta v3 e dos avisos (lista ou objeto).
- Suíte local: 187 testes aprovados.
- `ServerInterBillingSmoke` (novo, 24 verificações, Inter simulado) rodou em MySQL 8.0.40 local, dentro de transação com rollback. Cobre:
  - emissão e guarda de linha digitável, PIX e código de barras na parcela;
  - bloqueio de segundo boleto ativo e recusa de cliente sem endereço;
  - aviso com token desconhecido;
  - falha na consulta: devolve erro e libera o aviso para reenvio;
  - baixa com juros separados, na conta e na data do recebimento;
  - aviso repetido sem segunda baixa e cobrança de fora do sistema;
  - isolamento por grupo, cancelamento, reemissão e PDF.
- Passeio HTTP local, logado como demo:
  - a tela Banco Inter (API) mostra o endereço do aviso, e o título mostra o boleto recebido via PIX e o cancelado;
  - rota do aviso: 404 com token desconhecido; 200 para cobrança de fora do sistema e para aviso repetido;
  - a emissão com o certificado fictício da demo é recusada com mensagem na tela e fica como "Falha na emissão". Isso confirma que o certificado é enviado ao Inter.
- Demonstração: passo `interBilling` no `demo:extend` (idempotente, conferido rodando duas vezes).
- **Não homologado:** ainda não houve emissão real no sandbox nem em produção do Inter. A integração da Pro Redes aguarda a liberação no banco. Falta testar com Client ID, Client Secret e certificado reais: conexão, cadastro do aviso, emissão, PDF, pagamento no sandbox e baixa automática.

## Atualização — 01/10/2026 — Testes de NF-e/NFC-e, numeração, calendário e NFC-e ao consumidor

- Pro Redes (servidor, homologação SEFAZ-SP):
  - status do serviço NF-e (modelo 55) e NFC-e (modelo 65): **107 — Serviço em Operação** nos dois, com o CSC cadastrado;
  - emissão de NFC-e de teste (consumidor não identificado, dinheiro R$ 10,00): **245 — CNPJ Emitente não cadastrado**. A comunicação e o certificado funcionam; falta o credenciamento da empresa para NFC-e no ambiente de homologação da SEFAZ-SP. **NFC-e não homologada.**
  - nota, produto de teste e o cliente "Consumidor final" criados no teste foram apagados; próximo número da NFC-e voltou a 1.
- O teste revelou que a NFC-e exigia cliente com CPF/CNPJ e endereço. **Corrigido:** sem cliente, a NFC-e vai sem destinatário (prévia do XML local conferida: sem `<dest>`, `idDest` 1, `indFinal` 1, `tPag` 01).
- `NfceConsumerTest` (3) e `testModeloDaNotaPelaChave`; suíte com 179 testes aprovados. `ServerPosSmoke` aprovado no servidor (o PDV passou a usar o mesmo serviço do consumidor final).
- Empresa: botões Testar NF-e / NFC-e / NFS-e só com certificado (NFC-e só com CSC); próximo número da NF-e e da NFC-e editável. Configurações mostram os ambientes da NF-e/NFC-e e da NFS-e separados e a numeração.
- Calendário dos campos de data conferido por captura nos temas claro e escuro (popup por cima dos cartões, Hoje/Limpar).
- Regressão local: passeio da demo, roteiros de interface e geral aprovados. Os roteiros que usam o admin local e o rascunho de NFS-e falharam por dados do banco local (admin removido no teste da exclusão de grupo; a NFS-e da demo está autorizada), não por código.

## Atualização — 30/09/2026 — Pedido com produtos e serviços, modais e textos das telas

- A NF-e gerada do pedido levava também os itens de serviço. **Corrigido:** a NF-e/NFC-e leva só os produtos, a NFS-e só os serviços, e um pedido não gera duas NFS-e ativas.
- Roteiro HTTP com pedido misto: **4 verificações aprovadas** (o menu mostra NF-e e NFS-e; a NF-e sem o serviço; a NFS-e só com o serviço; pedido só de produtos não oferece NFS-e).
- Modais:
  - "Enviar para outro e-mail" no padrão do modal do sistema;
  - logo maior;
  - ícone por ação (envelope no envio) e ícone de confirmação no lugar do "?".
- Textos das telas: cerca de 50 introduções e frases de instrução retiradas ou encurtadas em 60 telas.
  - Ficaram as mensagens de lista vazia, o limite do arquivo do logo e as fórmulas de cálculo.
  - Acesso aos menus sem o selo "papel" e sem a frase de instrução.
- Regressão: passeio pelas 89 páginas da demo sem erro, roteiro dos submódulos (7) e 175 testes aprovados.

## Atualização — 30/09/2026 — Submódulos, envio ao contador, mensagens e Suporte de IA

- Migrations `0085` (submódulos desligados por empresa) e `0086` (contador da empresa), com rollback e reaplicação.
- `ServerFeatureGateSmoke` (novo): **8 verificações** com rollback.
  - Frente de caixa desligada bloqueia só o PDV; Pedidos seguem liberados.
  - Módulo desligado bloqueia os submódulos; empresa sem registro de módulos não é bloqueada.
  - Cadastros básicos nunca são bloqueados; a escolha de acessos esconde o que está desligado.
  - Religar devolve o acesso anterior.
- Roteiro HTTP dos submódulos: **7 verificações**. O Administrador Geral desliga a Frente de caixa da demo; o menu, a rota `/pdv` (403) e a escolha de acessos deixam de mostrar o PDV; Pedidos seguem abrindo; religar devolve.
- Envio ao contador: `AccountantPackageTest` (3) e roteiro HTTP com SMTP de teste, **8 verificações** (resumo do mês, menu, ZIP com XML e `resumo.csv`, mês vazio, cadastro do contador, envio com o ZIP anexo).
- Regressão depois da mudança no verificador de permissões: 175 testes, smokes de vendas, PDV, financeiro, expedição, inventário de peças e comissões, e passeio pelas 88 páginas da demo, todos aprovados.
- Suporte de IA: a pergunta "O que é GTIN tributável?" passa a achar o glossário novo como primeiro trecho, e o prompt trata variações de termos como o mesmo assunto.

## Atualização — 30/09/2026 — Produto: obrigatoriedade por módulo

- O cadastro de produto só exige o nome.
  - SKU em branco gera um código interno (PRD-/SERV-); unidade em branco vira UN.
  - Os códigos e a descrição do serviço passam a ser cobrados na emissão da NFS-e; o NCM, na emissão da NF-e.
- `ProductRequirementsTest` (3): pendências para NF-e, NFS-e e marketplace; o SKU interno não serve para marketplace.
- Roteiro HTTP como demo: **8 verificações aprovadas** (mercadoria e serviço só com o nome, SKU e unidade automáticos, quadro "Pronto para uso", formulário sem obrigatoriedades).
- Suíte com 172 testes aprovados; smokes de vendas, configurações de venda, peças e serviço sem estoque aprovados localmente.
- Pendente: o vínculo de anúncio de marketplace ainda não existe. Quando existir, ele usará `ProductRequirements::missingFor('marketplace')` para travar.

## Atualização — 30/09/2026 — Envio das notas por e-mail, filtros e logo no DANFSe

- Migration `0084`, com rollback e reaplicação. Dependências novas: `phpmailer/phpmailer` (SMTP) e `nfephp-org/sped-da` (DANFE/DANFCE em PDF).
- Roteiro HTTP como demo, com servidor SMTP de teste local: **16 verificações aprovadas**.
  - Sem configuração: explica e registra a mensagem com os anexos.
  - Validação dos campos, senha cifrada e e-mail de teste.
  - Envio para os e-mails do cadastro (fiscal e geral) e para e-mails digitados; e-mail inválido é recusado.
  - O servidor recebeu destinatários, cópia oculta, Reply-To e os anexos XML e PDF.
  - Sistema > E-mails mostra o remetente e os anexos; download do anexo; reenvio com anexos.
- PDFs conferidos visualmente: DANFSe com o logo (A4, a partir do XML) e DANFE da NF-e (NFePHP), com logo, código de barras e marca de homologação.
- Filtros de período, situação e modelo: `DocumentListFilterTest` (3) e **8 verificações HTTP** nas listagens de NF-e/NFC-e e NFS-e.
- **Não testado ainda:** envio por um SMTP real. Aguarda a conta de envio da Pro Redes.

## Atualização — 30/09/2026 — NF-e autorizada em homologação pela SEFAZ-SP

- Pro Redes, NF-e modelo 55 de teste (produto de teste, cliente real da base). Cada tentativa revelou um problema real, corrigido no sistema ou no cadastro:
  1. XML inválido: vDesc, vFrete, vSeg e vOutro com 0.00 no item. **Corrigido:** passam a ser omitidos.
  2. **452**: lote assíncrono com uma NF-e. **Corrigido:** envio síncrono, e o XML guardado passa a ser o nfeProc.
  3. **434**: indicativo do intermediador ausente. **Corrigido:** indIntermed 0 quando a presença exige.
  4. **696**: não contribuinte sem consumidor final. **Corrigido:** indFinal 1 automático com indIEDest 9.
  5. **904**: vPag preenchido com "sem pagamento". **Corrigido:** vPag zerado com tPag 90.
  6. **539**: número 1 da série 1 já usado em 2021 por outro sistema. Resolvido no teste com o número 900000; em produção, a numeração deve continuar a do sistema anterior.
  7. **232**: cliente contribuinte (IE ativa em SP) cadastrado sem IE. Resolvido completando o cadastro pela consulta de CNPJ.
  8. **Autorizada**: protocolo 135260008925651, cStat 100.
- Depois da validação, a NF-e de teste e o produto foram apagados, como pedido: a Pro Redes só trabalha com serviços.
- NFC-e **não testada**: a Pro Redes não tem CSC, que é gerado pela empresa no portal da NFC-e da SEFAZ-SP.
- O manual ganhou a seção "Antes da primeira nota fiscal de uma empresa" e a tabela de rejeições, lida também pelo Agente de Suporte.
- **Homologado:** NF-e da Pro Redes na SEFAZ-SP (ambiente de homologação).

## Atualização — 30/09/2026 — NFS-e autorizada em homologação pela prefeitura de Americana

- Pro Redes, homologação (`tpAmb` 2), sistema próprio de Americana no leiaute nacional:
  1. **X345**: inscrição municipal não vinculada ao CNPJ. A inscrição cadastrada estava errada; a correta (73856) veio de uma NFS-e real da empresa.
  2. **X141** sem inscrição: ela é obrigatória.
  3. **L2124**: dados de IBS/CBS obrigatórios, também para o Simples.
  4. **Autorizada**: NFS-e nº 1, situação 100, com cTribNac 140101, cTribMun 078, NBS 115022000, CST 000, cClassTrib 000001 e cIndOp 050101.
- A prefeitura calculou IBS 0,10% e CBS 0,90% sobre a base.
- A chave vem com o prefixo `NFS`; o sistema grava só os 50 dígitos.
- O PDF do DANFSe não existe no Ambiente Nacional para nota gerada pelo município (HTTP 404). O DANFSe passou a ser montado a partir do XML autorizado.
- Testes novos: `NfseDanfseDataTest` (2), chave com prefixo e código municipal na DPS validado no XSD. Suíte com 160 testes aprovados.
- **Homologado:** NFS-e da Pro Redes em Americana (ambiente de homologação da prefeitura).
- A NFS-e da Pro Redes foi passada para **Produção** (ambiente próprio da NFS-e, migration `0083`); a NF-e continua em homologação. No teste de comunicação em produção, o sistema da prefeitura aceitou o certificado. A primeira nota real é a próxima validação.

## Atualização — 30/09/2026 — Verificador de normas fiscais e NFS-e por município

- Migration `0082`, com rollback e reaplicação.
- `FiscalNormWatcherTest` (5 testes): leitura das notas técnicas do Portal da NF-e e dos arquivos da NFS-e, datas, número da nota para reconhecer versões e chave por versão.
- Execução real contra os portais oficiais:
  - NF-e/NFC-e: 313 notas técnicas lidas. O que foi publicado antes de 2026 entrou como linha de base; ficaram 15 pendentes, a versão mais recente de cada nota;
  - NFS-e: 17 documentos, 13 pendentes;
  - a segunda execução não registra nada novo.
- Roteiro HTTP do Administrador Geral: **5 verificações aprovadas** (aviso na área Sistema, página, versões substituídas, marcar como analisado, bloqueio sem login).
- NFS-e: o convênio de Americana/SP devolve `aderenteEmissorNacional = 0`, então a DPS vai ao sistema da prefeitura (`api/adn/dps/recepcao`), no leiaute nacional.
  - O servidor de homologação da prefeitura aceitou o certificado da Pro Redes: um GET recebeu "método não suportado", sem envio de documento.
  - 2 testes novos de roteamento.
- Verificação da Pro Redes **sem gravar nem enviar**, com os dados reais do produto e do cliente do pedido 20: nenhuma pendência na pré-validação, tomador com endereço completo e DPS assinada válida no XSD, com a assinatura conferida.
- Produto: a troca de tipo para Serviço é recusada quando o item tem saldo em estoque.
- Consulta de CNPJ: a inscrição estadual vem do CNPJ.ws e a consulta com CPF é recusada. Testado no Chrome sem interface com o `br-fields.js` real.

## Atualização — 30/09/2026 — NFS-e pelo Emissor Nacional

- Migration `0081`, com rollback e reaplicação.
- `NfseDpsBuilderTest` (11 testes), com DPS e pedido de cancelamento validados contra o **XSD oficial 1.01** (pacote de 09/02/2026):
  - Simples (ME/EPP), excesso de sublimite e regime normal com retenções e desconto;
  - tomador pessoa física sem endereço;
  - grupo IBS/CBS;
  - identificador da DPS com 45 posições;
  - DPS assinada com certificado gerado no teste: continua válida no XSD e a assinatura confere;
  - empacotamento gzip/base64 e três formatos de mensagem de rejeição.
- `NfsePreflightTest` (5 testes): pendências explicadas, código com pontuação aceito e IBS/CBS exigido a partir de 01/01/2027.
- Roteiro HTTP como demo: **10 verificações aprovadas**:
  - tela, prévia da DPS e prévia validada no XSD;
  - transmissão sem certificado explica a pendência e não reserva número;
  - DANFSe antes da autorização;
  - campos da empresa e teste da NFS-e Nacional.
- Corrigido: os campos de NFC-e e NFS-e estavam dentro do formulário do certificado. Ao salvar os dados fiscais, a série da NFC-e e a da NFS-e voltavam para 1.
- Achado no XSD oficial: o padrão da série da DPS usa `^` e `$`, que em XSD são literais. Só a nossa cópia de validação foi ajustada, com comentário.
- **Não testado ainda:** transmissão real. As APIs exigem o certificado do contribuinte na conexão, e o da Pro Redes só existe no servidor. É o próximo passo, pelo botão **Testar NFS-e Nacional** e por uma nota de teste da Pro Redes.
- Demonstração: `demo:extend` configura a empresa demo e cria uma NFS-e modelo em rascunho, com IBS/CBS. A segunda execução não repete nada.

## Atualização — 30/09/2026 — Teste de comunicação com a SEFAZ

- Novo botão **Testar comunicação com a SEFAZ** na tela da empresa: consulta o status do serviço (`NfeStatusServico`) sem emitir documento.
- Executado em produção para a Pro Redes (homologação, SP), com o certificado A1 cadastrado: **107 — Serviço em Operação**. Ficam confirmados o certificado, a senha e a comunicação com a SEFAZ-SP.
- Ainda não houve emissão de NF-e em homologação. Isso é um passo separado, que usa a numeração de homologação da série 1.
- A empresa de demonstração não tem certificado. Nela o botão explica que é preciso enviar o certificado antes.

## Atualização — 30/09/2026 — Bloco 9 concluído, CPF/CNPJ com dígito verificador e CNPJ alfanumérico

- Migration `0080`, com rollback e reaplicação.
- `TaxDocumentTest` (4 testes):
  - o exemplo oficial da Receita de CNPJ alfanumérico (12.ABC.345/01DE-35) confere;
  - CNPJ numérico, CPF, dígitos errados, repetidos, tamanho e letra no CPF;
  - limpeza e formatação.
- `PieceReviewTest` (4 testes): nota por 100 m², por 100 m ou só pontos; limites de 1ª e 2ª qualidade.
- `ServerPieceCountSmoke` (novo): **22 verificações** com rollback:
  - peça lida pelo número do terceiro e pelo número N4STi sem zeros;
  - leitura confere, repetida é recusada;
  - classificações fora do filtro, outro depósito e desconhecida;
  - esperadas, conferidas e faltantes;
  - aplicação só depois de encerrar: baixa a não encontrada, mantém a lida e deixa a reservada para resolver; não aplica duas vezes;
  - revisão em 1ª qualidade (1,11 por 100 m²) e reprovada (44,44), com bloqueio;
  - expedição recusa a peça reprovada lida pelo número do terceiro;
  - nova revisão em 2ª qualidade libera a peça; histórico; isolamento por empresa.
- Roteiro HTTP como demo: **16 verificações aprovadas**:
  - menu, contagem aberta, lida, encerrada com faltantes e cancelada;
  - revisão gravada e configurações;
  - filtro de terceiros;
  - CNPJ e CPF com dígito errado recusados e CNPJ alfanumérico aceito;
  - expedição, impressoras e configurações sem menção ao ERP anterior.
- Testes antigos com CPF e CNPJ inventados passaram a usar documentos válidos, porque a pré-validação da NF-e agora confere os dígitos.
- Referências ao ERP anterior retiradas do sistema: telas, endereços (`/etiquetas/imprimir`, `/cupom/imprimir`) e comentários. Fica só o cabeçalho técnico do serviço de impressão local, necessário para a comunicação.
- Demonstração: comando `demo:extend` idempotente, com os exemplos desta rodada. A segunda execução não repete nada.

## Atualização — 29/09/2026 — Cadastros e perfis sempre presentes; empresa de demonstração

- Cadastros padrão e os 13 perfis fiscais passam a ser criados em toda empresa, sem botão. Nas empresas existentes, eles entram pelo comando `starter:apply` na publicação.
- **Empresa de demonstração** (`demo:showcase`): todo o conteúdo é lançado pelas próprias rotas, com a sessão do usuário demo. Permissões, CSRF, validações e regras de estoque, financeiro e fiscal rodam como no uso real.
  - Ensaio completo com `--ensaio` (tudo desfeito no fim) e depois a gravação real no banco local.
  - Passeio autenticado como demo: **82 telas e detalhes** abertos, todos com HTTP 200 e sem aviso de PHP.
- **Erro encontrado e corrigido:** a Agenda comercial e a Qualidade da produção consultavam a tabela inexistente `group_users` e davam erro 500. Agora usam `group_memberships`.
- `ShowcaseDocumentsTest`: o gerador de CNPJ e CPF fictícios produz dígitos verificadores corretos (00.000.000/0001-91 e 111.444.777-35).
- Smokes locais: 12 aprovados. Três não se aplicam ao banco local:
  - `ServerFiscalPreviewSmoke` recebe o número de uma nota;
  - `ServerPlatformSmoke` exige o administrador da plataforma de produção;
  - `ServerChequeSmoke` compara a data do PHP com a do MySQL e falha perto da meia-noite UTC. É uma instabilidade de horário anterior a esta rodada.

## Atualização — 29/09/2026 — Editor de impressos com posição livre

- Layout em grade de 12 colunas por linhas (`pos` x/y/w/h), sem migration. O JSON salvo muda de formato e os formatos antigos são convertidos na leitura:
  - lista com largura (editor anterior), com o cabeçalho único dividido em logo, dados da empresa, título e linha;
  - grade antiga x/y.
- `PrintLayoutTest` (8 testes) cobre:
  - conversão da lista com cabeçalho, mantendo lado a lado e totais à direita;
  - grade antiga ordenada pela posição;
  - limites (largura mínima e borda direita) e opções limpas;
  - sobreposição resolvida sem mover blocos ocultos;
  - padrões estáveis dos quatro tipos;
  - etiqueta dentro das 12 linhas;
  - faixas de impressão e estilo por faixa.
- **Impressão em várias páginas (PDF do Chrome headless, 90 itens):**
  - 4 páginas, com "Documento gerado pelo N4STi Gestão em …" e "Página X de 4" no rodapé de cada uma, e o cabeçalho da tabela repetido;
  - a primeira versão deixava os Totais sobre os itens na última página, porque o Chrome não refaz a grade entre páginas. Foi corrigido imprimindo em faixas horizontais, cada uma com uma linha de grade.
- **Arrasto na prévia (eventos de ponteiro simulados no Chrome):**
  - Totais movido de x=6 para x=0;
  - Cliente redimensionado de 6×5 para 3×7 pela alça;
  - clique sem movimento seleciona o bloco.
- Roteiro HTTP: **8 verificações aprovadas**:
  - editor dos quatro tipos sem Subir/Descer;
  - layout antigo gravado no banco convertido no impresso real;
  - salvar posições;
  - impresso com totais à esquerda, texto livre ao lado e rodapé personalizado;
  - cupom em faixas.

## Atualização — 29/09/2026 — Cadastros padrão e perfis fiscais sugeridos

- `StarterDataTest` (4 testes) confere:
  - unidades com código válido e únicas;
  - formas de cobrança com tipo e modo existentes;
  - prazos crescentes;
  - plano de contas com o pai antes do filho.
- `FiscalProfileTemplatesTest` (5 testes) confere:
  - CSOSN válido no Simples e CST válido no regime normal;
  - PIS/COFINS de 0,65%/3% no Presumido e 1,65%/7,6% no Real;
  - CFOP coerente com entrada ou saída;
  - o CRT decide entre CSOSN e CST (CRT 2 usa CST).
- Comando `starter:apply` no banco local: incluiu 50 unidades, 6 formas, 14 condições e 39 contas no grupo demonstração; na segunda execução, nada foi incluído.
- Roteiro HTTP: **9 verificações aprovadas**:
  - botão de perfis sugeridos; 13 perfis criados, com CSOSN 102 na empresa do Simples; reaplicar não duplica; remessa para industrialização com CFOP 5901/6901;
  - painel do Administrador Geral com botão, modal, tema e máscaras;
  - aplicar em grupo existente mostra o resultado;
  - grupo novo já nasce com 59 unidades, 8 formas, 14 condições e 39 contas.
- **Erro encontrado e corrigido no teste:** a primeira versão tratava `simples_nacional` como regime normal e criava CST numa empresa do Simples. A escolha passou a usar o CRT.
- Análise das notas do TIMASY e do legado em `docs/ANALISE_PERFIS_FISCAIS.md`.

## Atualização — 29/09/2026 — Modal padrão, CEP, CNPJ, telefone e ajustes

- Máscaras e consultas testadas no Chrome headless, com as APIs públicas reais:
  - CEP 01310-100 preencheu Avenida Paulista, Bela Vista, São Paulo e SP;
  - CNPJ 00.000.000/0001-91 preencheu razão social, fantasia e telefone, com a situação ATIVA;
  - telefones (11) 98765-4321, (11) 3322-4455 e +55 (11) 98765-4321; estrangeiro +1 415 555 0100 ficou sem máscara;
  - CPF 123.456.789-01.
- Roteiro HTTP: **8 verificações aprovadas**:
  - assistente: sem a frase das chaves; "Testar conexão" sempre habilitado; teste com a chave digitada sem salvar nem ligar a IA; sem chave, pede a chave;
  - menu ativo em Regras fiscais e Apuração de impostos;
  - clientes, novo cliente e empresa com CEP primeiro, máscaras e consulta de CNPJ.
- Diálogos nativos do navegador: o único `confirm()` e o aviso de saída do editor de impressos foram trocados pelo modal do sistema. O modal ganhou ícone, título, texto e dois botões do mesmo tamanho, conferido nos dois temas.
- O indicador "carregando" agora afeta só o botão clicado, e não todos os botões do formulário.

## Atualização — 29/09/2026 — Assistente de suporte com IA

- Migration `0079` com rollback e reaplicação. Dependências novas: `anthropic-ai/sdk` 0.52 e `guzzlehttp/guzzle` 7 (ADR-011).
- `AssistantTextTest` (novo, 8 testes) cobre:
  - normalização de acentos com tabela fixa (o `iconv` dá resultados diferentes no Windows e no Linux);
  - palavras significativas e semelhança entre perguntas, incluindo recusar perguntas diferentes;
  - consulta FULLTEXT sem operadores do usuário;
  - divisão do manual por título e de trechos longos;
  - resumo.
- Roteiro HTTP no banco local: **20 verificações aprovadas**:
  - gaveta presente e resposta pelo manual sem IA;
  - manual indexado e item na central de configurações;
  - ativar sem chave recusado;
  - chave salva cifrada, com só os quatro últimos caracteres na tela;
  - chave falsa: a API real da Anthropic respondeu 401 e o usuário recebe mensagem amigável; OpenAI com chave falsa também (teste direto);
  - "Resolveu" vira conhecimento e pergunta parecida é respondida pela base, sem IA;
  - "Não resolveu" tira a resposta de uso, e ela não é reaproveitada;
  - limite mensal atingido volta ao manual, com o uso na tela;
  - remoção de resposta aprendida;
  - avaliação de mensagem alheia recusada;
  - operador sem permissão não configura (403), mas pergunta normalmente.
- Gaveta conferida por captura de tela nos temas claro e escuro.
- **Não testado:** resposta real da IA. Depende de uma chave válida do cliente; basta ativar em Configurações e usar **Testar conexão**.

## Atualização — 29/09/2026 — Acesso aos menus por usuário

- Sem migration: as escolhas usam as sobrescritas individuais de permissão que já existiam.
- PHPUnit: **102 testes**. `MenuAccessTest` (novo) confere três pontos:
  - todo item do menu aponta para uma permissão de consulta existente;
  - as chaves são únicas;
  - nenhum prefixo engloba outro.
- Roteiro HTTP no banco local: **14 verificações aprovadas**:
  - operador criado com papel e empresa, e quadro exibido com o estado do papel;
  - tirar Pedidos revoga consulta e alteração;
  - o menu do operador some e `/pedidos` responde 403;
  - religar remove a revogação e `/pedidos` volta a 200;
  - com um papel sem Auditoria, marcar o item concede só a consulta, e o operador abre a tela;
  - o administrador não consegue tirar de si o acesso a Usuários e vê a mensagem.

## Atualização — 29/09/2026 — Ajustes de uso: datas, impressos, módulos, serviço e tema

- PHPUnit: **99 testes**. `DateFormatTest` (novo) cobre a conversão de UTC para o horário de Brasília, a data pura sem conversão e os valores vazios.
- Roteiro HTTP no banco local: **11 verificações aprovadas**:
  - serviço salvo sem unidade, recebendo `UN`, e mercadoria sem unidade recusada;
  - administrador do grupo não vê módulos em Dados da empresa e recebe 403 em `/sistema`;
  - Administrador Geral vê os módulos, desliga um e religa, voltando ao estado inicial;
  - impresso do pedido com a barra padrão (Imprimir e Fechar do mesmo tamanho).
- O salvamento de módulos passou a rodar em transação, com `group_id` no filtro.
- Datas conferidas em pedidos, auditoria, PDV, caixa e expedição.
- Tema escuro com o fundo do NoLet e sem a sombra do menu no tema claro. Conferido por captura de tela.

## Atualização — 29/09/2026 — Editor de impressos, central de configurações e menu

- Migration `0078` com rollback e reaplicação. Ela corrige o banco, que só aceitava layout de orçamento e pedido: salvar cupom ou etiqueta falhava. PHPUnit: **95 testes, 1303 asserções**.
- `PrintLayoutTest` (novo) cobre:
  - conversão do layout antigo (grade x/y) para a ordem da folha;
  - cabeçalho inserido;
  - largura ajustada;
  - obrigatórios sempre visíveis;
  - opções limpas, sem bloco repetido ou desconhecido;
  - padrões dos quatro tipos;
  - papel do cupom e tamanho da etiqueta.
- Smokes de negócio, PDV e peças aprovados.
- Roteiro HTTP: **11 verificações aprovadas**:
  - editor dos quatro tipos;
  - salvar o layout do pedido e o impresso real do pedido usando cor, texto livre, rodapé, sem SKU e sem logo;
  - restaurar padrão;
  - cupom real em 58 mm com mensagem e sem impressão automática;
  - etiqueta real;
  - central de configurações;
  - impressoras.
- Prévias conferidas por captura de tela (pedido A4, cupom e etiqueta); central e editor conferidos no tema claro.
- **Menu:** voltou a abrir por clique, em sanfona (uma seção por vez, com animação), com a seção atual já aberta. Conferido por captura.
- **PWA:** o manifesto `site.webmanifest` e os ícones de instalação vinham da versão inicial do projeto. Foram removidos do repositório e do servidor.
## Atualização — 29/09/2026 — Expedição por cliente com leitura de peças

- Migration `0077` com rollback e reaplicação. PHPUnit: 91 testes, sem regressão.
- `tests/ServerDispatchSmoke.php` (novo): **24 verificações aprovadas**, com rollback. Cobre:
  - reserva de 130 m em peças;
  - recusa de pedido de outro cliente, de outro depósito e em duas expedições;
  - leitura com distribuição entre os pedidos e excesso sinalizado;
  - recusa de peça repetida, de outro produto e de código desconhecido;
  - quantidade digitada só para itens sem rastreio;
  - saldos e totais (peças, metros, peso);
  - retirar e ler de novo;
  - peso líquido maior que o bruto recusado;
  - uma remessa por pedido com volumes e pesos das peças;
  - estoque e saldo de cada peça zerados, com a reserva de outro cliente intacta;
  - fechada não aceita leitura;
  - cancelamento devolve o pedido à fila;
  - isolamento.
- **Defeito encontrado e corrigido no smoke:** as reservas de pedidos diferentes compartilham peças. Baixar a peça antes de liberar a reserva do outro pedido falhava. O fechamento passou a liberar primeiro as reservas de todos os pedidos e só depois baixar as peças.
- Roteiro HTTP: **10 verificações aprovadas**:
  - botão;
  - escolha do cliente com os pedidos;
  - criação;
  - fila sem os pedidos;
  - leitura com mensagem;
  - leitura repetida;
  - impressão;
  - fechamento com 2 remessas;
  - peças zeradas;
  - tela despachada.
- **Não executado:** leitura com coletor físico (entra com o HUB).
## Atualização — 29/09/2026 — Avisos de vencimento por e-mail

- Migration `0076` com rollback e reaplicação. PHPUnit: **91 testes, 1242 asserções**. `PaymentReminderRulesTest` (novo) cobre prazos e marcadores.
- `tests/ServerPaymentReminderSmoke.php` (novo): **14 verificações aprovadas**, com rollback e e-mails `.test` pelo LogMailer. Cobre:
  - normalização e limites dos prazos;
  - prévia só de contas a receber em aberto nos prazos;
  - e-mail financeiro com preferência;
  - marcadores preenchidos;
  - envio só para quem tem e-mail, registrado no acompanhamento;
  - segunda execução sem repetir;
  - histórico;
  - título pago fora da lista;
  - rotina ignorando empresa com aviso desligado.
- HTTP:
  - tela;
  - salvar;
  - recusa de prazo inválido na tela;
  - comando `php bin/console finance:reminders` executado.
- **Pendente externo:** envio real depende do SMTP (hoje o sistema grava as mensagens e usa o LogMailer).
## Atualização — 29/09/2026 — Boletos a pagar (código de barras)

- Migration `0075` com rollback e reaplicação. PHPUnit: **88 testes, 1229 asserções**.
- `BoletoCodeTest` (novo) cobre:
  - o par linha digitável/código de barras publicado em boletobancario-codigodebarras.com (confere dígitos, valor e vencimento de 31/12/2007);
  - ida e volta entre código e linha;
  - fator de vencimento após o recomeço de 22/02/2025 e no ciclo antigo;
  - dígito geral e bloco com erro de digitação;
  - arrecadação com módulos 10 e 11;
  - tamanho inválido.
- `tests/ServerPaymentCodeSmoke.php` (novo): **7 verificações aprovadas**:
  - código inválido impede o lançamento;
  - código guardado na parcela;
  - linha reconstruída;
  - avisos de valor e vencimento;
  - remover;
  - isolamento por empresa.
- Roteiro HTTP: **7 verificações aprovadas**:
  - leitura em JSON (válida e inválida);
  - campo no formulário;
  - título lançado com o boleto;
  - card com "Copiar linha";
  - remover e colar de novo com conferência.
## Atualização — 29/09/2026 — Cheques

- Migration `0074` com rollback e reaplicação. PHPUnit: **79 testes, 1203 asserções**. `ChequeCmc7Test` (novo) cobre:
  - leitura do CMC7;
  - dígito divergente sinalizado sem bloquear;
  - CMC7 incompleto.
- `tests/ServerChequeSmoke.php` (novo): **27 verificações aprovadas**, com saldos da carteira e do banco conferidos a cada passo. Cobre:
  - validações;
  - dois cheques quitando o título;
  - valor na carteira;
  - carteira única;
  - resumo;
  - cheque avulso;
  - depósito, recusa de depósito repetido ou na carteira;
  - alínea;
  - devolução, reapresentação, compensação;
  - cobrança com título;
  - repasse pagando o fornecedor;
  - cheque emitido pagando e cancelado com estorno (com e sem título);
  - listas, histórico e isolamento.
- Roteiro HTTP: **13 verificações aprovadas**:
  - lista e menu;
  - formulário;
  - títulos em aberto e leitura do CMC7 (JSON);
  - recebimento quitando título;
  - erro de valor no formulário;
  - seleção em lote;
  - depósito em lote;
  - devolução com alínea;
  - tela com histórico e ações;
  - carteira;
  - aba de emitidos.
- **Não executado:** leitura com leitor de CMC7 físico (entra com o HUB).
## Atualização — 29/09/2026 — Distribuição de DF-e

- Migration `0073` com rollback e reaplicação. PHPUnit: **76 testes, 1173 asserções**.
- `DfeParseTest` (novo) usa respostas `retDistDFeInt` fictícias, compactadas como as da SEFAZ (`tests/Support/DfeResponses.php`), e cobre:
  - resumo;
  - procNFe;
  - evento de cancelamento;
  - resposta vazia;
  - resposta inesperada.
- `tests/ServerDfeSmoke.php` (novo): **20 verificações aprovadas**, com a SEFAZ simulada. Cobre:
  - orientação sem certificado;
  - busca em duas rodadas até o maxNSU;
  - NSU gravado;
  - resumo e XML por chave;
  - pausa de 1 hora sem novidades (sem nova chamada);
  - consumo indevido (656);
  - entrada recusada só com resumo;
  - justificativa da não realizada;
  - ciência com o XML pedido pela chave;
  - entrada na conferência sem duplicar;
  - filtros;
  - cancelamento pelo emitente bloqueando a entrada;
  - ocultar;
  - recusa da SEFAZ informada.
- Roteiro HTTP: **7 verificações aprovadas**:
  - contador na aba;
  - lista com resumo e XML;
  - aviso de certificado ao buscar;
  - dar entrada;
  - filtro de importadas;
  - ocultar.
- **Não executado:** consulta real à SEFAZ e manifestação com o certificado A1 da empresa (homologação externa pendente).
## Atualização — 29/09/2026 — Nota fiscal de entrada

- Migration `0072` com rollback e reaplicação. PHPUnit: **73 testes, 1142 asserções**. `InboundInvoiceTest` (novo) usa um XML fictício em `tests/Fixtures/nfe_entrada.xml` e cobre:
  - cabeçalho, itens, impostos, duplicatas e notas referenciadas;
  - XML inválido;
  - custo com frete/IPI/desconto;
  - fator de embalagem;
  - métodos de custo e markup.
- `tests/ServerInboundInvoiceSmoke.php` (novo): **37 verificações aprovadas**, com rollback. Cobre:
  - recusa de nota de outro destinatário e de chave repetida;
  - fornecedor pelo CNPJ formatado;
  - vínculo pelo código do fornecedor com fator e pelo EAN;
  - pedido pelo `xPed`;
  - pendências e soma das parcelas;
  - média ponderada e preço pelo markup;
  - estoque em unidade de estoque;
  - custo com ICMS-ST;
  - aprendizado do código;
  - baixa parcial do pedido;
  - conta a pagar;
  - uso e consumo sem estoque;
  - lote no endereço;
  - bloqueios de cancelamento, cancelamento com estorno;
  - fornecedor novo com endereço;
  - descarte;
  - isolamento por empresa.
- Demais smokes aprovados (vendas 15, comissões 35, peças 12, fiscal 15, PDV 25, financeiro 17, negócio 23).
- Roteiro HTTP: **14 verificações aprovadas**:
  - menu e área de upload;
  - aviso de outro CNPJ;
  - importação por upload;
  - conferência com pendência;
  - busca de produtos;
  - salvar, pronta para lançar, lançar;
  - estoque +505;
  - tela lançada;
  - download do XML;
  - cancelamento com estorno do estoque;
  - filtro.
- Encontrado e corrigido no smoke: com só o markup preenchido, o preço sugerido não era gravado.
## Atualização — 29/09/2026 — Tipos de pedido e configurações de vendas

- Migration `0071` com rollback e reaplicação. PHPUnit: **63 testes, 1086 asserções**. `SalesSettingsTest` (novo) cobre duplicidade com nome, tipo cobrado e recusa de tipo desconhecido.
- `tests/ServerSalesSettingsSmoke.php` (novo): **15 verificações aprovadas**, com rollback:
  - padrões;
  - recusa de operação fiscal de outra empresa e de observação longa;
  - gravação e isolamento por empresa;
  - operação fiscal por tipo;
  - nome da variante na mensagem;
  - vencimentos previstos pela condição e reais pelo título, e sem vencimentos na amostra;
  - amostra sem comissão e piloto com comissão;
  - realizado da meta sem as amostras.
- Demais smokes (comissões 35, peças 12, fiscal 15, PDV 25, financeiro 17, negócio 23): aprovados.
- Roteiro HTTP: **15 verificações aprovadas**:
  - configurações;
  - observação padrão e tipo no pedido novo;
  - trava de duplicidade e recusa de tipo inválido;
  - amostra confirmada sem título e sem comissão, sem bloco de pagamento, com o pagamento recusado (422);
  - tipo na lista;
  - impresso com vencimentos previstos e, após a confirmação, reais;
  - NF-e do piloto com a operação do tipo já escolhida.
## Atualização — 29/09/2026 — Comissões e metas

- Migration `0070` com rollback e reaplicação; PHPUnit **58 testes, 1068 asserções** (`CommissionRuleTest` novo: prioridade, faixa de desconto nos limites, regra por representante, sem regra).
- `tests/ServerCommissionSmoke.php` (novo): **35 verificações aprovadas**, com rollback:
  - validação das regras e escolha do percentual;
  - rateio do desconto geral na base;
  - geração idempotente;
  - liberação proporcional ao recebimento e liberação na venda;
  - comissão do PDV e estorno proporcional na devolução;
  - fechamento só do que está liberado, com a conta a pagar;
  - bloqueio de cancelamento após o fechamento;
  - cancelamento de pedido;
  - metas × realizado (pedido + PDV).
- Smokes de peças, fiscal, PDV, financeiro e negócio: aprovados, sem regressão com os ganchos de comissão no PDV e no pedido.
- Roteiro HTTP: **13 verificações aprovadas**:
  - menu;
  - extrato;
  - regra salva com vírgula, recusa acima de 100% com a mensagem na tela;
  - edição e desativação de regra;
  - modo de liberação;
  - aviso ao fechar sem comissão;
  - metas salvas e exibidas.
## Atualização — 28/09/2026 — Estoque por peça/rolo

- Migrations até `0069` com rollback e reaplicação; PHPUnit **52 testes, 1041 asserções**.
- `tests/ServerPiecesSmoke.php` (novo): **12 verificações aprovadas**, com rollback:
  - numeração sequencial por empresa;
  - peso líquido e fator kg/m calculados;
  - saldo do produto somando as peças e saldo em kg pelo fator;
  - recusa de metragem vazia e de tara maior que o bruto;
  - peça de produto em kg;
  - corte parcial e recusa de corte acima do saldo;
  - isolamento por empresa;
  - venda no PDV baixando das peças;
  - devolução voltando para a peça de origem.
- Smokes fiscal (17), PDV (25), financeiro (17) e negócio (23): aprovados, sem regressão.
- Roteiro HTTP das peças: **10 verificações aprovadas** (rastreio por peça na variante, entrada de 2 peças, lista com kg calculado, erro de metragem na tela, detalhe, baixa parcial, etiquetas com código de barras marcadas como impressas).
- Ainda não executado: leitura com coletor e impressão em impressora de etiquetas (entra com o HUB).

## Atualização — 28/09/2026 — Produtos

- Migrations até `0068` com rollback e reaplicação; PHPUnit **52 testes, 1023 asserções**.
- Smoke fiscal: agora com **17 verificações**, incluindo a informação adicional do item (informação fiscal do produto + campo adicional) e `infAdProd` no XML.
- Roteiro HTTP do catálogo: **15 verificações aprovadas** na primeira execução:
  - configurações, campo adicional e recusa de duplicado;
  - categoria e subcategoria com caminho;
  - formulário com apelido e campo adicional;
  - bloqueio por NCM obrigatório;
  - produto com valor do campo, busca pelo campo e filtro pela categoria principal;
  - preço com 3 casas;
  - fornecedor com fator de embalagem e unidade.
- Defeitos antigos corrigidos:
  - a informação adicional fiscal do produto era gravada mas nunca ia para o XML da NF-e;
  - o erro de NCM inválido abria a aba fiscal sem mostrar a mensagem.

## Atualização — 28/09/2026 — Regras fiscais e IBS/CBS

Ambiente descartável MySQL 8.0.40, migrations até `0067` com rollback e reaplicação.

- PHPUnit: **51 testes, 1006 asserções**. `FiscalTaxEngineTest` cobre:
  - perfil com ICMS/PIS/COFINS e IBS/CBS;
  - regra por UF com a posterior vencendo;
  - redução de base;
  - exclusão do ICMS da base de PIS/COFINS;
  - condições que não casam;
  - regra de IBS/CBS por CFOP;
  - edição sem recálculo.
- `tests/ServerFiscalRulesSmoke.php` (novo): **15 verificações aprovadas**:
  - regras gravadas com lista de NCM e isoladas por empresa;
  - CFOP interestadual; ICMS 12% com redução de 41,67%;
  - PIS/COFINS sem ICMS na base; IPI;
  - base e valores de IBS/CBS;
  - totais da nota;
  - XML PL_010 com `IBSCBS`, `cClassTrib`, `vCBS`, `IBSCBSTot`, `pRedBC` e `cBenef`, e chave de 44 dígitos.
- Smokes PDV (25), financeiro (17) e negócio (23): aprovados.
- Roteiro HTTP das telas fiscais: **12 verificações aprovadas** (regras, apuração, perfis com IBS/CBS, recusa de CST × cClassTrib incompatíveis, edição e desativação de regra, formulários de NF-e e NFC-e).
- Defeito antigo corrigido: o XML chamava `tagveiculo`, inexistente na NFePHP, e quebraria toda NF-e com placa de veículo; agora usa `tagveicTransp`.
- Evidência da fórmula de IBS/CBS: no TIMASY, 5.297 de 5.756 itens de NFC-e (92%) conferem com base = valor − PIS − COFINS (− ICMS); os demais diferem só por desconto geral não rateado no legado.
- Ainda não executado: transmissão em homologação SEFAZ com leiaute PL_010 (depende de certificado), validação das regras e alíquotas pelo contador, DIFAL/FCP e SPED.

## Atualização — 28/09/2026 — Frente de caixa (PDV)

Mesmo ambiente descartável (MySQL 8.0.40), banco recriado do zero com as 66 migrations; rollback e reaplicação da `0066` sem erro.

- PHPUnit com banco: **45 testes, 968 asserções**.
- `tests/ServerPosSmoke.php` (novo): **25 verificações aprovadas**, com rollback:
  - configuração com consumidor final automático;
  - total com item repetido, serviço e desconto geral;
  - envio ao caixa; bloqueio com caixa fechado e com soma diferente do total;
  - isolamento por empresa;
  - recebimento em dinheiro com troco + PIX + crediário em 2 parcelas;
  - baixa de estoque, inclusive do lote; valor esperado no caixa e saldo da conta;
  - bloqueio de novo recebimento e de cancelamento de venda concluída;
  - devolução com desconto rateado, reembolso pelo caixa e volta ao estoque;
  - devolução em crédito com volta ao mesmo lote; bloqueio de devolução em dobro;
  - numeração sequencial e cancelamento de pré-venda.
- Smokes financeiro (17) e de negócio (23): aprovados, sem regressão.
- Roteiro HTTP autenticado do PDV: **21 verificações aprovadas**:
  - configuração e busca por código de barras;
  - pré-venda enviada ao caixa;
  - erro de caixa fechado exibido na tela;
  - abertura de caixa e conclusão com dinheiro + PIX, com troco exibido;
  - baixa de estoque;
  - cupom não fiscal;
  - NFC-e pré-preenchida pela venda;
  - devolução em dinheiro com volta ao estoque;
  - telas do caixa e da lista;
  - auditoria.
- Ainda não executado: emissão real da NFC-e (depende de certificado, CSC e homologação SEFAZ), impressão física no térmico, leitor de código de barras físico e teste com navegador real das teclas de atalho.

## Atualização — 28/09/2026 — Financeiro essencial

Ambiente: MySQL 8.0.40 descartável criado localmente só para o teste (mesma versão do servidor), banco recriado do zero com as 65 migrations; PHP 8.5.

- Migrations `0001` a `0065` aplicadas do zero; rollback e reaplicação da `0065` sem erro.
- PHPUnit com banco: **41 testes, 921 asserções, nenhum pulado** (inclui os testes de isolamento entre grupos, que antes eram pulados por falta de MySQL local).
- `tests/ServerFinanceSmoke.php` (novo): **17 verificações aprovadas**, com rollback:
  - condição de pagamento e parcelas que somam exatamente o total;
  - vencimento mensal no fim do mês;
  - baixa agrupada com juros e desconto e saldo da conta;
  - recusa de misturar a receber e a pagar;
  - isolamento por empresa;
  - abatimento sem movimento bancário;
  - estorno de lote;
  - lançamento avulso, transferência e extrato;
  - conciliação automática por OFX;
  - lançamento criado a partir do extrato;
  - bloqueio de estorno conciliado;
  - cancelamento.
- `tests/ServerBusinessSmoke.php`: **23 verificações aprovadas**, sem regressão.
- Roteiro HTTP autenticado com servidor PHP local: **41 verificações aprovadas**:
  - as 11 telas do Financeiro respondem 200 sem aviso de PHP;
  - cadastro de conta sem banco;
  - condições e formas de cobrança, com erro de validação exibido na tela;
  - título manual;
  - baixa de parcela com juros;
  - baixa em lote e estorno;
  - lançamento avulso e transferência;
  - importação OFX com conciliação automática;
  - criação de lançamento pelo extrato;
  - registro na auditoria.
- Defeito encontrado e corrigido no roteiro: texto recebido fora de UTF-8 (Windows-1252) gerava erro 500 no MySQL; agora é convertido na entrada.
- Ainda não executado: teste com navegador real (interação JavaScript das prévias e totais), concorrência simultânea de duas baixas e homologação com extrato OFX real de banco.

## Atualização — 26/09/2026

- Migrações de produção aplicadas até `0047`.
- PHPUnit local: **28 testes, 679 asserções, 2 testes de integração pulados** por falta de MySQL local.
- Expedição: separação e conferência persistidas, despacho com volumes/rastreio, romaneio A4 e etiquetas por volume.
- Compras: inspeção por item recebido, reprovação, devolução física ao fornecedor e crédito financeiro vinculados.
- Produção: apontamentos parciais, consumo proporcional, perda/refugo e histórico por OP.

- Migrações de produção aplicadas até `0036` (layout de impressão e administrador global da plataforma).
- PHPUnit local: **25 testes, 625 asserções, 2 testes de integração pulados** por falta de MySQL local; 1 aviso de depreciação.
- Teste transacional no servidor: **23 verificações aprovadas**, com rollback. Incluiu lote/série, reserva/expedição, consumo, devolução em inspeção, baixa e estorno financeiro, caixa físico, fluxo mensal, layout de impressão e isolamento entre empresas.
- Teste de plataforma no servidor: administrador `contato@n4sti.com.br`, flag de acesso global e tabela de layouts verificados.
- Sintaxe PHP dos arquivos alterados: sem erros.
- Ainda não executado: navegação autenticada de ponta a ponta em todas as telas (o navegador automatizado não estava disponível nesta execução), concorrência simultânea, homologação fiscal e integração real do Mercado Livre. Não tratar esses itens como concluídos.

### Roteiro de conferência manual pendente

1. Produto rastreável → endereço → entrada por compra → pedido → reserva → guia de separação → despacho → devolução bloqueada.
2. OP com componente rastreável → liberar → concluir com lote do produto acabado → conferir saldos e genealogia.
3. Caixa: abrir → suprir → sangrar → conferir divergência → fechar → impedir novo movimento.
4. Financeiro: conferir título, baixa parcial, estorno e fluxo mensal previsto/realizado por empresa.
5. Nota fiscal: revisar dados e XML em homologação com certificado real e contador responsável antes de transmissão de produção.

## Linha de base — 20/09/2026

## Resultado automatizado

- Sintaxe PHP: **185 arquivos aprovados**.
- PHPUnit: **24 testes aprovados, 539 asserções**.
- Integridade de rotas: todos os controllers e métodos registrados foram encontrados.
- Pendências do PHPUnit local: 2 testes de integração pulados por ausência de MySQL local; foram compensados pelo teste transacional no servidor.
- Migrations de produção: `0001` a `0029` aplicadas.
- Smoke HTTP público: `/login` respondeu HTTP 200.

## Teste transacional no servidor

Executado dentro de transação e finalizado com rollback. Nenhum dado de teste permaneceu no banco.

1. Criar grupo, empresa, estabelecimento e depósito temporários.
2. Habilitar módulos e validar o gate de backend.
3. Criar unidade, produto e variante.
4. Lançar 100 unidades em estoque.
5. Reservar 10: disponível 90, reservado 10.
6. Liberar reserva: disponível novamente 100.
7. Criar conta a receber de R$ 100.
8. Baixar R$ 40: situação parcialmente paga.
9. Estornar a baixa com motivo: situação novamente em aberto.
10. Validar uma NF-e básica de Simples Nacional: sem erros de pré-validação.

Todos os dez passos foram aprovados.

## Verificação por módulo

| Módulo | Situação verificada | Limite conhecido |
|---|---|---|
| Plataforma/Empresas/RBAC | Super Admin restrito à plataforma; grupos, empresas, módulos e permissões ativos | Ampliar testes HTTP autenticados por perfil |
| Produtos | Cadastro/variantes presentes | Campos avançados do benchmark ainda serão ampliados |
| Estoque | Ledger, reserva e estorno aprovados | Lote/série e inventário completo ainda pendentes |
| Almoxarifado | Rotas e fluxo implementados | Falta teste automatizado do ciclo completo |
| Orçamentos | Versões, impressão e editor de layout por empresa implementados | Falta automação de envio/aceite externo |
| Pedidos | Reserva, confirmação, impressão e editor de layout por empresa implementados | Devolução comercial completa pendente |
| Expedição | Separação, conferência, volumes, rastreio, romaneio e etiquetas implementados | Homologar leitores e impressoras físicos |
| Compras | Aprovação, recebimento parcial, qualidade e devolução ao fornecedor implementados | Cotação, aprovação multinível, XML de entrada e IQF |
| Financeiro | Baixa, estorno e parcelas aprovados | Rateio/centro de custo, OFX e DRE |
| Produção | BOM, reserva, apontamentos parciais, consumo proporcional e perdas implementados | Roteiros, recursos, qualidade, custo real e genealogia consolidada |
| Industrialização | Remessa, trânsito, terceiro e retorno parcial implementados | Genealogia por lote pendente |
| NF-e | Rascunho, prévia, XML, transmissão e cancelamento implementados | Homologação real depende do certificado/contador |
| NFC-e | Modelo, série, CSC e rascunho implementados | QR Code/DANFE NFC-e e homologação SEFAZ pendentes |
| NFS-e | Rascunho, retenções, conferência e DPS XML implementados | Transmissão depende do município/Ambiente Nacional |
| Mercado Livre | OAuth, token, webhook e captura de pedidos implementados | Conversão automática, anúncios e sincronização ativa de estoque pendentes |

## Correções desta rodada

- removido o selo incorreto “ainda não implementado” dos módulos disponíveis;
- backend passou a rejeitar habilitação manipulada de módulo não implementado;
- corrigido o campo de CPF/CNPJ da NFS-e (`document_number`);
- adicionada pré-validação fiscal com mensagens orientadas ao campo;
- validação acontece antes da reserva de número/transmissão.

## Critério para considerar “totalmente concluído”

Integrações fiscais e marketplace só podem ser aprovadas integralmente após piloto controlado com credenciais reais, certificado A1, CSC, conta Mercado Livre e validação do contador. Até lá, a interface deve mostrar “em configuração/homologação”, nunca “produção aprovada”.
