Accept technical extraction of shared budget core with QA limits
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
# Aceitação técnica — núcleo orçamental comum
|
||||
|
||||
29/10/2026. Decisão expressa da Tempo nesta sessão: aceitar `COMMON-BUDGET-SYNTHETIC-v1` **como extracção técnica do núcleo comum**, com checkpoint exclusivamente local nos dois repositórios. Referências: [entrega técnica](COMMON_BUDGET_DELIVERY.md), [plano](PURCHASING_COMMON_CORE_PLAN.md) e [provas dos dois hosts](proofs/common-budget-hosts.json).
|
||||
|
||||
A aceitação abrange a fonte única, os adaptadores locais, equivalência da sequência orçamental, protecções e provas técnicas descritas na entrega. Não significa aceitação visual, instalação de Compras integral no SGF ou autorização operacional real.
|
||||
|
||||
## Pendências preservadas
|
||||
|
||||
1. **Revisão visual de Compras pendente.** A tentativa de Computer Use foi interrompida por não ser possível determinar o URL do navegador com segurança. Não houve demonstração visual concluída dos valores/efeitos. Esta limitação de automação não bloqueia o desenvolvimento autorizado.
|
||||
2. **SGF demonstrado apenas pelo adaptador em QA.** Não existe interface deste percurso orçamental no SGF; prova de bootstrap/adaptador não equivale a revisão visual ou percurso integral disponível à equipa.
|
||||
3. **Cobertura MFA pendente em Compras.** Os testes ignorados são `users with two factor enabled are redirected to two factor challenge` (`tests/Feature/Auth/AuthenticationTest.php`) e `security page is displayed` (`tests/Feature/Settings/SecurityTest.php`). Ambos dependem de `Features::twoFactorAuthentication()`, desactivada na configuração actual. Não retiram a evidência das regras orçamentais, autorização/isolamento e concorrência testadas; não demonstram o fluxo de autenticação/página de segurança com MFA activo. MFA não foi activado nesta aceitação.
|
||||
|
||||
Compras conserva a interface e percursos existentes, agora delegando os efeitos orçamentais no núcleo comum; isso não autoriza utilização real nem supera os limites operacionais anteriores. SGF conserva o adaptador bloqueado fora do ambiente/base QA e o orçamento industrial separado.
|
||||
|
||||
## Checkpoint e continuação
|
||||
|
||||
Autoriza-se preservar apenas o incremento e os seus documentos/provas em Git local, sem credenciais, dados privados, push ou publicação. Alterações anteriores de outros incrementos permanecem na árvore de trabalho e não são incluídas por arrasto.
|
||||
|
||||
O próximo passo é disponibilizar um percurso sintético integrado no SGF para a equipa testar, reutilizando este núcleo, mantendo os direitos/contextos sintéticos e a separação entre demonstração e utilização real. Esta aceitação não activa migrações, concessões, dados de cliente, obrigações, pagamentos, contabilidade ou emissão real. A implementação desse percurso não foi realizada nesta passagem de encerramento técnico.
|
||||
|
||||
As menções anteriores a aceitação/checkpoint pendentes conservam-se como histórico e são substituídas apenas no âmbito desta extracção técnica. Revisão visual e cobertura MFA mantêm-se abertas.
|
||||
@@ -0,0 +1,100 @@
|
||||
# Controlo orçamental comum — entrega técnica em verificação
|
||||
|
||||
**Actualização posterior de 29/10/2026:** extracção técnica aceite pela Tempo, com autorização de checkpoint exclusivamente local. Ver [aceitação e pendências preservadas](COMMON_BUDGET_ACCEPTANCE.md). A revisão visual de Compras continua pendente; SGF continua demonstrado apenas pelo adaptador QA, sem interface deste percurso; os dois testes MFA ignorados continuam pendentes. As menções abaixo a aceitação/checkpoint por realizar são históricas; não há activação operacional decorrente desta aceitação.
|
||||
|
||||
29/10/2026. `COMMON-BUDGET-SYNTHETIC-v1`. Implementação do primeiro incremento de [desenho e transição](PURCHASING_COMMON_CORE_PLAN.md). **Sem aceitação presumida ou checkpoint de encerramento.** Apenas provas isoladas; nenhuma migração, concessão ou operação nas bases de desenvolvimento/produção. Não houve publicação ou push.
|
||||
|
||||
## Resultado e fronteira
|
||||
|
||||
Existe uma fonte única em `packages/budget-control`: `Tempo\Finance\Budget\BudgetControl`, contexto explícito `BudgetContext` e erro de domínio `BudgetFailure`. Foram retirados os algoritmos de movimentos/reforços/consumo de Compras; os percursos anteriores delegam neste núcleo. O núcleo grava dotação, aprovação, reforço, reserva, ajuste de adjudicação, compromisso, libertação permitida e consumo orçamental. Saldo/total aprovado também são calculados pelo núcleo.
|
||||
|
||||
Não chama `auth()`, sessão ou contexto global de uma aplicação, nem depende de Sales, recebimentos, contas a pagar, pagamentos, contabilidade ou de um SGF remoto. Usa `Illuminate\Database\ConnectionInterface` já disponibilizada pelos hosts, contexto imutável, tabelas por prefixo e callbacks locais de autorização/bloqueio/auditoria. A autorização é revalidada antes de qualquer replay; a auditoria participa na transacção do efeito.
|
||||
|
||||
O primeiro consumidor é Compras, nos seus percursos efectivos. O segundo é a composição reduzida de QA do SGF: bootstrap Laravel real, modelos de identidade/contexto/permissões reais e adaptador `app/Modules/Purchasing/BudgetAdapter.php`. O adaptador SGF recusa funcionar fora de `budget-testing` e de uma base descartável `budget_core_sgf_<12 hex>`, PostgreSQL local verificado. **Não se declara instalado o módulo completo de Compras no SGF, nova interface visual ou circuito de procurement SGF completo.** A origem SGF é uma referência sintética mapeada para testar o primeiro efeito comum; não é uma obrigação ou factura operacional.
|
||||
|
||||
## Dependências e valores
|
||||
|
||||
- Mantidos manifests/lockfiles: Laravel 13.39.0 / Brick Math 1.0.0 de Compras e Laravel 13.38.0 / Brick Math 0.14.8 do SGF. Nenhuma instalação, actualização ou substituição de dependências.
|
||||
- O núcleo usa os inteiros em centavos já gravados por Compras. Não calcula IVA, não converte câmbio e não introduz float. MZN é o recorte suportado; o adaptador Compras verifica a moeda empresarial antes/depois do bloqueio. Outras moedas permanecem explicitamente não suportadas.
|
||||
- Conversão decimal de entrada continua no Brick Math da aplicação Compras, exactamente pelos caminhos anteriores. Quantidades em milésimos, arredondamento HalfUp das linhas e cálculo cumulativo de facturas parciais permanecem em `InvoiceWorkflow`/serviços anteriores. Política SGF de truncagem do IVA de vendas não é aplicada a compras.
|
||||
- Não se recalcularam documentos nem se reescreveram valores históricos. O total inicial permanece imutável no percurso normal; apenas reforços aprovados contam para a dotação total.
|
||||
- A chave histórica `(requisition_id, kind)` continua a identificar o efeito. Replay idêntico não grava; o núcleo reconstrói o alvo monetário da entrada histórica para recusar replay com montante diferente, sem exigir hash ou migração retroactiva. Esta recusa é um reforço explícito: antes, o percurso de movimentos devolvia silenciosamente o efeito existente mesmo quando o montante pedido diferia. Não altera a história nem cria nova versão de documentos.
|
||||
|
||||
## Adaptadores e responsabilidade
|
||||
|
||||
| Ponto | Papel nesta entrega |
|
||||
| --- | --- |
|
||||
| Compras `app/Services/CommonBudget.php` | Confere sessão/actor, empresa, moeda e perfil actual; bloqueia empresa/actor; traduz erros; liga auditoria e elegibilidade do proponente |
|
||||
| Compras `BudgetWorkflow.php` | Conserva contrato dos chamadores, exigência de transacção exterior, vínculo da requisição e classificação corrente/investimento; delega o efeito |
|
||||
| Compras `BudgetReinforcementWorkflow.php` | Conserva conversão decimal/normalização de referência e retorno Eloquent; delega proposta/decisão |
|
||||
| Compras `BudgetController.php` | Conserva interface/validação/autorizações de origem; delega dotação, aprovação e saldos |
|
||||
| Compras `InvoiceWorkflow.php` | Conserva conferência de factura/preço/IVA/quantidades, actor distinto e auditoria `invoice.validated`; delega apenas consumo orçamental na mesma transacção |
|
||||
| Compras `Budget.php` | Mantém modelo/imutabilidade e usa a soma inteira comum do total aprovado |
|
||||
| SGF `app/Modules/Purchasing/BudgetAdapter.php` | Confere actor autenticado e contexto seleccionado, revalida membership/acções por unidade dentro do bloqueio e usa origens/centros explicitamente mapeados de QA |
|
||||
| `BudgetControl` | Único escritor do ledger/dotação/reforços dentro do recorte; não substitui elegibilidade de procurement ou conferência do documento |
|
||||
|
||||
Compras continua a tratar o seu `tenant_id` como empresa. SGF usa separadamente tenant/empresa/unidade; o teste cria identificadores diferentes e um centro de compras próprio. Nenhum departamento ou lote industrial é convertido implicitamente em unidade/dotação. O orçamento industrial existente do SGF não foi alterado.
|
||||
|
||||
## Fonte única e distribuição autónoma
|
||||
|
||||
O provider SGF carrega `packages/budget-control/bootstrap.php`. Compras procura o artefacto instalado em `packages/budget-control`, ou o caminho explícito `config/common-budget.php` / `COMMON_BUDGET_PATH`. Só em ambiente não produtivo existe fallback para a fonte canónica do checkout SGF vizinho. Não há chamadas remotas.
|
||||
|
||||
A prova autónoma empacota temporariamente apenas bootstrap e os três ficheiros de produção do núcleo, fora de ambos os projectos, e arranca Compras usando esse artefacto destacado. O teste exige que a classe efectivamente carregada venha do artefacto. O SGF carrega a fonte canónica. Os SHA-256 e traços normalizados coincidem. O artefacto temporário é eliminado no final, não constitui uma segunda fonte mantida. Para distribuição comercial, o artefacto local versionado terá de acompanhar Compras; não basta enviar o checkout sem o pacote. Automatização completa de releases/licenciamento não está incluída.
|
||||
|
||||
## Provas executadas
|
||||
|
||||
Comando dos dois hosts, a partir de Compras:
|
||||
|
||||
```powershell
|
||||
& 'C:\Users\macbook\.config\investmoz\php-8.5.11\php.exe' tests/Concurrency/run-common-budget.php
|
||||
```
|
||||
|
||||
O coordenador usa uma ligação administrativa à base de manutenção `postgres` exclusivamente para criar/eliminar duas bases novas. Não consulta ou migra bases de negócio. Em Compras aplica as migrações existentes apenas a `compras_receipts_test_<12 hex>` e usa as fixtures sintéticas existentes; no SGF aplica a fundação de identidade e o schema de QA apenas a `budget_core_sgf_<12 hex>`. Bases eliminadas no final. Configurações privadas são consumidas em processo, sem imprimir/versionar credenciais. Não se fez comparação de dados activos nem se reivindica checksum desses dados.
|
||||
|
||||
Evidência dirigida: [dois hosts e concorrência](proofs/common-budget-hosts.json). O relatório inclui hash do núcleo realmente carregado, igualdade dos traços, bases descartadas e ausência de revisão visual.
|
||||
|
||||
| Sequência, em ambos os hosts | Resultado em centavos |
|
||||
| --- | --- |
|
||||
| Dotação aprovada 100000; reserva 30000 repetida | Reservado 30000; disponível 70000 |
|
||||
| Ajuste da adjudicação para 35000 repetido | Reservado 35000; disponível 65000 |
|
||||
| Compromisso 35000 repetido | Reservado 0; comprometido 35000; disponível 65000 |
|
||||
| Consumo parcial 10000 repetido | Comprometido 25000; consumido 10000; disponível 65000 |
|
||||
| Reforço 20000 proposto | Disponível permanece 65000 |
|
||||
| Aprovação distinta do reforço repetida | Dotação total 120000; disponível 85000 |
|
||||
|
||||
Também passaram, nos dois hosts: recusa de aprovação própria; conflito de montante em replay; recusa de libertação já comprometida; isolamento de dotação entre empresas; libertação antes de compromisso uma única vez; base sem IVA usando subtotal original; falha SQL injectada na auditoria com rollback da reserva e retry sem duplicação; replay de decisão com permissão entretanto revogada. No SGF: origem de outra empresa recusada, unidade reservada recusada e contexto mudado após obter o serviço recusado.
|
||||
|
||||
**Concorrência PostgreSQL: oito cenários aprovados, quatro por host.** Duas ligações/processos PHP independentes, com dois waits de bloqueio observados em cada cenário: duas reservas acima do saldo conjunto; repetição da mesma reserva; repetição do mesmo compromisso; repetição da mesma libertação. No excesso apenas um efeito de 6000 cabe na dotação 10000; nos replays ambos os pedidos obtêm sucesso e o saldo só muda uma vez. Não é uma prova de todas as corridas possíveis ou teste de carga.
|
||||
|
||||
## Regressões e compilação
|
||||
|
||||
- Referência antes da alteração: 75 testes dirigidos / 317 asserções aprovados. Mesma bateria após extracção: 75 / 317, sem mudar expectativas existentes.
|
||||
- Regressão completa Compras: **498 aprovados, 2 ignorados, 4141 asserções**, incluindo percursos/autorização existentes. Os dois ignorados são as limitações MFA anteriormente documentadas; não se declarou cobertura nova desses casos.
|
||||
- PHPStan Compras: zero erros. Pint dos ficheiros de produção alterados: aprovado. Sintaxe PHP 8.4 do pacote/adaptador/fixtures SGF: aprovada.
|
||||
- Compilação Compras: `npm.cmd run build`, aprovada; compilação SGF: `scripts/sgf.ps1 npm run build`, aprovada. Sem alterações de dependências; geração Wayfinder ocorreu pelo build habitual.
|
||||
- A suite destrutiva SGF normal não foi executada sobre `sgf_tempo_test`, para preservar a demonstração da equipa. O delta SGF foi verificado no host/bootstrap real com base descartável e nas verificações acima. Não se atribui regressão integral de todos os módulos SGF a esta prova.
|
||||
- Uma tentativa inicial com outro PHP existente falhou por falta do driver SQLite, sem asserções ou alteração de base. A bateria válida usou o executável já instalado com SQLite. O primeiro comando `npm` foi recusado pela política PowerShell; usou-se `npm.cmd`, sem mudar a política.
|
||||
|
||||
## Ficheiros deste incremento
|
||||
|
||||
**Fonte comum no SGF:** `packages/budget-control/bootstrap.php`, `README.md`, `src/BudgetContext.php`, `src/BudgetFailure.php`, `src/BudgetControl.php`; provas reproduzíveis em `tests/host-support.php`, `tests/run-host.php`, `tests/sgf-schema.php` dentro do mesmo pacote.
|
||||
|
||||
**SGF:** `app/Providers/AppServiceProvider.php`, `app/Modules/Purchasing/BudgetAdapter.php`, este relatório, `docs/proofs/common-budget-hosts.json` e referências nos documentos/instruções existentes.
|
||||
|
||||
**Compras:** `app/Providers/AppServiceProvider.php`, `config/common-budget.php`, `app/Services/CommonBudget.php`, `BudgetWorkflow.php`, `BudgetReinforcementWorkflow.php`, `InvoiceWorkflow.php`, `app/Models/Budget.php`, `app/Http/Controllers/BudgetController.php`, `tests/Concurrency/run-common-budget.php` e referências nos relatórios existentes.
|
||||
|
||||
Alterações anteriores de oficinas/navegação, fontes e histórico SGF e documentação prévia de Compras foram preservadas, sem commit, reset ou checkout. Não são atribuídas a este incremento.
|
||||
|
||||
## Migrações para desenvolvimento/produção — separadas e não executadas
|
||||
|
||||
**Compras:** o adaptador conserva as tabelas/colunas/índices existentes; esta extracção não necessita de migração SQL para os efeitos existentes. Não foram executadas migrações nessas bases. A distribuição tem de incluir o pacote e conservar os seus originais e lockfiles.
|
||||
|
||||
**SGF:** o único schema executado é a fixture `packages/budget-control/tests/sgf-schema.php`, que tem guarda QA e não está registada em `database/migrations`. Documenta `cb_centres`, `cb_origins`, `cb_budgets`, `cb_budget_entries`, `cb_budget_consumptions`, `cb_budget_reinforcements`, `cb_audit` e as sete acções `purchasing_budget.*`, mais a extensão da constraint de permissões na base nova. Nenhuma concessão real foi instalada.
|
||||
|
||||
A futura migração SGF terá de adaptar essas referências aos cadastros definitivos de Purchasing/Platform, completar constraints compostas de pertença e políticas de imutabilidade, conferir schema/permissões de destino e ser ensaiada com backup/restauro. Não apresentar esta fixture como migração operacional pronta nem retirar a guarda para apontar para `sgf_tempo_dev`. Não fundir tabelas/IDs/históricos existentes por igualdade numérica.
|
||||
|
||||
## Limitações e próximos passos
|
||||
|
||||
Revisão visual não realizada; nenhum ecrã novo apresentado como aceite. SGF demonstra o efeito orçamental do primeiro incremento, não Compras integral instalado. O pacote não inclui obrigações, pagamentos ou contabilidade, emissão real, câmbio, novas reversões ou cancelamento de ordens já emitidas. A revogação/concessão de direitos reais permanece fora desta entrega.
|
||||
|
||||
Próximo passo dentro desta entrega: revisão do desenho/código/provas e dificuldades que a equipa identificar, sem presumir aceitação. Depois, preparar o empacotamento e os pontos de montagem do módulo completo nos dois produtos com os cadastros definitivos. T2 (obrigações), T3 (pagamentos) e restantes passos do plano não foram iniciados. As capacidades inexistentes continuam pendentes, sem motores fictícios ou reaproveitamento indevido de recebimentos de clientes/orçamento industrial.
|
||||
@@ -0,0 +1,147 @@
|
||||
# Compras e núcleo financeiro comum — desenho e transição
|
||||
|
||||
**Actualização de execução, 29/10/2026:** primeiro incremento implementado e tecnicamente demonstrado em hosts sintéticos, conforme [entrega e limites](COMMON_BUDGET_DELIVERY.md). A marcação de desenho/não executado abaixo conserva o estado da proposta original. Não há aceitação, implantação ou extracção integral de Compras presumidas; T2 e seguintes não foram iniciados.
|
||||
|
||||
29/10/2026. Estado: desenho técnico revisto e primeiro incremento delimitado; reestruturação e provas ainda não executadas. Referência principal para os dois projectos. Não substitui as matrizes de requisitos ou as aceitações existentes.
|
||||
|
||||
## 1. Decisão expressa e alcance
|
||||
|
||||
Decisão da Tempo: **um módulo de Compras, um núcleo financeiro comum e duas composições comerciais**. O ERP SGF inclui Compras. A composição Compras autónomo inclui as capacidades comuns necessárias, sem exigir a facturação de vendas SGF nem um SGF remoto. Os percursos entregues são preservados. Esta orientação substitui a proposta anterior de duas aplicações ligadas por conector remoto como arquitectura principal.
|
||||
|
||||
Desenvolvimento e validação usam organizações, unidades, contas e operações sintéticas; pessoas reais e concessões na Tempo pertencem à implantação. As configurações, dados, aprovações e alterações posteriores dos dois projectos mantêm-se. Nesta passagem alterou-se apenas documentação; não se leram credenciais, executaram bases/testes ou alteraram dependências.
|
||||
|
||||
Origem das restrições: composição comercial, núcleo único, preservação e uso sintético são decisões expressas da Tempo. Organização em pacotes, transacção local, contratos e sequência abaixo são propostas de implementação. Regras empresariais continuam a ser as aprovadas e versionadas, não políticas universais criadas pela modularização.
|
||||
|
||||
## 2. Duas composições, a mesma implementação
|
||||
|
||||
| Componente | ERP SGF | Compras autónomo |
|
||||
| --- | --- | --- |
|
||||
| Plataforma comum: identidade, empresa fiscal/unidade, autorizações, auditoria e comandos | Incluída | Incluída na extensão necessária ao produto |
|
||||
| Núcleo financeiro comum e suas migrações | Uma implementação local | A mesma implementação local/versionada |
|
||||
| Módulo de Compras e seus percursos | Incluído | Incluído |
|
||||
| Facturação de vendas, oficinas, produção e outros módulos ERP | Conforme composição | Não obrigatórios para instalar, entrar, comprar ou pagar fornecedores |
|
||||
| Comunicação entre Compras e financeiro | Interfaces de aplicação no mesmo processo | As mesmas interfaces no mesmo processo |
|
||||
|
||||
Autonomia é autonomia de instalação e utilização, não outra cópia das regras. As duas instalações de clientes diferentes têm naturalmente os seus próprios dados; não se pretende sincronizar automaticamente essas instalações. Integração com facturação externa poderá ser opcional e contratada separadamente, nunca condição para usar Compras.
|
||||
|
||||
Proposta de estrutura lógica: `Platform` (contexto/acesso/auditoria), `Finance` (capacidades financeiras comuns), `Inventory` (movimentos físicos comuns), `Purchasing` (procurement), `Sales` e restantes módulos SGF. Stock físico não é contabilidade geral; ambos têm responsáveis definidos. As dependências apontam de Purchasing/Sales para contratos comuns, sem Finance depender dos controladores ou tabelas de vendas.
|
||||
|
||||
Os nomes e o formato físico dos pacotes são escolhas técnicas. A fonte de cada módulo deve ser única, com namespace próprio, versão e testes. Não copiar `App/Services` de Compras para outro `App/Modules` e continuar a manter ambos. Durante a transição, fachadas antigas delegam para o serviço extraído; não executam também a lógica antiga. Distribuir os mesmos artefactos em duas composições, sem exigir caminhos relativos entre repositórios no cliente.
|
||||
|
||||
No modo instalado, preferir uma ligação transaccional local para documento, efeito e auditoria quando pertencem à mesma operação. Separar propriedade das tabelas por módulo não exige bases separadas. Não unir agora as bases existentes, tabelas `users`/`tenants`, identificadores, históricos ou sessões. A estratégia exacta de schema será demonstrada em instalação sintética antes de qualquer migração de cliente.
|
||||
|
||||
## 3. Percursos de Compras a preservar
|
||||
|
||||
Referências relativas a `C:/laragon/www/compras`. As provas anteriores são reutilizadas; acrescentar verificações apenas do delta. Estado de implementação não equivale a autorização operacional real.
|
||||
|
||||
| Percurso preservado | Implementação de referência | Preservação na composição SGF/autónoma |
|
||||
| --- | --- | --- |
|
||||
| Empresa/equipa, departamentos e centros | `app/Http/Controllers/CompanyController.php`; `app/Enums/PurchasingRole.php` | Adaptar contexto e acesso sem alargar poderes; manter utilizadores e direitos históricos |
|
||||
| Planeamento e marcos ligados à requisição | `app/Services/PurchasePlanningWorkflow.php` | Manter versões, responsáveis e ausência de reserva pelo simples planeamento |
|
||||
| Requisição, linhas e aprovações sequenciais | `app/Services/RequisitionWorkflow.php` | Manter autoria, limites/base congelados, decisões distintas, exactidão e histórico |
|
||||
| Fornecedor, documentos e dados bancários | `SupplierBankWorkflow.php`; controladores `SupplierController.php`/`SupplierDocumentController.php` | Preservar revisões, dupla validação bancária, cifragem e documentos privados |
|
||||
| Cotações, matriz e conflitos | `ProposalComparison.php`; `ConflictGuard.php`; `QuotationController.php` | Mesmos critérios e elegibilidade; não reutilizar direitos de vendas |
|
||||
| Abertura, qualificação, admissão e recomendação | `ProposalOpeningWorkflow.php`; `DocumentaryQualificationWorkflow.php`; `FormalAdmission.php`; `FormalRecommendation.php` | Preservar adopções opcionais, políticas por versão, bases, quóruns e decisões |
|
||||
| Adjudicação, aprovação final e ordem | `PurchaseWorkflow.php`; `InvestmentWorkflow.php` | Manter nova aprovação do valor final, ordem única, snapshots e requisitos de investimento |
|
||||
| Revisão/cancelamento antes de ordem | `PurchaseControlPolicyWorkflow.php`; `PurchaseRevisionWorkflow.php` | Preservar limites, libertação única e novo rascunho sem herdar decisões; não alargar a ordens emitidas |
|
||||
| Recepção, qualidade e aceitação parcial | `ReceiptWorkflow.php` | Mesmas quantidades aceites, segregação, guia e origem única do movimento físico |
|
||||
| Stock, equipamentos e peças | `StockWorkflow.php`; `EquipmentWorkflow.php` | Manter armazéns, saldos, saídas, transferências, contagens, ajustes e rastreabilidade |
|
||||
| Dotação, reforço, reserva e compromisso | `BudgetWorkflow.php`; `BudgetReinforcementWorkflow.php` | Extrair a capacidade financeira existente; não criar orçamento paralelo no SGF |
|
||||
| Factura recebida e conferência | `InvoiceWorkflow.php` | Preservar preço/unidade/IVA da ordem, aceitação física e facturação parcial cumulativa |
|
||||
| Pagamento externo e conferência | `ExternalPaymentWorkflow.php` | Manter saldo, versão bancária e confirmação independente; não executar transferências |
|
||||
| Processo único, auditoria e impressão | `PurchaseProcessController.php`; `ProcurementReviewReport.php`; `routes/web.php` | Conservar documentos e leitura histórica, com navegação adaptável às duas composições |
|
||||
|
||||
Os serviços sem caminho completo nesta tabela ficam em `app/Services`; os controladores ficam em `app/Http/Controllers`. `docs/validacao-tecnica.md` já descreve recomendação/migração 000020; resumos ainda referidos a 000017 são anteriores, não indício de perda. Não reabrir a aceitação dos incrementos conservados nem declarar executadas novas provas a partir desses relatórios.
|
||||
|
||||
## 4. Capacidades comuns e um responsável por efeito
|
||||
|
||||
Responsável significa o módulo/serviço que valida e grava o efeito, não uma pessoa real. Um documento pode originar efeitos diferentes, cada um com identidade e responsável próprios; não deve provocar duas gravações do mesmo efeito.
|
||||
|
||||
| Capacidade/efeito | Existente e origem | Falta desenvolver/adaptar | Único responsável de destino |
|
||||
| --- | --- | --- | --- |
|
||||
| Contexto empresarial e autorização | SGF: `CompanyContext`, `Permissions`, memberships/unidades. Compras: tenant=empresa, perfil/departamento e `CurrentActor` | Contrato comum e adaptação dos perfis; unidade não equivale a departamento/armazém | Platform; Purchasing conserva a elegibilidade e segregação do seu processo |
|
||||
| Montantes e quantidades | Compras: centavos, milésimos e HalfUp; SGF: decimais exactos/racionais e política própria de IVA de serviços | Tipos/contratos com moeda, escala, unidade e política explícitas; sem uniformizar resultados históricos | Política de cálculo identificada por domínio/versão; Finance valida representação dos efeitos monetários |
|
||||
| Dotação e reforço | Compras: `Budget`, `BudgetReinforcement`, aprovações e histórico | Extrair reutilizando regras existentes e generalizar origem sem perder controlos | Finance/BudgetControl |
|
||||
| Reserva, ajuste na adjudicação, compromisso, libertação permitida e consumo | Compras: `BudgetWorkflow`, `InvoiceWorkflow`, `budget_entries`, `budget_consumptions` | Unificar todos os escritores desses efeitos, idempotência por origem e transacção local | Finance/BudgetControl; Purchasing pede o efeito e valida o processo |
|
||||
| Orçamento industrial previsto/realizado | SGF: `app/Modules/Industry/IndustrialBudgets.php`, simulação aceite | Articular dimensões futuras; não substituir controlo de disponibilidade por comparação de custo | Industry/CostPlanning; não é outro escritor do ledger de dotações |
|
||||
| Factura recebida e obrigação a fornecedor | Compras: registo e conferência em `InvoiceWorkflow` | Serviço comum de contas a pagar, vencimentos/condições e correcções; preservar documento de origem | Purchasing confere factura; Finance/Payables grava a obrigação uma vez |
|
||||
| Pagamento e afectação à obrigação | Compras: registo/conferência externo em `ExternalPaymentWorkflow` | Extrair mecanismo para Finance/Treasury/Payables; execução bancária e conciliação completa não demonstradas | Finance; Purchasing recebe estado/consulta e não liquida de novo |
|
||||
| Facturação de vendas e recebimentos | SGF: `ServiceInvoicing`, `ServiceReceivables`, emissão/recebimentos delimitados de teste | Interfaces financeiras comuns futuras; contas a receber não substituem contas a pagar | Sales conserva documento; Finance a receber/tesouraria quando extraído; nenhuma dependência comercial obrigatória em Compras |
|
||||
| Quantidade física e saldo por armazém | Compras: `ReceiptWorkflow`, `StockWorkflow`, `StockMovement` | Extrair Inventory comum e delegar entradas/saídas de todos os consumidores; não presumir método de valorização | Inventory, invocado uma vez por origem; Purchasing aceita recepção e Workshop declara consumo |
|
||||
| Custo directo/industrial | SGF: `DirectCosts`, `IndustrialCosts` e `ExactCostMath`, actualmente sintéticos | Ligar movimentos e taxas identificados, sem repetir consumo físico ou custo | Serviços de custos comuns/Industry conforme natureza; Inventory continua dono da quantidade |
|
||||
| Classificação e conhecimento fiscal | SGF: `CatalogueAccounting`, `ServiceFiscal`; requisitos FIS-SGF-13 a 19 | Completar consumidor de compras e vigência/dedutibilidade; reutilizar conhecimento aceite | Finance/TaxAccounting, com regra e período explícitos; taxa da cotação não confirma dedutibilidade |
|
||||
| Lançamento, razão, fecho e modelos | SGF: âmbito descrito em `SERVICE_INVOICE_CALCULATION_SPEC.md`, não motor geral concluído | Construir capacidades e ligações em falta com origem/versão e correcções | Finance/GeneralLedger e Finance/TaxReporting; nenhum lançamento implícito na migração/importação |
|
||||
| Auditoria e repetição de comandos | Ambos: histórico, transacções, chaves/hash em percursos específicos | Contrato de comando/origem e correlação comuns; preservar protecções existentes | Platform regista auditoria; cada serviço mantém unicidade do seu efeito na mesma transacção |
|
||||
|
||||
Um núcleo financeiro comum não significa que todas as suas capacidades já existam no SGF. Parte será formada por extracção do código de Compras; parte pelas capacidades SGF já demonstradas; parte terá de ser desenvolvida. Receber factura não é emitir factura de vendas. Compromisso orçamental, obrigação, pagamento, movimento físico e lançamento são efeitos distintos.
|
||||
|
||||
## 5. Dependências e compatibilidade antes da extracção
|
||||
|
||||
1. Ambos usam Laravel 13, mas `composer.lock` difere: Compras Laravel 13.39.0/Brick Math 1.0.0; SGF Laravel 13.38.0/Brick Math 0.14.8. Escolher uma combinação suportada para o pacote no ensaio sintético; não actualizar manifests/lockfiles dos clientes automaticamente. Dependência incompatível é um problema concreto de implementação, não motivo para duplicar o motor.
|
||||
2. Compras usa Inertia/TypeScript; SGF usa React/JSX e JSON de sessão. Primeiro separar aplicação/domínio da apresentação. Preservar ecrãs Compras, permitindo layouts diferentes; não reescrever todo o frontend para demonstrar o primeiro efeito partilhado.
|
||||
3. `BelongsToTenant` e `CurrentActor` de Compras dependem de `auth()`; SGF usa selecção empresa/unidade e token de contexto. Definir actor/contexto explícitos e adaptadores locais revalidáveis. Não desactivar filtros ou conceder poderes globais para acomodar o pacote.
|
||||
4. Um utilizador Compras tem actualmente um tenant/perfil/departamento; o SGF permite memberships e concessões. Definir correspondência sem usar email, nome ou igualdade de IDs como autoridade. Conta multiempresa e eventual evolução do modelo Compras exigem testes específicos; a extracção inicial pode limitar o cenário sintético a uma empresa/unidade, declarando a cobertura.
|
||||
5. Não reaproveitar os nomes `tenants`/`users` para fundir tabelas automaticamente. Namespace próprio e uma migração proprietária de cada tabela; manter referências de origem e regras de acesso. Não juntar histórias de migrações ou copiar schemas de clientes para o novo ensaio.
|
||||
6. As tabelas outbox SGF capturadas/sintéticas não são um serviço financeiro executável. Chamadas locais são suficientes para a primeira composição; não introduzir conector remoto, broker ou transacção distribuída como dependência.
|
||||
|
||||
## 6. Transição gradual
|
||||
|
||||
| Passo | Resultado | Preservação / condição de passagem |
|
||||
| --- | --- | --- |
|
||||
| T0 — este desenho | Percursos, efeitos, responsáveis e primeiro incremento delimitados | Documentação apenas; nenhuma aceitação funcional nova |
|
||||
| T1 — controlo orçamental comum | Um serviço, contratos locais e dois hosts sintéticos exercitam o mesmo pacote | Paridade das regras/resultados existentes; todos os escritores do ledger delimitado passam pela mesma implementação |
|
||||
| T2 — factura recebida e contas a pagar | Documento conferido origina uma obrigação comum; ecrãs/decisões Compras conservados | Sem emissão de venda obrigatória; consumo orçamental não repetido; correcções no âmbito implementado |
|
||||
| T3 — pagamentos comuns | Extrair registo, conferência e afectação externa existentes; ligar obrigação | Um pagamento/afectação por origem; sem execução bancária presumida; preservar validação bancária |
|
||||
| T4 — inventário e custos | Extrair movimentos físicos existentes e ligar consumidores SGF | Uma origem física, um movimento; valorizações e regras de custo explícitas |
|
||||
| T5 — contabilidade/fiscalidade e composições completas | Completar consumidores, modelos e empacotamento das duas instalações | Conformidade/implantação por capacidade e cliente; sem obrigar a facturação de vendas |
|
||||
|
||||
A ordem é incremental e pode ser ajustada por dependências demonstradas. Enquanto uma capacidade não foi extraída, mantém-se o seu escritor actual. Quando passar ao módulo comum, a fachada antiga apenas delega. Não manter dois fornecedores seleccionáveis para a mesma capacidade nas duas composições finais, nem comparar em paralelo gravando duas vezes. Comparações de paridade usam rollback ou leitura sem efeitos.
|
||||
|
||||
Dados históricos não são executados de novo como comandos. A transição de um cliente exige inventário de código/schema/dados/permissões equivalentes, backup/restauro e migração aditiva ensaiada. Preservar identificadores públicos/documentos/snapshots ou manter correspondência imutável, sem usar a extracção para recalcular IVA ou reaprovar processos concluídos. Reversão da versão de código não pode apagar efeitos ou deixar dois escritores activos; planear compatibilidade e recuperação antes de qualquer aplicação real.
|
||||
|
||||
## 7. Primeiro incremento delimitado — COMMON-BUDGET-SYNTHETIC-v1
|
||||
|
||||
**Objectivo:** demonstrar, em dois hosts de instalação sintéticos, a mesma implementação local de controlo orçamental proveniente de Compras, sem carregar vendas/facturação SGF como dependência.
|
||||
|
||||
**Incluído:** contrato de actor/contexto, origem do comando, moeda/base/exercício/centro, identidade idempotente e decisão elegível; operações existentes de dotação/reforço, reserva, ajuste de adjudicação, compromisso, libertação apenas no âmbito actualmente permitido e consumo por factura. Consolidar leitura de disponibilidade, ledger e auditoria, sem novo método de cálculo ou política empresarial. Pedidos sem dotação mantêm a distinção histórica de documento de desenvolvimento não controlado; não reinterpretar isso como controlo aprovado para utilização real.
|
||||
|
||||
**Fronteira de código prevista:** extrair de `BudgetWorkflow.php`, `BudgetReinforcementWorkflow.php`, operações orçamentais dos controladores de orçamento e de `InvoiceWorkflow::validate`, com `Budget`, `BudgetEntry`, `BudgetConsumption` e `BudgetReinforcement`. Manter as decisões de procurement e a conferência da factura nos seus serviços. Inventariar todos os pontos de escrita dessas tabelas antes da primeira alteração e incluir os testes/concorrência de orçamento e reforço existentes. Os ficheiros são pontos de origem, não autorização para copiar duas implementações.
|
||||
|
||||
**Dois hosts de prova:** composição Compras autónomo e composição ERP SGF reduzida com Purchasing, Platform e Finance. Ambos usam o mesmo artefacto/versionamento; cada um instala a sua base sintética isolada. Exercitar o circuito de aplicação real do módulo em cada host, não apenas um teste unitário com duas etiquetas. As entidades/actores de teste não são contas reais e não dependem de Osmane/Samira. A montagem visual completa do ERP não é condição para esta prova de extracção, mas o host deve carregar o módulo e os seus adaptadores de forma efectiva.
|
||||
|
||||
**Excluído:** alterações nas bases/clientes existentes, concessões reais, migração da Tempo, reestruturação integral do frontend, vendas, emissão fiscal, novo livro geral, criação de pagamentos, execução bancária, stock/valorização e novas regras de cancelamento. O consumo por factura é só o efeito orçamental existente, não a implementação antecipada de Payables. Não mover operações fora do incremento por arrasto.
|
||||
|
||||
**Critério de saída:** mesmas entradas produzem o mesmo ledger/saldos/recusas nos dois hosts, utilizando a mesma implementação, preservando base com/sem IVA, segregação, histórico e transacção. Uma origem gera um único efeito, replay idêntico recupera o resultado e conflito de conteúdo é recusado. Factura parcial consome apenas o montante devido, compromisso não é consumido duas vezes e falha da auditoria reverte o movimento. Os testes devem demonstrar revogação de direito e concorrência PostgreSQL. Artefacto Compras instala/arranca sem Sales ou SGF remoto.
|
||||
|
||||
Este incremento fica delimitado para orientar a próxima reestruturação. Não foi implementado ou aceite nesta passagem; as dependências acima deverão ser resolvidas no ensaio isolado, sem nova aprovação de cada pequeno passo técnico.
|
||||
|
||||
## 8. Plano de provas sintéticas, não executadas nesta passagem
|
||||
|
||||
| Prova nos dois modos | Resultado exigido |
|
||||
| --- | --- |
|
||||
| Instalação autónoma sem Sales e sem rede para SGF | Arranque, contexto, procurement e controlo orçamental funcionam localmente |
|
||||
| Instalação ERP com Purchasing | Mesmo pacote/migrações, serviços e resultados; sem segundo serviço de orçamento |
|
||||
| Empresa A/B, unidade central/reservada, IDs coincidentes | Nenhum acesso ou movimento cruzado; contexto incompatível recusado |
|
||||
| Proponente, aprovador, comprador e conferente sintéticos | Direitos explícitos; pessoa não valida a própria operação; revogação revalidada na transacção |
|
||||
| Dotação 1000, reserva 300, ajuste para 350, compromisso 350, consumo parcial 100 | Ledger conserva os deltas; 100 consumidos e 250 comprometidos; disponível 650, sem dupla subtracção |
|
||||
| Reforço 200 proposto e depois aprovado distintamente | Disponível só aumenta após aprovação; replay não aumenta outra vez |
|
||||
| Mesmo comando repetido; chave igual com conteúdo diferente | Mesmo resultado sem novo efeito; conflito explícito no segundo caso |
|
||||
| Duas reservas simultâneas acima do saldo conjunto | Uma recusa ou espera conforme serialização; saldo nunca negativo |
|
||||
| Falha entre documento, movimento e auditoria | Rollback local integral; repetição segura e sem reserva órfã |
|
||||
| Cancelamento permitido antes de compromisso / ordem já emitida | Libertação única só no primeiro âmbito; manter recusa no segundo |
|
||||
| Moeda/base/exercício ausentes ou incompatíveis | Pendência/recusa explicável, sem zero ou política inventada |
|
||||
| Migração sintética e recuperação da versão | Contagens/origens/histórico conservados; nenhum replay de documentos históricos |
|
||||
|
||||
Provas futuras T2–T5 acrescentam obrigação única, pagamento parcial, versões bancárias, movimento físico único, origem até lançamento e compatibilidade de regra/modelo fiscal. Não são critérios artificialmente antecipados para bloquear T1. Reutilizar provas aceites e registar apenas o delta nas matrizes/relatórios existentes. Demonstração persistente da equipa e bases destrutivas de regressão precisam de ambientes separados; não executar testes de extracção na demonstração SGF existente.
|
||||
|
||||
## 9. Referências SGF e cobertura documental
|
||||
|
||||
- `AGENTS.md`: decisões de produto e preservação; âmbito sintético.
|
||||
- `docs/PRODUCT_DEMO.md`: capacidades existentes e demonstração, sem contabilidade geral presumida.
|
||||
- `docs/SERVICE_INVOICE_CALCULATION_SPEC.md`, FIS-SGF-13 a 19: requisitos de compras/classificação, stock, contabilidade, custos e modelos; estados e critérios mantidos, sem nova matriz de requisitos.
|
||||
- `app/Shared/Context/CompanyContext.php`, `app/Modules/Identity/Services/Permissions.php`: contexto/acessos existentes.
|
||||
- `app/Modules/Services/ServiceCalculation.php`, `DraftValues.php`, `ServiceReceivables.php`, `CatalogueAccounting.php`: semântica financeira/fiscal existente e limites.
|
||||
- `app/Modules/Industry/IndustrialBudgets.php`, `IndustrialCosts.php`: orçamento de custo e custeio industrial distintos de dotação de procurement.
|
||||
- `composer.json`/`composer.lock` dos dois projectos: dependências reais a reconciliar na extracção.
|
||||
|
||||
Pendências específicas de desenho: forma física/versionamento/distribuição dos pacotes; schema sintético e estratégia futura de migração; correspondência multiempresa/unidade/departamento; combinação de dependências suportada. São decisões de implementação a demonstrar em QA, não requisitos para criar pessoas reais nem pretexto para um segundo motor financeiro.
|
||||
@@ -0,0 +1,247 @@
|
||||
{
|
||||
"version": "COMMON-BUDGET-SYNTHETIC-v1",
|
||||
"checked_at": "2026-10-29T11:07:06+00:00",
|
||||
"client_databases_touched": false,
|
||||
"hosts": [
|
||||
{
|
||||
"host": "compras",
|
||||
"passed": true,
|
||||
"detached_package_artifact": true,
|
||||
"core_sha256": "1349d1ab4ab58a83c9abbf43549ebe7e4ed77717ed5463a2defac748cf7b9a31",
|
||||
"steps": {
|
||||
"reserve": {
|
||||
"approved_total_minor": 100000,
|
||||
"reinforced_minor": 0,
|
||||
"reserved_minor": 30000,
|
||||
"committed_minor": 0,
|
||||
"consumed_minor": 0,
|
||||
"available_minor": 70000
|
||||
},
|
||||
"award": {
|
||||
"approved_total_minor": 100000,
|
||||
"reinforced_minor": 0,
|
||||
"reserved_minor": 35000,
|
||||
"committed_minor": 0,
|
||||
"consumed_minor": 0,
|
||||
"available_minor": 65000
|
||||
},
|
||||
"commit": {
|
||||
"approved_total_minor": 100000,
|
||||
"reinforced_minor": 0,
|
||||
"reserved_minor": 0,
|
||||
"committed_minor": 35000,
|
||||
"consumed_minor": 0,
|
||||
"available_minor": 65000
|
||||
},
|
||||
"consume": {
|
||||
"approved_total_minor": 100000,
|
||||
"reinforced_minor": 0,
|
||||
"reserved_minor": 0,
|
||||
"committed_minor": 25000,
|
||||
"consumed_minor": 10000,
|
||||
"available_minor": 65000
|
||||
},
|
||||
"reinforcement": {
|
||||
"approved_total_minor": 120000,
|
||||
"reinforced_minor": 20000,
|
||||
"reserved_minor": 0,
|
||||
"committed_minor": 25000,
|
||||
"consumed_minor": 10000,
|
||||
"available_minor": 85000
|
||||
}
|
||||
},
|
||||
"races": [
|
||||
{
|
||||
"scenario": "over_reserve",
|
||||
"passed": true,
|
||||
"observed_lock_waits": 2,
|
||||
"balance": {
|
||||
"approved_total_minor": 10000,
|
||||
"reinforced_minor": 0,
|
||||
"reserved_minor": 6000,
|
||||
"committed_minor": 0,
|
||||
"consumed_minor": 0,
|
||||
"available_minor": 4000
|
||||
}
|
||||
},
|
||||
{
|
||||
"scenario": "same_reserve",
|
||||
"passed": true,
|
||||
"observed_lock_waits": 2,
|
||||
"balance": {
|
||||
"approved_total_minor": 10000,
|
||||
"reinforced_minor": 0,
|
||||
"reserved_minor": 6000,
|
||||
"committed_minor": 0,
|
||||
"consumed_minor": 0,
|
||||
"available_minor": 4000
|
||||
}
|
||||
},
|
||||
{
|
||||
"scenario": "same_commit",
|
||||
"passed": true,
|
||||
"observed_lock_waits": 2,
|
||||
"balance": {
|
||||
"approved_total_minor": 10000,
|
||||
"reinforced_minor": 0,
|
||||
"reserved_minor": 0,
|
||||
"committed_minor": 6000,
|
||||
"consumed_minor": 0,
|
||||
"available_minor": 4000
|
||||
}
|
||||
},
|
||||
{
|
||||
"scenario": "same_release",
|
||||
"passed": true,
|
||||
"observed_lock_waits": 2,
|
||||
"balance": {
|
||||
"approved_total_minor": 10000,
|
||||
"reinforced_minor": 0,
|
||||
"reserved_minor": 0,
|
||||
"committed_minor": 0,
|
||||
"consumed_minor": 0,
|
||||
"available_minor": 10000
|
||||
}
|
||||
}
|
||||
],
|
||||
"checks": [
|
||||
"independent_approval",
|
||||
"partial_consumption",
|
||||
"same_command_replay",
|
||||
"changed_replay_rejected",
|
||||
"committed_release_refused",
|
||||
"reinforcement_pending_and_approved",
|
||||
"tenant_isolation",
|
||||
"release_once",
|
||||
"net_tax_basis",
|
||||
"audit_rollback_and_retry",
|
||||
"revoked_reviewer_replay"
|
||||
],
|
||||
"sgf_context_checks": [],
|
||||
"visual_review": false
|
||||
},
|
||||
{
|
||||
"host": "sgf",
|
||||
"passed": true,
|
||||
"detached_package_artifact": false,
|
||||
"core_sha256": "1349d1ab4ab58a83c9abbf43549ebe7e4ed77717ed5463a2defac748cf7b9a31",
|
||||
"steps": {
|
||||
"reserve": {
|
||||
"approved_total_minor": 100000,
|
||||
"reinforced_minor": 0,
|
||||
"reserved_minor": 30000,
|
||||
"committed_minor": 0,
|
||||
"consumed_minor": 0,
|
||||
"available_minor": 70000
|
||||
},
|
||||
"award": {
|
||||
"approved_total_minor": 100000,
|
||||
"reinforced_minor": 0,
|
||||
"reserved_minor": 35000,
|
||||
"committed_minor": 0,
|
||||
"consumed_minor": 0,
|
||||
"available_minor": 65000
|
||||
},
|
||||
"commit": {
|
||||
"approved_total_minor": 100000,
|
||||
"reinforced_minor": 0,
|
||||
"reserved_minor": 0,
|
||||
"committed_minor": 35000,
|
||||
"consumed_minor": 0,
|
||||
"available_minor": 65000
|
||||
},
|
||||
"consume": {
|
||||
"approved_total_minor": 100000,
|
||||
"reinforced_minor": 0,
|
||||
"reserved_minor": 0,
|
||||
"committed_minor": 25000,
|
||||
"consumed_minor": 10000,
|
||||
"available_minor": 65000
|
||||
},
|
||||
"reinforcement": {
|
||||
"approved_total_minor": 120000,
|
||||
"reinforced_minor": 20000,
|
||||
"reserved_minor": 0,
|
||||
"committed_minor": 25000,
|
||||
"consumed_minor": 10000,
|
||||
"available_minor": 85000
|
||||
}
|
||||
},
|
||||
"races": [
|
||||
{
|
||||
"scenario": "over_reserve",
|
||||
"passed": true,
|
||||
"observed_lock_waits": 2,
|
||||
"balance": {
|
||||
"approved_total_minor": 10000,
|
||||
"reinforced_minor": 0,
|
||||
"reserved_minor": 6000,
|
||||
"committed_minor": 0,
|
||||
"consumed_minor": 0,
|
||||
"available_minor": 4000
|
||||
}
|
||||
},
|
||||
{
|
||||
"scenario": "same_reserve",
|
||||
"passed": true,
|
||||
"observed_lock_waits": 2,
|
||||
"balance": {
|
||||
"approved_total_minor": 10000,
|
||||
"reinforced_minor": 0,
|
||||
"reserved_minor": 6000,
|
||||
"committed_minor": 0,
|
||||
"consumed_minor": 0,
|
||||
"available_minor": 4000
|
||||
}
|
||||
},
|
||||
{
|
||||
"scenario": "same_commit",
|
||||
"passed": true,
|
||||
"observed_lock_waits": 2,
|
||||
"balance": {
|
||||
"approved_total_minor": 10000,
|
||||
"reinforced_minor": 0,
|
||||
"reserved_minor": 0,
|
||||
"committed_minor": 6000,
|
||||
"consumed_minor": 0,
|
||||
"available_minor": 4000
|
||||
}
|
||||
},
|
||||
{
|
||||
"scenario": "same_release",
|
||||
"passed": true,
|
||||
"observed_lock_waits": 2,
|
||||
"balance": {
|
||||
"approved_total_minor": 10000,
|
||||
"reinforced_minor": 0,
|
||||
"reserved_minor": 0,
|
||||
"committed_minor": 0,
|
||||
"consumed_minor": 0,
|
||||
"available_minor": 10000
|
||||
}
|
||||
}
|
||||
],
|
||||
"checks": [
|
||||
"independent_approval",
|
||||
"partial_consumption",
|
||||
"same_command_replay",
|
||||
"changed_replay_rejected",
|
||||
"committed_release_refused",
|
||||
"reinforcement_pending_and_approved",
|
||||
"tenant_isolation",
|
||||
"release_once",
|
||||
"net_tax_basis",
|
||||
"audit_rollback_and_retry",
|
||||
"revoked_reviewer_replay"
|
||||
],
|
||||
"sgf_context_checks": [
|
||||
"foreign_source_refused",
|
||||
"reserved_unit_refused",
|
||||
"stale_context_refused"
|
||||
],
|
||||
"visual_review": false
|
||||
}
|
||||
],
|
||||
"equivalent": true,
|
||||
"disposable_databases_dropped": true
|
||||
}
|
||||
Reference in New Issue
Block a user