Files
SGF/docs/SGF_PAYABLE_PAGED_READ_DELIVERY.md
2026-11-04 09:37:20 +02:00

69 lines
11 KiB
Markdown

# Consulta financeira SGF: páginas e leitura conjunta
Continuação posterior: [adaptador nativo SGC paginado em composição QA](NATIVE_PAYABLE_PAGED_READ_DELIVERY.md). Essa entrega acrescenta a integração nativa sem alterar as medições abaixo; pacote instalado e activação nativa permanecem separados. A descrição final deste relatório corresponde ao estado anterior a essa continuação.
02/11/2026 — `SGF-PAYABLE-PAGED-READ-SIM-v1`. Implementação local sintética, continuação do [recibo histórico](SGF_PAYABLE_HISTORY_RECEIPT_DELIVERY.md). A listagem SGF deixa de carregar todas as origens, obrigações, propostas e eventos em cada pedido. Não altera decisões, saldos, origens ou competências reais; não activa Compras.
## Comportamento entregue
`GET /api/supplier-payables` e a página existente aceitam `page`, `per_page` (25/100), `q` (número ou fornecedor), `recognition` (`all/recognised/unrecognised`), `proposal_page` e `event_page`. Parâmetros desconhecidos ou inválidos são recusados com 422. A pesquisa trata `%` e `_` como caracteres literais. Texto e links da interface são escapados.
Os filtros e os totais são calculados no servidor, antes da paginação, no contexto exacto de tenant/empresa/unidade. Reconhecimento significa existência de obrigação reconhecida, não pagamento, vencimento ou saldo liquidado. Não foi criado um filtro de «paga/vencida» que ignorasse dados indeterminados.
Documentos têm ordem descendente por ID. As propostas e os eventos **dos documentos da página** têm páginas independentes, também descendentes. Mudar de página documental reinicia os paginadores de evidência; os links preservam pesquisa, reconhecimento e tamanho. A interface explica o âmbito da janela e mantém todas as versões/eventos recuperáveis, sem devolver o universo completo. As posições financeiras conservam a ordem anterior por ID da obrigação.
`SupplierPayables` verifica em conjunto as origens e os recibos históricos da página. `Payables::listingPage` lê as origens das obrigações, incorporações, pagamentos originais, decisões e totais de afectações/reversões por conjuntos de IDs. O cálculo de posição e a reconstrução/verificação da cadeia histórica permanecem nos mesmos métodos do núcleo. Os caminhos antigos continuam disponíveis para outros adaptadores e como comparador; não se criou um segundo motor financeiro.
O pedido SGF usa `REPEATABLE READ READ ONLY` e revalida identidade, contexto e direitos sem bloquear as linhas de escrita da empresa/utilizador. A autorização de leitura reutiliza as mesmas verificações; não concede preparar/validar por consequência da consulta. Preparações/confirmações continuam a usar autorização com bloqueios e leitura actual da origem/histórico. Os snapshots de leitura existem apenas dentro da consulta e não são utilizados por comandos.
Recibo divergente continua a tornar apenas a posição dependente indeterminada (`balance_minor=null`), mantendo principal, documentos e histórico consultáveis. Origem/pessoa/contexto alterados continuam a exigir nova conferência. Vencimento desconhecido e pendentes/rejeitados preservam o tratamento anterior.
## Antes/depois observado
[Medições, fingerprints e hashes](proofs/sgf-payable-paged-read-20261102.json). Tempos do trecho de leitura em milissegundos; memória é **pico do heap PHP alocado, em MiB**, incluindo a base de 24 MiB do framework.
| Documentos no ensaio | Página nova | Tempo integral anterior (ms) | Tempo novo (ms) | Consultas antes → depois | Pico PHP antes → depois (MiB) |
| ---: | ---: | ---: | ---: | ---: | ---: |
| 1.000 | 25 | 22.202,6 | 69,7 | 25.028 → 67 | 42 → 24 |
| 1.000 | 100 | 22.202,6 | 123,9 | 25.028 → 67 | 42 → 28 |
| 5.000 | 25 | 115.270,2 | 91,9 | 125.028 → 67 | 88 → 24 |
| 5.000 | 100 | 115.270,2 | 151,7 | 125.028 → 67 | 88 → 28 |
| 10.000 | 25 | 338.498,5 | 139,6 | 250.028 → 67 | 146 → 24 |
| 10.000 | 100 | 338.498,5 | 166,9 | 250.028 → 67 | 146 → 28 |
A leitura anterior era integral, sem tamanho de página. Foi medida **uma vez por volume**, e a mesma medição é referida nas duas linhas correspondentes; não são duas execuções anteriores independentes. Os fingerprints de todos os campos das posições das janelas de 25/100 coincidiram com os do leitor anterior nos três volumes. Propostas/eventos passam a ser limitados e paginados, em vez de todos serem devolvidos.
Condições: mesma base/role/schema de ensaio por volume, PHP 8.4.27, limite de memória 512M, processo PHP novo por estratégia e aquecimento limitado igual. PostgreSQL já estava aquecido pela preparação dos dados; não se esvaziaram caches. Ordem: leitura integral, página25 e página100. Uma amostra por estratégia, sem distribuição estatística ou carga concorrente. A medição antiga usa o método integral e os callbacks de origem anteriores, sem as flags finais do adaptador antigo; a nova inclui o adaptador SGF paginado completo. Não são tempos totais de HTTP/browser/renderização.
O pico extra de heap alocado de uma página de 25 foi zero porque reutilizou blocos já alocados pelo framework; **não significa consumo de memória zero**. Não foi medido RSS do processo. O ganho observado resulta conjuntamente de paginação, leitura em lote e remoção de bloqueios de escrita nas consultas. Não se isolou cada técnica. **Nenhum índice foi acrescentado/removido/experimentado**, nem no destino; não há ganho de índices a atribuir.
O gargalo anterior era a leitura de todo o universo, com consultas de origem, schema e dependências repetidas por obrigação. O teste de consultas identificou ainda uma descoberta de schema por posição no primeiro leitor em lote; foi removida desse percurso após verificação conjunta da disponibilidade. A leitura final faz67 consultas tanto para25 como para100 documentos, com os custos de autorização/metadados incluídos.
Os volumes maiores contêm clones explicitamente sintéticos para carga: uma origem efectivamente conferida nos workflows de Compras, preservada, mais999/4.999/9.999 clones de benchmark. Não se declara que cada clone executou um workflow nativo. Cada obrigação de carga tem três pagamentos históricos; a fixture é preparada em blocos de100, sem construir todo o universo em memória PHP.
## Testes e concorrência
- Dez cenários existentes do adaptador histórico SGF /56 asserções, executados por serem afectados pela mudança da leitura/autorização.
- Oito cenários novos de paginação /34 asserções: páginas disjuntas, ordenação, filtros antes dos totais, pesquisa literal, janela vazia, paridade integral de posições, leitura conjunta constante, revogação/isolamento, recibo alterado, afectações/reversões e cadeia histórica.
- 21 testes de compatibilidade nativa / 144 asserções, usando a fonte canónica apenas nas bases QA novas. Não se actualizou o pacote/candidata/demonstração nativa. Vinte casos válidos foram reutilizados; um caso de imutabilidade foi corrigido para envolver as violações SQL esperadas em savepoints e repetido isoladamente. Sem savepoint, o PostgreSQL abortava a transacção do próprio teste antes da verificação seguinte.
- 24 verificações HTTP pelo kernel real: páginas de 25/100, fontes/eventos disjuntos, filtros, recusa de parâmetros/contexto, leitor sem escrita, links, escaping e respostas privadas. A prova HTTP anterior de 17 controlos também passou no adaptador alterado, antes da expansão da carga.
- Provas adicionais isoladas: documento efectivamente por reconhecer aparece no filtro correcto; outra unidade da mesma empresa não aparece; comando posterior à leitura recusa uma origem entretanto alterada; leitor termina enquanto o escritor mantém bloqueio na empresa e não observa recibo ainda não confirmado.
Os cenários de decisões/afectações adicionais usaram apenas fixtures de leitura dentro de transacções com rollback. Não activaram confirmação de pagamentos pendentes no SGF nem instalaram permanentemente essa capacidade. O postcheck confirmou ausência dessas tabelas temporárias, cinco concessões QA originais preservadas e o recibo efectivo inicial inalterado. O fingerprint dos registos financeiros e de `pa_access`, em leitura, permaneceu igual antes/depois dos últimos testes e do HTTP.
O runner financeiro nativo passou a exigir uma base QA **nova** por execução, por usar `RefreshDatabase`. Uma tentativa de retoma encontrou uma função residual na preparação da própria base de prova e não foi contada como teste válido. Não se reparou schema instalado nem se fez reset dos hosts de regressão/demonstração protegidos. Diagnósticos e JUnit anteriores permanecem guardados; o consolidado selecciona apenas casos aprovados por nome.
## Reproduzir sem destruir provas
`scripts/payable-page-run.mjs <tag-da-origem-histórica>` cria uma base SGF nova e reutiliza a captura nativa existente, sem repetir ou alterar o workflow nativo. Executar `scripts/payable-history-sgf-proof.php <settings.json-privado> page-seed 51`, depois a fase `page-cases`. `scripts/payable-page-load.mjs <novo-tag>` expande a fixture por 1.000/5.000/10.000 e mede cada estratégia em processo próprio. Não voltar a executar os casos de 51 registos na fixture já expandida; não a reduzir/resetar. As fases `page-fresh-command`, `page-filter-positive`, `page-concurrent-read`, HTTP e `page-post` conferem o estado final. `scripts/summarize-payable-page.mjs <novo-tag>` consolida as provas preservadas. Usar PHP/Node fixados nas instruções locais.
PHP/HTML foram verificados sem novo build JavaScript, navegador ou dependências. O servidor HTTP temporário terminou apenas o processo próprio. Credenciais, cookies, configurações e cópias de fontes permaneceram na pasta QA privada, fora do relatório versionável.
## Limites e preservação
Fotografias de leitura são por pedido, não uma sessão longa/cursor que fixe várias páginas durante navegação humana. Cada página confere o histórico completo necessário dos documentos seleccionados; um único documento com histórico muito extenso precisa de avaliação própria.67 consultas constantes ainda incluem verificações de autorização/schema; os tempos locais não são garantia de SLA, throughput ou implantação.
O adaptador autónomo nativo conserva a sua listagem anterior: foi verificada a compatibilidade do núcleo, sem aplicar esta interface/paginação ao destino nativo. A passagem histórica continua por recibos de ensaio, sem origem viva autenticada ou cutover operacional da responsabilidade financeira. Não se declara Financeiro completo, contabilidade, reconciliação bancária ou capacidade de implantação. Revisão visual permanece separada e pendente.
Preservados seis registos de associação, cache bloqueada, provas/checkpoints anteriores, dados/acessos/configurações de demonstrações e instalações reais e trabalho alheio. Sem publicação, activação de Compras, novo direito real, migração/índice no destino ou checkpoint presumidos.