Files
SGF/docs/SERVICES_B1_DELIVERY.md
T

11 KiB

B1 — confirmação interna e fotografia histórica

Data: 25 de Outubro de 2026 (Africa/Johannesburg). Estado: B1 aceite pelo utilizador no âmbito demonstrado de confirmação interna, sem validade fiscal nem lançamentos contabilísticos. Não constitui conclusão integral de B. A permanece aceite no checkpoint ca13acb, com antecessor 26b80df; nenhum foi substituído ou reaberto.

Aceitação

Em 25 de Outubro de 2026, o utilizador declarou: «Aceito B1 no âmbito demonstrado de confirmação interna, sem validade fiscal nem lançamentos contabilísticos. Regista a aceitação e preserva um checkpoint Git local, sem credenciais ou dados locais. Não avances para os restantes incrementos nem publiques.»

O checkpoint preserva código, migração, documentação e provas sintéticas. Exclui credenciais, configurações privadas, bases, sessões e logs. As contagens de desenvolvimento neste relatório são evidência histórica da entrega, não uma cópia dos dados locais. A aceitação encerra apenas B1 e mantém os limites abaixo.

O que ficou funcional

Um utilizador com billing_drafts.view e a nova concessão explícita billing_drafts.confirm_internal, na empresa/unidade seleccionadas, pode abrir o rascunho, rever a operação e confirmar uma versão actual. A interface apresenta «Confirmado internamente — sem validade fiscal» e referência técnica INT-B1-<id>, distinta de numeração fiscal.

A confirmação exige cliente/serviços válidos na empresa, prestação na mesma unidade, versão da prestação correspondente à origem guardada, designação e linhas com quantidade positiva/preço não negativo completos. Reutiliza as validações decimais de A. Campos e identificadores protegidos enviados pelo navegador são recusados. Empresa/unidade, pertenças e permissão são revalidadas no servidor dentro da transacção, após bloquear a empresa e antes da operação. A sessão e o token de contexto existentes continuam em uso.

Moeda desconhecida é conservada como null, com pendência explícita. Imposto permanece pendente e não é convertido em zero. Mesmo uma moeda preenchida continua sujeita a validação. A base aritmética usa decimais exactos e não se apresenta como total monetário definitivo ou fiscal; não há agregação de moedas distintas.

A fotografia conserva o rascunho e a prestação com versões/dados originais, cliente e serviços com versões/dados observados, linhas e valores usados, moeda conhecida ou desconhecida, pendências, âmbito, autor e instante. Os nomes nas linhas e identificação do cliente usados na confirmação são conferidos no cadastro actual, que também fica fotografado; a versão original do rascunho continua preservada separadamente. Alterações posteriores dos cadastros ou da prestação não reescrevem a fotografia.

A confirmação cria uma identidade própria, sem transformar a prestação em serviço confirmado. O rascunho de origem mantém a versão fixada e fica bloqueado para edição/eliminação. API e triggers SQL impedem actualizações em massa ou eliminação do rascunho confirmado; a fotografia tem protecção append-only. Não há reabertura, correcção ou anulação. A prestação e os cadastros continuam com o comportamento de A, preservando as suas versões.

Captura e repetição

Confirmação, fotografia, histórico, evento b1.billing_draft.confirmed_internal, pendências, auditoria e resultado do comando são persistidos na mesma transacção. A captura reutiliza a_history, a_events, a_outbox, a_pending e a_commands; os eventos de A não são reconstruídos ou alterados.

O outbox permanece captured, sem consumidor contabilístico. A fotografia mostra not_issued para fiscalidade e blocked_pending para contabilidade. Além das pendências de A, contas/classificação e reconhecimento ficam explicitamente pendentes. Não há lançamentos, receita reconhecida ou estado contabilizado.

Repetição com mesma chave/autor/conteúdo recupera o resultado. Conteúdo diferente com a mesma chave produz 409. Outra chave para o mesmo rascunho/versão recupera a confirmação existente, sem novo evento. A unicidade por rascunho e bloqueios transaccionais impedem confirmações concorrentes duplicadas. Como não há reabertura, não se confirmam versões posteriores do rascunho já fixado. Resolução futura de pendências exigirá registos/versionamento próprios, sem editar a fotografia.

Migração e acesso aplicados

O delta foi apresentado antes da aplicação. Migração aditiva 2026_10_25_040000_create_internal_confirmations, aplicada em sgf_tempo_test pelas provas e depois em sgf_tempo_dev pelo wrapper, com proprietário separado:

  • Cria apenas b_internal_confirmations, com referência única ao rascunho, versão, âmbito composto, fotografia, autor e instante.
  • Acrescenta triggers de validade/imutabilidade e bloqueio do rascunho confirmado; amplia a validação de a_history para a nova origem sem remover as origens de A.
  • Acrescenta billing_drafts.confirm_internal ao catálogo SQL permitido, sempre com unidade explícita. Não concede esse direito pela migração, por nome/email ou por direitos de A.
  • Não modifica dados históricos de A nem cria tabelas de lançamentos, numeração fiscal ou processamento contabilístico. O rollback automático desta migração é recusado para não eliminar confirmações históricas; qualquer reversão requer procedimento de preservação revisto.

