Files
SGF/docs/SGC_INVOICE_WORKSPACE_DELIVERY.md
2026-11-11 09:00:17 +02:00

69 lines
11 KiB
Markdown

# 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.
1. 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.
2. 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.
3. 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.
4. 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.
5. 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.
6. 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:
1. 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.
2. Aprovar ligação, mapeamentos e identidade/segredo/contexto privados com direitos existentes. Não criar ou conceder acessos por inferência.
3. 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.
4. 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](proofs/sgc-invoice-workspace-final-20261110.json); o resumo inicial de19 casos/138 asserções fica preservado.