50 lines
7.8 KiB
Markdown
50 lines
7.8 KiB
Markdown
# Livro financeiro → relatório de obrigações reconciliado
|
||
|
||
02/11/2026 — `SGF-PAYABLE-POSITION-REPORT-SIM-v1`. Implementação local sintética, sobre a [consulta financeira coerente](SGF_SETTLEMENT_READ_ISOLATION_DELIVERY.md). Entregue código funcional de relatório. O primeiro lançamento contabilístico permanece **apenas especificado, por autorizar**, em [GENERAL_LEDGER_FIRST_SYNTHETIC_SCOPE.md](GENERAL_LEDGER_FIRST_SYNTHETIC_SCOPE.md).
|
||
|
||
## Percurso e significado
|
||
|
||
A consulta de obrigações SGF liga a **Relatório das obrigações reconhecidas abrangidas pelo filtro**. `GET /supplier-payables/report` apresenta o relatório; `GET /api/supplier-payables/report` devolve os mesmos campos em JSON. Critérios: número/fornecedor literal e origem local opcional, dentro do tenant/empresa/unidade activos. Mantém `supplier_payables.view` e `pa_access.view`; não cria direitos ou autoridade de decisão. Outros parâmetros, incluindo contexto injectado e data de corte não suportada, recusam 422.
|
||
|
||
O relatório abrange **todas** as obrigações reconhecidas do filtro, sem se limitar à página actualmente visível. O mesmo núcleo `Payables` fornece principal, confirmados históricos, afectações líquidas de reversões, saldo e compatibilidade. Não se guardou outro saldo ou um novo movimento pela consulta.
|
||
|
||
Apresenta separadamente principal original, quantidade de posições conhecidas/indeterminadas e componentes conhecidos. Uma posição com evidência divergente mantém o principal, mas deixa o saldo global **indeterminado**. O saldo conhecido é explicitamente parcial. Não se soma um desconhecido como zero. Vencimento ausente permanece contado como desconhecido, sem inventar datas ou atraso.
|
||
|
||
Os componentes conhecidos reconciliam-se exactamente: principal − confirmados históricos incorporados − afectações líquidas = saldo. Pagamentos ainda por afectar não abatem a dívida. Reporta MZN, sem soma entre moedas, recálculo fiscal ou classificação contabilística.
|
||
|
||
Cada geração tem captura UTC, âmbito, critérios e SHA-256 do conteúdo ordenado das posições/revisões. Links levam aos documentos e evidências existentes. JSON e ligações geram nova captura; não prometem recuperar um relatório arquivado. São posições actuais sobre recibos de ensaio, sem fonte histórica SGF viva ou corte histórico. A interface identifica esses limites.
|
||
|
||
## Leitura completa e correcção do gargalo encontrado
|
||
|
||
A primeira implementação segura reutilizava a listagem paginada em 100 fontes por janela. Na prova de 10.000 posições, revelou 6.607 consultas e 19,1 s, porque cada janela repetia contagens, autorizações e propostas/eventos de apresentação que o relatório não consumia.
|
||
|
||
Foi corrigida nesta entrega: `Payables::positionsPage()` usa o mesmo cálculo/leituras conjuntas da listagem, omitindo apenas as páginas de propostas/eventos. O adaptador partilha o predicado de filtros com a listagem e percorre IDs descendentes por chave, em vez de repetir contagens/offsets. Carrega até 100 fontes e suas dependências por janela. O motor construído para a janela só autoriza leitura; uma tentativa de comando nesse percurso lança recusa. Autoridade, identidade e contexto continuam conferidos durante o relatório.
|
||
|
||
Uma transacção própria `REPEATABLE READ READ ONLY` cobre a geração inteira. Não há bloqueios de escrita da empresa/actor. Se invocado dentro de transacção existente, exige pelo menos `repeatable read`/`serializable` e participa nela; recusa 409 um contexto aninhado incoerente. O percurso HTTP foi efectivamente verificado só de leitura. Não se mantém transacção aberta enquanto uma pessoa lê/confirma a página.
|
||
|
||
| Geração completa de 10.000 posições | Tempo ms | Consultas | Pico heap PHP MiB | Janelas |
|
||
|---|---:|---:|---:|---:|
|
||
| Reutilização inicial da listagem | 19.066,022 | 6.607 | 34 | 100 |
|
||
| Leitura específica conjunta por chave | 12.557,809 | 2.313 | 32 | 100 |
|
||
|
||
Totais, componentes e SHA-256 do conteúdo **iguais** antes/depois. Cenário: 10.000 obrigações sintéticas com os históricos importados conservados, principal 60,00 MZN e confirmados 30,00 MZN por posição. Principal global 600.000,00 MZN, confirmado histórico 300.000,00 MZN, saldo 300.000,00 MZN, sem afectações novas. 99,99% são cópias de volume explícitas da fixture anterior; não 10.000 workflows de compra executados.
|
||
|
||
Condições equivalentes: mesma base/role e filtro, PHP 8.4.27/512M, processos independentes, base local aquecida, uma amostra válida por implementação e actividade local não controlada. Memória é heap alocado, não RSS. Não houve índice novo/experimento de índice. Não se repetiram os benchmarks anteriores de páginas ou de pagamentos: são duas gerações completas do novo relatório, sobre o mesmo universo.
|
||
|
||
**Limite material:** 12,6 s continua elevado para 10.000 posições numa consulta interactiva. Retirou-se o custo de apresentação e reduziu-se o número de consultas, mas o custo restante não foi isolado por perfilagem. A correcção mínima seguinte é medir separadamente leitura, validação/captura histórica e serialização/hash antes de escolher outro índice, cache ou geração em segundo plano. Não se declara ausência de gargalos, carga sustentada ou capacidade de implantação.
|
||
|
||
## Provas e preservação
|
||
|
||
- Três cenários finais / 17 asserções: foco e filtros literais, identificação de conteúdo estável, vencimento desconhecido, mistura de saldo conhecido com histórico divergente, checksum inválido, âmbito estrangeiro em tenant/empresa/unidade, direito revogado e transacção aninhada incoerente. Repetidos apenas estes casos afectados depois da optimização; a prova inicial válida fica preservada e não se soma duas vezes.
|
||
- Livro de afectações/reversões anterior: 61 obrigações, principal 3.660,00 MZN, afectação líquida 3,92 MZN e saldo 3.656,08 MZN, reconciliados pelo núcleo. Nenhum pagamento ou lançamento criado pelo relatório.
|
||
- 17 verificações HTTP reais: autenticação, relatório completo de 61 posições, foco, reconciliação, JSON/HTML, retorno à evidência, ligação no workspace existente,422/403/409, escape HTML e `no-store`. Instrumentação confirma fotografia só de leitura e zero `FOR UPDATE`. Sem navegador ou revisão visual.
|
||
- Pós-ensaio confirmou os fingerprints integrais dos dois livros anteriores. Factos, direitos e provas permanecem iguais; alterações dos casos adversariais foram revertidas. Não se fizeram resets, limpezas de cache, concessões reais ou activação de candidatas.
|
||
|
||
Manifesto: [resultados, medições e hashes](proofs/sgf-payable-report-20261102.json). Rotinas dirigidas no harness protegido: fases `payable-report-volume-batch`, `payable-report-cases-batch`, `payable-report-settlements` e `payable-report-post`. HTTP: `scripts/payable-report-http.mjs <tag>`. Consolidação sem repetir provas: `scripts/summarize-payable-report.mjs`. Marcadores concluídos são preservados; credenciais, sessões e logs ficam privados. Sintaxe PHP/JavaScript e diferenças verificadas; Blade renderizado pelo kernel HTTP, sem build JavaScript novo.
|
||
|
||
## Próxima fronteira
|
||
|
||
O relatório funcional não resolve reconhecimento contabilístico, períodos, razão ou lançamentos. A proposta [COMMON-LEDGER-PAYABLE-SIM-v1](GENERAL_LEDGER_FIRST_SYNTHETIC_SCOPE.md) delimita um primeiro lançamento equilibrado, contas/período artificiais, separação de funções, quatro direitos exclusivamente QA e testes, para autorização específica. Não há código funcional contabilístico nesta entrega.
|
||
|
||
Seis registos protegidos, cache bloqueada, demos, configurações/direitos reais e alterações alheias preservados. Sem publicação, checkpoint, migração no destino ou activação de Compras. Revisão visual, optimização adicional de relatórios e implantação permanecem separadas; a autorização seguinte não as transforma em provas concluídas.
|