A conta existente foi conferida e apresentada: ID 1, Osmane Nala, na empresa Tempo Lda ID 1 / SEGI ID 1. O utilizador confirmou exactamente a nova concessão antes da aplicação. Foi aplicada uma concessão billing_drafts.confirm_internal, com auditoria b1.access.initial_grant. Samira mantém apenas consulta; os restantes direitos de A foram preservados. Total de concessões em desenvolvimento: 29. Não foram criadas contas, nem poderes de gestão da nova concessão, emissão, contabilização, recebimento ou fecho.

O procedimento local scripts/b1-access.php user_id company_id unit_id permite pré-visualizar a conta/âmbito. --apply só deve ser usado depois de confirmação específica da operação apresentada. Não o executar como seed ou criação automática de direitos. A interface de gestão de A não permite delegar confirm_internal; alterações futuras desta concessão continuam a exigir procedimento local autorizado e auditado. scripts/b1-status.php verifica contagens e a concessão sem mostrar credenciais.

Depois da aplicação: duas contas, um tenant, uma empresa e uma unidade preservados; clientes, serviços, prestações, rascunhos e confirmações em desenvolvimento continuavam vazios. Não foi criado qualquer documento interno real ou de demonstração na Tempo Lda/SEGI. A aplicação normal conserva sgf_dev_app, sem administração PostgreSQL, e a ligação à base de desenvolvimento.

Provas realizadas

Suite completa: 58 testes / 442 asserções aprovados, incluindo regressões de identidade e A, sem reabrir a sua aceitação. Compilação Vite aprovada, sem alteração de versões, manifests ou lockfiles.

Os 14 testes de B1 cobrem confirmação autorizada; consulta e gestor de A sem nova permissão recusados; revogação efectiva no pedido seguinte da mesma sessão; impossibilidade de delegar o novo direito pela gestão de A; âmbito manipulado; acesso cruzado entre unidades e entre empresas do mesmo tenant; versão/contexto antigos; fotografia preservada após alterações de cliente, serviço e prestação; moeda/regra desconhecidas; linhas incompletas; origem desactualizada; repetição/conflito; bloqueio API e SQL de edição/eliminação; fotografia append-only; falha injectada no outbox com rollback integral, incluindo auditoria e comando.

Prova de concorrência com dois processos PHP reais, sobre PostgreSQL e com sobreposição demonstrada de bloqueios: chaves iguais e chaves diferentes produziram apenas uma confirmação e um evento por rascunho. Resultado.

Prova HTTP com autenticação real de contas sintéticas, CSRF activo e sessões distintas: confirmação autorizada, leitor recusado 403, contexto/versão antigos 409, repetição recuperada, conteúdo diferente 409, alteração de rascunho confirmado 409 e fotografia inalterada após edição dos cadastros. Resultado.

No navegador isolado em http://127.0.0.1:8001, ligado exclusivamente a sgf_tempo_test, o gestor entrou pelo formulário, preparou um rascunho e confirmou-o pela revisão explícita. A interface mostrou moeda desconhecida, referência interna, fotografia e pendências. Após saída, a conta de consulta entrou pelo formulário e consultou a fotografia sem botões de criação, edição, gestão ou confirmação. Não foi apenas uma prova com actingAs.

Provas visuais: confirmação interna e pendências e consulta com contexto sintético. Métricas de captura verificam correspondência entre confirmações, históricos, eventos e outbox.

A instância de prova foi parada; a suite final limpa os dados sintéticos apenas na base de testes. Não se alterou a ligação da aplicação normal, não se terminaram processos de outros projectos e não se publicaram conteúdos.

Ficheiros e comandos

Novo workflow app/Modules/Services/InternalConfirmation.php, integração em ServiceController.php, ServiceWorkflow.php, routes/web.php, ServicesWorkspace.jsx e rodapé de app.jsx; migração indicada acima. A integração acrescenta estado de confirmação à lista, protege o rascunho e evita pendências posteriores de origem reescreverem a captura já confirmada.

Testes em tests/Feature/InternalConfirmationTest.php, fixture tests/Support/InternalConfirmationFixture.php; preparação de navegador adaptada e worker de concorrência existente reutilizado. Scripts próprios: b1-access.php, b1-status.php, b1-concurrency-proof.php, b1-http-proof.mjs e b1-proof-metrics.php. Documentação actualizada em AGENTS, README e especificações, respeitando as alterações posteriores a A.

powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\scripts\sgf.ps1 test
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\scripts\sgf.ps1 npm run build
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\scripts\sgf.ps1 php scripts/b1-status.php

Os scripts de concorrência/métricas verificam explicitamente o destino sgf_tempo_test. Parar a instância de navegador antes de executar testes que recriam essa base. Recuperação de acesso mantém o procedimento assistido de IDENTITY_WORKFLOW.md, sem fornecedor ou recuperação por email.

Limites remanescentes

B1 fixa dados internos; não emite documento comercial/fiscal, não imprime/exporta uma factura, não confirma execução do serviço, não reconhece receita nem produz lançamentos. Não foi criado consumidor contabilístico. Contas, reconhecimento, moeda funcional, regras fiscais e arredondamento fiscal continuam por validar. Não foram implementados recebimentos, reconciliação, fecho, reabertura, correcção ou anulação. O restante B e C dependem de âmbito e autorização próprios. B1 foi aceite com estes limites; A permanece encerrada. Não avançar para os restantes incrementos nem publicar.