# Entrega A — serviços em rascunho 25 de Outubro de 2026. Entrega A aceite pelo utilizador no âmbito demonstrado e com os limites documentados. O checkpoint `26b80df` foi preservado; versões, manifests e lockfiles não foram alterados. ## Aceitação Em 25 de Outubro de 2026 (Africa/Johannesburg), o utilizador declarou: «Aceito a entrega A no âmbito demonstrado e com os limites documentados. Regista a aceitação e preserva um checkpoint Git local, sem credenciais ou dados locais. Não avances ainda para B/C nem publiques.» Esta aceitação encerra apenas A. O checkpoint contém código, migração, documentação e provas sintéticas; exclui configurações privadas, credenciais, bases, sessões, logs e o plano operacional específico de concessões locais. Não autoriza B/C ou publicação. ## Percurso funcional Depois de entrar e seleccionar empresa/unidade autorizadas, estão disponíveis Clientes, Serviços, Prestações em rascunho e Rascunhos de facturação, conforme concessões explícitas. - Clientes e serviços pertencem à empresa e são reutilizados entre unidades. Nome é o único campo obrigatório do cliente. - Prestações e rascunhos de facturação pertencem à unidade autorizada. A facturação reutiliza cliente, linhas, moeda indicada e versão da prestação. - Consulta, criação, edição e gestão de concessões são separadas nas quatro áreas. Direitos de identidade não concedem automaticamente direitos de A. Gestores só delegam direitos que possuem no mesmo âmbito. - Alterações preservam versões, histórico, eventos duráveis, outbox, pendências e resultado idempotente na mesma transacção. Repetir o comando não duplica o registo ou evento; versões e contextos antigos são recusados. - Alterar a prestação gera uma pendência nos rascunhos de facturação associados. Actualizar explicitamente da prestação cria outra versão, preservando a anterior. Quantidades e preços são cadeias decimais não negativas, com até 16 algarismos inteiros e 8 decimais; quantidade preenchida deve ser positiva. Entradas excedentes são recusadas, sem arredondamento. Produtos e somas derivados usam aritmética decimal exacta, podendo exigir mais casas. A base aritmética não é total fiscal nem valor definitivo a pagar. Moeda não é presumida; imposto desconhecido não é zero. Mesmo com código de moeda preenchido permanece pendente a sua validação. Regras fiscais e contabilísticas continuam explicitamente pendentes. Não há confirmação financeira, emissão de factura, lançamento contabilístico, recebimento, correcção financeira, reconciliação ou fecho. O outbox fica em captura durável, sem processamento contabilístico. B/C dependem de regras e autorização próprias. ## Migração e preservação de dados Aplicada em `sgf_tempo_dev`, pelo wrapper de migrações e proprietário separado, a migração aditiva `2026_10_25_030000_create_services_delivery_a` (batch 4). A aplicação conserva o papel `sgf_dev_app`, sem administração PostgreSQL. O delta cria nove tabelas: `a_clients`, `a_services`, `a_service_drafts`, `a_billing_drafts`, `a_history`, `a_events`, `a_outbox`, `a_pending` e `a_commands`. Amplia o catálogo permitido de concessões, sem conceder acessos automaticamente. Inclui relações de âmbito, protecção SQL contra transferências de pertença, validação de dados e protecção append-only. O escopo Eloquent não é a única fronteira de isolamento. Não foi executado reset/fresh/wipe em desenvolvimento. As duas contas, tenant, empresa, unidade e oito concessões de identidade foram preservados. Após a implementação, as nove tabelas de A estavam vazias em desenvolvimento: as demonstrações usaram exclusivamente `sgf_tempo_test`. ## Concessões especificamente confirmadas As contas foram conferidas antes da aplicação; nenhuma foi criada ou associada por suposição. O utilizador confirmou exactamente estas contas e concessões: | Conta existente | Clientes / serviços — Tempo Lda, empresa 1 | Prestações / facturação em rascunho — SEGI, unidade 1 | | --- | --- | --- | | ID 1 — Osmane Nala, nala@tempo.co.mz | Consulta, criação, edição e gestão em cada área | Consulta, criação, edição e gestão em cada área | | ID 2 — Samira Nal, onala@me.com | Consulta em cada área | Consulta em cada área | Foram aplicadas e auditadas 16 concessões para Osmane e 4 para Samira, mantendo as oito anteriores (28 no total). Não há direitos implícitos noutras unidades ou poderes financeiros. Os emails apenas identificaram as contas nesta operação confirmada; não determinam privilégios durante a execução da aplicação. O plano operacional local `scripts/a-access-plan.php` conserva a pré-visualização e as verificações da operação, mas fica excluído do checkpoint por conter identificações locais. Não repetir `--apply` após alterações posteriores dos direitos sem nova confirmação específica. `scripts/a-status.php` permite verificar estado sem apresentar segredos. ## Verificação realizada - Suite completa: **44 testes, 273 asserções, todos aprovados**, incluindo a fundação anterior. - Compilação Vite: aprovada. Nenhuma dependência ou versão foi substituída. - Testes de isolamento entre empresas, inclusive do mesmo tenant, e unidades; identificadores manipulados; consulta sem escrita; ausência de herança implícita; limites de delegação; versões/contextos antigos; alterações SQL em massa; histórico imutável; rollback integral com falha injectada no outbox. - Dois processos PHP concorrentes: criação repetida produziu um registo/evento; edição concorrente terminou em 200/409, com apenas uma nova versão/evento. [Resultado](proofs/a-concurrency.json). - HTTP com login real de contas sintéticas: leitura 200, alteração/gestão recusadas 403, concessão/revogação efectivas no pedido seguinte da mesma sessão, contexto/versão antigos 409, protecção CSRF 419 e cookie de sessão terminada 401. [Resultado](proofs/a-http-results.json). - Captura durável na prova: 9 versões, 9 eventos, 9 entradas de outbox, 9 resultados de comandos, sem eventos órfãos; estado apenas `captured`. [Métricas](proofs/a-durable-capture.json). - `verify-foundation.php` confirmou isolamento de papéis e ausência de contas sintéticas na base de desenvolvimento. A prova visual utilizou uma instância isolada na porta 8001, ligada apenas a `sgf_tempo_test`, com sessões/cache próprios, CSRF activo e utilizadores sintéticos equivalentes. Incluiu login pelo formulário, criação de cliente/serviço/prestação, recusa de precisão excessiva, preparação e edição de rascunho de facturação, histórico e gestão delimitada de acessos. O utilizador de consulta viu os registos sem botões de criação, edição ou gestão. Não se tratou apenas de `actingAs`. Provas: [precisão recusada](proofs/a-01-precision-refused.png), [rascunho](proofs/a-02-draft-pending.png), [histórico e pendências](proofs/a-03-history-and-pending.png), [consulta](proofs/a-04-read-only.png). A instância de prova foi parada e a suite executada novamente para limpar os dados sintéticos na base de testes. A aplicação normal permaneceu na porta 8000, sem alteração de ligação ou dados de demonstração na Tempo Lda/SEGI. Não foram terminados processos de outros projectos. ## Ficheiros e utilização Implementação em `app/Modules/Services` (permissões, valores, workflow, acessos e controlador), migração acima, `resources/js/ServicesWorkspace.jsx`, integração em `app.jsx`, CSS e rotas. A fundação de identidade foi reutilizada; a auditoria recebeu metadados de A e a listagem antiga de acessos ficou delimitada ao seu catálogo. Testes em `tests/Feature/ServicesDeliveryATest.php` e `tests/Support/ServicesFixture.php`; procedimentos de prova em `scripts/a-concurrency-proof.php`, `a-concurrency-worker.php`, `a-http-proof.mjs` e `a-proof-metrics.php`, com preparação de fixtures sintéticas adaptada. README e especificação foram actualizados. Para utilizar, actualizar o navegador em http://127.0.0.1:8000, entrar normalmente e seleccionar Tempo Lda/SEGI. Seguir o percurso do [README](../README.md). Não executar os scripts de fixtures para criar dados reais. A recuperação local assistida da identidade mantém-se documentada em [IDENTITY_WORKFLOW.md](IDENTITY_WORKFLOW.md); não há recuperação por email. Comandos de verificação, a partir do projecto: ```powershell 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/a-status.php ``` As provas destrutivas continuam bloqueadas fora de `sgf_tempo_test`. Parar a instância de navegador de testes antes de executar a suite que recria essa base. Os scripts de prova de concorrência e métricas têm também verificação própria do destino. Não mudar a aplicação normal para a base de testes. ## Limites e próxima decisão A entrega A foi aceite com estes limites. Não define regime fiscal, numeração, moeda funcional, plano de contas, reconhecimento ou arredondamento fiscal. Não inclui emissão, processamento contabilístico ou processamento externo do outbox. Não foi publicada nem iniciado outro incremento. A especificação B/C permanece como proposta, sem autorização de execução.