11 KiB
SGC → SGF: rascunho, conferência, decisão e recibo persistentes
10/11/2026. Bloco implementado e testado, incluindo ecrã, persistência auditada, exclusão de duplicação local e integração com o endpoint SGF. Não instalado/activado no SGC operacional ou8085. Não se declara concluído o SGF inteiro, implantação ou uso real por consequência desta entrega.
Percurso utilizável no código entregue
Entrada SGC preparada: /facturas/envio-sgf, ligada à página nativa de facturas quando a capacidade estiver autorizada/activa. Rotas usam autenticação, verificação existente, empresa configurada e contexto de trabalho nativos. Não foi aberta sessão de demonstração ou criado novo servidor.
- Finanças escolhe explicitamente ligação e mapeamento aprovados da sua empresa; não se selecciona primeiro fornecedor/ordem/linha nem se deduzem IDs por nomes.
- Guarda referência de origem, número/data/documento/linhas e fundamento. Só rascunhos ainda não registados no SGC: a associação ao fornecedor da origem vem do mapeamento autorizado, não do pedido do browser.
- O rascunho reserva a identidade empresa/fornecedor/número. Edição antes de qualquer confirmação cria nova versão auditada e invalida prévia/intenção anteriores; nunca apaga o histórico. Uma confirmação iniciada torna o conteúdo imutável, mesmo que se perca a resposta.
- A prévia guarda intenção, UUID e reserva de execução antes da rede. Obtém contexto exacto da ordem no SGF e apresenta o impacto recebido, sem criar factura persistente. Não há confirmação automática.
- A decisão individual exige fundamento, versão actual, mesmo operador/contexto da conferência e o hash desse impacto. A decisão/intenção/cut são conservados antes da chamada de confirmação.
- O recibo verificado fica persistido como
received_pending, com IDs de ordem/factura e repetição observada. O ecrã oferece continuidade pela entrada existente de8085, com escolha explícita de função e os IDs do recibo, sem bearer/cut na URL. Revisão financeira/consumo/obrigação continuam no SGF e exigem as decisões distintas existentes.
O ecrã tem lista SQL paginada25 e filtro de estado por empresa, formulário com linhas explicitamente mapeadas, versão/fundamento, prévia legível, confirmação individual, recuperação e histórico SQL paginado25. A evidência é apresentada por campos, escapada contra HTML injectado. A adição de linhas não reutiliza nomes dos campos existentes. Campos por guardar e confirmação em curso são protegidos ao sair; comandos no servidor continuam autoritativos entre abas/processos.
Persistência e isolamento
Migração preparada no SGC: 2026_11_10_000001_create_sgf_invoice_dispatches.php, não aplicada ao piloto. Acrescenta apenas:
sgf_invoice_dispatches: fonte, documento/mapeamento congelado, versão de fonte e de controlo, UUID, estado cifrado, hash de aprovação, lease, recibo e autor inicial. Unicidade por empresa/referência e empresa/fornecedor/número.sgf_invoice_dispatch_events: autor, data UTC, acção, fundamento e estado anterior/posterior, incluindo versões, documento, mapeamento, intenção/impacto por hash e recibo. Eventos append-only e rascunhos sem DELETE, por triggers PostgreSQL/SQLite. Não há tabela de dívida/consumo/stock/contabilidade nova.
O cut/intenção/impacto de transporte fica cifrado com a chave da aplicação na tabela; segredos de ligação nunca entram nos rascunhos/eventos/HTML. As consultas usam o tenant da pessoa autenticada. A pessoa, função financeira, exclusão de manutenção, fornecedor autorizado, mapeamento e versão são revalidados nos comandos; autoridade e ligação são ainda revalidadas pelo gateway antes de cada chamada.
O writer original InvoiceWorkflow::register ganhou apenas a guarda da reserva SGF dentro do bloqueio empresarial já existente, antes de criar uma factura local. A criação do rascunho toma o mesmo bloqueio e recusa uma factura local preexistente. Assim, as duas direcções não podem registar a mesma identidade documental em simultâneo. A reserva mantém efeito mesmo se o workspace/transporte forem depois desligados. Se a nova estrutura ainda não estiver instalada, o writer nativo anterior conserva o seu percurso; activar o workspace sem estrutura devolve503 e não migra por inferência.
Não há novo nome de direito ou concessão. Usam-se função/âmbito/contexto nativos e os direitos SGF já existentes. Os mapeamentos/principais operacionais continuam vazios/não escolhidos; workspace_enabled=false e enabled=false na configuração entregue.
O manifesto apresenta os privilégios SQL mínimos para revisão antes de qualquer concessão, com role/base aindaNULL e aprovaçãofalse: SELECT/INSERT/UPDATE no rascunho, SELECT/INSERT nos eventos e USAGE/SELECT nas sequências. Não propõe UPDATE/DELETE da auditoria ou grantsPUBLIC. São necessidades de instalação a conferir contra privilégios já existentes; nenhumGRANT foi aplicado a contas reais.
Concorrência e falhas
Cada transição toma empresa/pessoa/rascunho na mesma ordem e compara version. A transacção conserva intenção ou decisão e um lease120s, termina antes da rede, e regista a observação numa segunda transacção. Não se mantêm locks empresariais durante HTTP. A mesma fonte não ganha outra chave para contornar uma operação pendente/incerta.
Uma execução simultânea/versão antiga é recusada409. Se houver interrupção antes de observar a resposta, o estado sending com intenção/cut/decisão já existe; terminado o lease, a recuperação explícita usa a mesma chave e conteúdo. Uma resposta tardia de lease substituído não sobrescreve o estado actual. Uma falha de persistência depois do commit remoto conserva o estado de envio/decisão, permitindo recuperar o recibo sem outra factura.
Não há retries automáticos ou novos UUIDs gerados para confirmação/recuperação.401/403 bloqueiam,409 exige conferência, timeout/503/resultado incerto conservam a intenção. Mudanças de contexto da ligação são recusadas antes de gravar uma decisão sobre a prévia antiga. Uma nova prévia explicitamente pedida usa a autoridade actual; depois de iniciado um envio mantém a chave/conteúdo. Alterar o mapeamento de uma fonte já enviada/incerta não é autorizado para contornar o resultado: exige reconciliação da autoridade original, sem forçar outro documento.
Provas reutilizáveis
20 casos únicos/142 asserções em SQLite exclusivamente em memória, seleccionados dos XMLs JUnit (17 da consolidação, um do formulário completo, um da estrutura ausente e um da fotografia de operador/contexto na auditoria). A repetição dirigida de uma guarda anterior não é somada novamente. Incluem ecrã real Blade/HTTP, formulário→prévia→decisão→recibo, CSRF, acesso estrangeiro/função indevida/revogada, versões/hash/operador/contexto/mapeamento, paginação e histórico além25, HTML injectado, cifragem, imutabilidade, reserva local, falha de armazenamento depois da confirmação remota e recuperação. Não houve migrate:fresh ou suites alheias.
14 verificações PostgreSQL e integração entre dois processos de aplicação nos livros de regressão já existentes: origem SGC b4093c6f6707, receptor SGF da77bb730751. Só nesses ensaios se activaram flags em memória. Foram criadas as duas tabelas de teste no livro de origem, sem nova base/role/porta/demo. Duas fontes sintéticas produziram exactamente duas facturas pendentes no receptor:
- Primeiro caso: commit real do writer SGF, resposta perdida na origem, estado incerto persistido e recuperação do mesmo recibo com a mesma chave.
- Segundo caso: duas decisões concorrentes em processos PHP; uma envia/conserva recibo, outra recusa409 por versão/em curso; uma única decisão persistida e uma factura no receptor.
- Writer nativo SGC recusou o documento reservado antes de qualquer registo local. PostgreSQL recusou reescrita de evento. Todos os dados/sequências anteriores da origem mantiveram-se; orçamento, movimentos e pagamentos do receptor não mudaram.8085 manteve todas as linhas/sequências dos dois livros.
A primeira prévia deste harness falhou porque variáveis de cache herdadas do processo SGC apontavam o processo receptor para metadados de providers do SGC. O harness receptor passou a isolar esses valores antes de arrancar; retomou-se o rascunho/UUID já conservados, sem repetir confirmação aceite nem apagar a tentativa auditada. Logs de falha ficam privados.
As aplicações usaram os kernels Laravel e o writer nativo real em processos independentes, com a ponte interceptada para processos CLI: não é tráfego TCP para8085, nem activação de8085. As78 provas anteriores do endpoint e as16 do cliente portátil foram reutilizadas, sem repetir suites de negócio. A pequena guarda de estrutura instalada acrescentada no final foi verificada por ensaio dirigido, sem repetir os commits integrados.
Typescript sem erros; ficheiro TSX alterado compilado para artefacto privado, sem alterar public/build. Os Blade foram compilados/renderizados nos testes, e os três scripts inline renderizados passaram na verificação sintáctica. Isso não é revisão visual, prova de interação de browser ou build completo do produto/implantação.
Preparação concreta e próximos passos autorizáveis
Novo pacote inactivo: 3bb99e866f52965dbb7d, fora da aplicação8085, no mesmo directório privado de preparação. Contém oito ficheiros SGF e15 do cliente/SGC, incluindo migração, ecrãs, serviço e guardas. Conserva o pacote anterior d09aac9d09da98e61df5 como prova histórica. Ficheiros SGC existentes (rotas, writer, controlador e TSX) são assinalados para merge dirigido: não sobrescrever alterações alheias. Os modelos de principal/mapeamento não foram preenchidos/aprovados.
node scripts/prepare-sgc-8085.mjs check verifica a preparação e8085 sem instalar, activar, migrar, iniciar servidor ou limpar cache. Antes do uso operacional deste recorte faltam passos de instalação/configuração, não os ecrãs/persistência agora entregues:
- Autorizar e preparar backup/restauro para instalação exacta da nova migração SGC e código desligado; não executar todas as migrations pendentes.
- Aprovar ligação, mapeamentos e identidade/segredo/contexto privados com direitos existentes. Não criar ou conceder acessos por inferência.
- Instalar o código do endpoint desligado na mesma8085, compor o cliente e preparar o build do link de navegação SGC por via privada/revista. Os ecrãs Blade têm rota própria e não dependem do build do link.
- Só após autorização de activação, ensaiar tráfego entre as aplicações nessa mesma8085 com fonte nova sintética e decisões individuais. Não reenviar facturas históricas, activar Compras/candidatas ou migrar responsabilidades financeiras.
Os seis registos protegidos e a cache não foram alterados/limpos. Nenhum comando/migração no SGC operacional, concessão real, instalação/activação em8085, publicação, aceitação ou checkpoint. Visual, TLS/carga sustentada, recuperação de desastre e capacidade de implantação mantêm provas próprias. Prova final consolidada; o resumo inicial de19 casos/138 asserções fica preservado.