# Correcção e cancelamento de rascunhos de oficina — entrega em verificação **Verificação técnica concluída:** regressão completa **183 testes / 3 209 asserções, zero falhas/erros**, incluindo oito casos novos; seis cenários concorrentes e build aprovados. Ver [resumo de provas](proofs/workshop-corrections-tests.json). Referências abaixo a regressão em execução são históricas. Prova manual/capturas e aceitação permanecem pendentes. 28/10/2026. `WORKSHOP-BILLING-CORRECTION-SIM-v1`, [âmbito e decisões validadas](WORKSHOP_BILLING_CORRECTION_SCOPE.md). Preservados `3932b94`, `30029b9`, `d071bc0` e anteriores. Autorizada só implementação/prova sintética, sem migração/concessões em desenvolvimento ou utilização real. **Sem aceitação presumida ou checkpoint de encerramento.** ## Comportamento Pedidos imutáveis por geração, com predecessor explícito, versões exactas dos dois destinos, motivo, origens e composição comercial. Tipos: substituição, cancelamento e desistência do pedido anterior não aplicado. Osmane sintético prepara/aplica; Samira sintética aprova/recusa a versão exacta por identidade distinta, sem editar/aplicar ou verificar a oficina por consequência. Direitos próprios e contexto revalidados no servidor e na transacção; nenhum nome/email especial no código funcional. Substituição cria nova prestação e novo rascunho via `ServiceWorkflow`, com relação append-only ao par anterior, sem editar/apagar originais. Um destino actual por cadeia; a aplicação anterior consome a elegibilidade do destino antigo, não a origem técnica. `wb_claims` permanece com duas utilizações originais, sem novas linhas de consumo/tempo. Mesmo cliente, moeda MZN, origens e quantidades integrais; não se aceitam campos para os mudar. Preços, fonte, descrição e serviço comercial podem mudar com versão exacta e revisão. O catálogo actual não tem unidade comercial tipada: a unidade/quantidade física é conservada da origem e a adequação do serviço é matéria da revisão comercial, sem conversão implícita. Exemplo: original 1,75 H × 200 + 2 UN × 75 = 500 MZN sem imposto; substituto 1,75 H × 200 + 2 UN × 80 = 510. Fonte sintética sucessora `WORKSHOP-SALES-SYNTHETIC-v2`. Não é custo, margem, total fiscal ou quantia exigível. Zero explícito é distinto de preço ausente; exactidão decimal/racional herdada, sem float ou regra fiscal de arredondamento. Imposto/moeda funcional/classificação mantêm pendências. Cancelamento acrescenta estado de preparação cancelada e preserva origens, par actual e histórico; não cria novo par, não liberta origens e não admite reabertura neste recorte. Não anula ordem, apontamentos ou documentos fiscais. Desistência cria sucessor de pedido sem aplicar mudança aos destinos. Pedidos materiais novos não herdam decisões; referência antiga, nova dependência, cadastro ou origem alterados exigem nova revisão. ## Elegibilidade e integrações `WorkshopCommercialState` centraliza ligação e estado para originais/sucessores. Edição directa e nova facturação da mesma prestação bloqueadas em A e no SQL; estados comerciais visíveis no detalhe. B1 recusa confirmar destinos substituídos/cancelados, antes de replay; trigger SQL reforça estado e serializa com o bloqueio da empresa. Se B1 vencer a aplicação da correcção é recusada; se a correcção/cancelamento vencer a confirmação antiga é recusada. Não se altera confirmação ou fotografia existente. Preparação documental não pode editar destinos históricos. Aplicação exige par ainda draft, sem B1 e sem outros rascunhos derivados; origem/tarefa verificada actual e cliente/moeda compatíveis. Limite conservador: se já existir preparação documental específica no par, a operação é recusada até circuito próprio de herança. Nenhum conteúdo privado de instruções documentais é copiado para pedidos, auditoria ou provas. IDs/versões dos registos documentais da empresa compõem a referência: mudança invalida aprovação mesmo que seja conservadoramente noutro registo. Casos com herança documental, documentos fiscais, repartição parcial e reabertura continuam fora do recorte. Chave idempotente por geração/actor/acção/conteúdo, replay com permissão revalidada, conflito de conteúdo e recuperação após resposta perdida. Bloqueio de empresa serializa comandos; pedido/decisão/aplicação, prestação/rascunho, auditoria/evento/outbox são atómicos. Falha de outbox desfaz sucessores e estado; SQL reforça ambiente, cadeia, identidade, referência aprovada, destino e imutabilidade. Não é RLS ou segundo motor comercial independente contra administrador de confiança. Não são desligados triggers nem usadas flags de sessão para autorizar correcções. ## Provas e percurso Primeiros seis testes de correcção aprovados (89 asserções). Acrescentados testes de B1 posterior à revisão, preço zero/ausente e protecção SQL, com regressão completa em execução. Seis casos com processos sobrepostos aprovados: pedido repetido, substituição versus cancelamento concorrentes, decisão repetida, aplicação repetida, decisões concorrentes e cancelamento versus B1. Ver [concorrência](proofs/workshop-corrections-concurrency.json). Nesta execução concorrente resultaram uma substituição, um cancelamento, duas utilizações técnicas originais e nenhuma confirmação B1. Compilação aprovada com Vite 8.3.5, sem mudança de dependências. Novo destino **Oficinas → Correcção e cancelamento**, com consulta/preparação/revisão/aplicação filtradas por permissões. Origens/quantidades não editáveis; pedido mostra base anterior e nova soma, destinos exactos e histórico. Conversão original também identifica substituição/cancelamento e último sucessor; consulta do rascunho apresenta estado comercial. Não há decisão automática nem confirmação B1 automática. **Prova visual/manual ainda pendente.** Não repetida a automação bloqueada do Edge nem declaradas capturas. Preparação isolada, só com base de testes vazia e testes parados: ```powershell powershell -NoProfile -ExecutionPolicy Bypass -File scripts/browser-proof.ps1 start -Port 8002 powershell -NoProfile -ExecutionPolicy Bypass -File scripts/sgf.ps1 php scripts/workshop-corrections-fixture.php --env=testing ``` Fixture prepara apenas a conversão original de 500 pelos percursos existentes com identidades distintas, sem pedidos ou decisões de correcção predefinidos. Contas `gestor@example.test` e `consulta@example.test`; credenciais aleatórias só no manifesto/ficheiro local protegido `C:\laragon\data\sgf-tempo\secrets\workshop-corrections-manual-entry.txt`, nunca no relatório/capturas. Preparador escolhe geração, mantém trabalho 200 e altera material para 80, indica fonte v2 e motivo, submete; revisor aprova versão exacta; preparador aplica. Conferir original 500 histórico, novo 510 actual, linhas e origens preservadas. Depois preparar cancelamento do destino actual, rever distintamente e aplicar; conferir estado cancelado e ausência de reabertura. Não confirmar B1 na prova manual, nem executar testes destrutivos enquanto activa. Parar apenas a instância SGF com `scripts/browser-proof.ps1 stop`. Instância efectivamente arrancada em 8002 depois dos testes finais e fixture de suporte criada. Diagnóstico HTTP confirmou ambiente `browser-testing`, base `sgf_tempo_test`, papel `sgf_test_runner`, PostgreSQL 55432, sessão/cache em ficheiros isolados: [prova de ambiente](proofs/workshop-corrections-environment.json). Ficheiro de entrada e manifesto com ACL apenas do utilizador local/SYSTEM, fora do repositório. Credenciais anteriores de outros ensaios não devem ser reutilizadas. Nenhum login/fluxo visual de correcção é declarado executado por esta preparação. ## Migração proposta — NÃO aplicada `2026_10_28_130000_create_workshop_billing_corrections.php`, SQL `database/sql/workshop-corrections.sql`. Destino futuro proposto `sgf_tempo_dev` / `127.0.0.1:55432`, por caminho exclusivo com `sgf_dev_owner`; aplicação mantém `sgf_dev_app`. Exige autorização específica separada. Cria seis tabelas `wc_requests`, `wc_reviews`, `wc_applications`, `wc_commands`, `wc_events`, `wc_outbox`, constraints/FKs/índices/triggers e funções próprias; amplia CHECK com quatro permissões de unidade, sem concessões automáticas. Reforça funções de protecção dos rascunhos ligados já existentes e acrescenta trigger de elegibilidade em B1; não altera linhas ou fotografias existentes. INSERT nas seis tabelas exige `sgf_tempo_test`/55432, guarda operacional exige ambiente isolado seguro. `down()` recusa destruir história; nenhum reset de desenvolvimento ou instalação de dependências. ## Cinco concessões propostas — NÃO aplicadas Consulta read-only `scripts/workshop-corrections-permissions-preview.php` confirmou `130000` ausente, cinco concessões ausentes, pré-requisitos existentes e operação real bloqueada. Todas no **tenant #1 / Tempo Lda #1 / SEGI #1**: | Conta existente | Direitos exactos propostos | | --- | --- | | Osmane #1 | `workshop_corrections.view`, `workshop_corrections.request`, `workshop_corrections.apply` | | Samira #2 | `workshop_corrections.view`, `workshop_corrections.review` | Não herdar direitos da conversão, custos, contabilidade ou nomes. Não concede supervisão/verificação técnica, gestão de acessos, emissão, stock ou uso real. `110000`/`120000` instaladas anteriormente permanecem preservadas, sem reaplicação ou novas concessões por arrasto. ## Ficheiros e limites Novos: módulo `WorkshopCorrections.php`, estado comum `WorkshopCommercialState.php`, controlador, migração/SQL, `WorkshopCorrectionsWorkspace.jsx`, testes e fixture, scripts de concorrência/worker/fixture/pré-visualização e relatório/provas. Integrações em `ServiceWorkflow`, `InternalConfirmation`, `DocumentPreparation`, consulta `WorkshopBilling`, router, navegação/início e vistas de rascunho/conversão. Sem nova operação real, confirmação automática, fiscalidade, stock, recebimentos, lançamentos, publicação, aceitação ou checkpoint.