62 lines
12 KiB
Markdown
62 lines
12 KiB
Markdown
# Obrigação reconhecida → primeiro lançamento contabilístico sintético
|
|
|
|
02/11/2026 — `COMMON-LEDGER-PAYABLE-SIM-v1`. **Código funcional, interface, integração e provas locais entregues** no recorte expressamente autorizado pelo utilizador: «Autorizar o incremento sintético proposto». [Âmbito autorizado](GENERAL_LEDGER_FIRST_SYNTHETIC_SCOPE.md). A autorização permite este desenvolvimento/fixture; não presume aceitação funcional ou checkpoint.
|
|
|
|
## Percurso implementado
|
|
|
|
O núcleo único `packages/general-ledger` recebe do adaptador SGF a obrigação já reconhecida pelo Payables, conferida de novo pela identidade factual, reconhecimento/revisão e âmbito exactos. Não recebe um saldo de relatório ou um estado de factura como autorização de lançamento. O principal vem da origem: **60,00 MZN**, imposto documental 0, vencimento desconhecido. O cenário inicial não tem pagamentos. Não se atribuiu uma regra contabilística real à Tempo nem se modificou a obrigação financeira.
|
|
|
|
Uma regra e período de ensaio explícitos capturam **D 60,00 em `QA-CONTRAPARTIDA` / C 60,00 em `QA-FORNECEDOR`**, em 29/10/2026 no período artificial `QA-2026-10`. As duas contas são de movimento, artificiais e em MZN. Não representam contas PGC aprovadas, inventário/despesa/IVA inferidos, uma regra fiscal ou saldo por liquidar.
|
|
|
|
1. Preparador propõe obrigação/data/regra/período e fundamento. Fica guardada uma versão imutável da fonte, configuração, linhas e impacto; ainda não há lançamento.
|
|
2. Outra identidade **e pessoa** aprova ou recusa a revisão exacta, com fundamento. A aprovação financeira da obrigação não substitui esta conferência contabilística. Recusa e versões anteriores permanecem preservadas.
|
|
3. O preparador autorizado aplica apenas a versão revista. A aplicação volta a verificar direitos, pessoa, contexto, fonte, regra/período/versões, moeda e equilíbrio. Mudança exige nova conferência. Cabeçalho, linhas, auditoria e recibo de repetição ficam na mesma transacção.
|
|
4. O lançamento liga à obrigação, proposta, revisão, regra e período aplicados. A interface conserva a fotografia mesmo quando a proposta fica noutra página, apresenta o comprovativo e deixa de oferecer uma segunda aplicação. Para abrir a posição financeira actual, muda-se explicitamente para Compras; não se contorna a separação modular.
|
|
|
|
Unicidade pela identidade factual do efeito e âmbito, independente da chave de pedido ou revisão. Duas aplicações concorrentes ou outra chave para a mesma aplicação recuperam **o mesmo lançamento**. Conteúdo incompatível recusa 409. Um recibo já gravado continua recuperável depois de o período fechar em dados adversariais de ensaio, sempre com a autorização actual, sem nova gravação. Não existe interface de fecho/reabertura ou de edição de lançamentos.
|
|
|
|
## Base, direitos e navegação
|
|
|
|
Configuração `general_ledger.synthetic_enabled=false` por defeito, sem activação por variável de ambiente. A guarda exige `payable-testing`, base/role QA próprias, loopback, cluster de regressão 55439 e role sem poderes administrativos. Nenhuma migração ou concessão foi aplicada no destino. Esquema instalado explicitamente numa **base nova**, separada dos livros/demos anteriores; não há criação/reparação por acesso à página.
|
|
|
|
Quatro direitos autorizados, apenas nas fixtures: `general_ledger.view/prepare/validate/post`. São **seis concessões por fixture**: preparador view/prepare/post, validador view/validate, consulta view. Reutilizam-se contexto, membros, permissões e identidade de pessoa existentes; não há herança de Administração, Financeiro ou nomes. Consumir a fonte exige também os acessos de leitura financeira explícitos já presentes nessas identidades QA. Não foi alargado o catálogo público de concessões reais.
|
|
|
|
As novas rotas pertencem a **Contabilidade**, mantendo os seis módulos e Início/Opções gerais: `/general-ledger`, `GET /api/general-ledger`, `POST /api/general-ledger/prepare|validate|post`. O menu mostra a ligação de ensaio só com `general_ledger.view` na unidade. Módulo errado ou geração antiga de contexto recusa 409. O pacote instalado de Compras não foi substituído/activado; o adaptador nativo permanece por construir no seu âmbito próprio.
|
|
|
|
Consulta por período/conta, diário e histórico em janelas de 25. Totais incluem todas as linhas do filtro, não apenas a página. Período ou conta indisponíveis são recusados em vez de aparentarem saldo zero por falta de configuração. Leitura HTTP usa fotografia `REPEATABLE READ READ ONLY`, sem bloqueios de escrita. Não se adicionaram dependências.
|
|
|
|
## Integridade e provas
|
|
|
|
Nove tabelas próprias, todas append-only. Chaves estrangeiras compostas protegem o âmbito de contas/linhas/revisões. Checks impedem montantes negativos, cabeçalho desequilibrado e terceira linha. A validação imediata do núcleo e um constraint trigger diferido conferem duas linhas, contas de movimento, moeda, fonte/fotografia exactas, revisão aprovada e independente e preparador/aplicador. O papel QA é proprietário da base nova; isto não valida endurecimento de papéis/schema para implantação real.
|
|
|
|
- **Oito cenários, 74 asserções**, seleccionando a execução final válida: circuito completo, impacto antes da aplicação, conciliação de período/contas, independência por utilizador/pessoa, recusa, preparador de outra identidade, direitos revogados, pessoa trocada, versões de fonte/regra/período/captura/revisão, moeda, conta agregadora, âmbito estrangeiro e campos injectados.
|
|
- Repetição pela mesma/outra chave; recibo após período alterado; falhas injectadas depois do cabeçalho, linhas, evento e recibo. Rollback integral e recuperação sem duplicação em cada ponto. Nenhum controlo de falha é exposto pela API/configuração.
|
|
- Base recusou escrita directa de cabeçalho desigual, principal incompatível, linha em falta, conta estrangeira, terceira linha e alteração de qualquer tabela do histórico. PostgreSQL usa savepoints nos casos esperados; uma transacção abortada não foi contada como recusa funcional.
|
|
- **Concorrência real em dois processos:** ambos aguardaram a empresa, com cadeia confirmada por `pg_blocking_pids`/`pg_stat_activity` em `companies FOR UPDATE`. Após libertação, ambos devolveram o mesmo ID. Resultado persistido na base QA: **um lançamento, duas linhas, um evento de aplicação**. Repetição posterior recuperou o recibo sem novo efeito.
|
|
- **23 verificações HTTP reais:** autenticação, consulta/totalização, duas contas, três rotas de comando recuperando os recibos originais de preparação/revisão/aplicação, outra chave para o mesmo efeito, conflito de conteúdo, permissões, conta/período indisponíveis, 422/403/409, CSRF 419, módulo errado e `no-store`. O circuito de criação/revisão/aplicação foi exercitado pelos serviços e processos reais; no HTTP verificaram-se recuperação/delegação e recusas, sem alegar criação de outro lançamento para repetir a prova.
|
|
- Três verificações estáticas dirigidas de permissão/renderização do menu, build de produção **privado** e renderização final Blade. Assets/manifesto QA foram servidos pelo router loopback de prova. Não se substituiu o manifesto público das demos.
|
|
|
|
O teste geral de navegação não terminou e foi interrompido. **Não é uma prova aprovada.** Não se alterou o trabalho alheio para o fazer passar, não se limpou cache e não se repetiu uma via de navegador. A ligação nova foi validada pelos testes dirigidos, build e recusas HTTP; revisão visual/interacção no navegador permanece pendente.
|
|
|
|
[Manifesto, resultados e hashes](proofs/common-ledger-payable-20261102.json). O texto exacto da proposta autorizada é recuperado e arquivado por SHA-256; a nota de autorização posterior não altera o recorte. As provas financeiras anteriores são conferidas por hash, sem reexecutar as suites alheias.
|
|
|
|
O primeiro diagnóstico de preparação identificou um erro no fingerprint do harness (`company_memberships` tem chave composta, não coluna `id`). A fixture foi conferida e recuperada sem repetir schema/concessões/reconhecimento; essa base ficou como diagnóstico. A prova final usa outra base nova com todos os constraints finais. Uma asserção de soma SQL foi ajustada para comparar o valor inteiro devolvido como `numeric`, sem mudar os montantes. Execuções diagnósticas não contam como aprovadas; não houve reset/remoção dos seus dados.
|
|
|
|
## Preservação e reprodução
|
|
|
|
**Demonstração própria para a equipa:** [http://127.0.0.1:8048/qa/ledger-demo](http://127.0.0.1:8048/qa/ledger-demo), apenas em loopback. Outra base/role QA, sem usar a base das provas. Tem uma obrigação reconhecida de 60 MZN e, no momento da entrega, **zero propostas e lançamentos**. Escolher Preparar/aplicar, Revisão ou Consulta na página; obrigação #1, data 29/10/2026, período/regra de ensaio já apresentados. A equipa pode executar o circuito e registar feedback; não foi atribuída aceitação ou revisão visual.
|
|
|
|
São 13 verificações adicionais de preparação do demo, sem operações de negócio: três identidades, interfaces e consulta da fixture ainda vazia. Cookie de sessão específico e nenhum `XSRF-TOKEN` global substituído; um complemento confirmou CSRF 419 e recusa de escrita 403 com token válido. A validação CSRF permanece activa e as formas usam o header explícito. Assim, autenticação/cookies das demos anteriores não são substituídos. Build copiado apenas entre as duas pastas privadas de assets; manifesto público original preservado.
|
|
|
|
`scripts/ledger-demo.mjs <tag>` inicia apenas um servidor próprio numa porta loopback livre ou reconhece o existente, sem repetir a preparação. Estado/PID e logs ficam na pasta privada. Não reiniciar/apagar dados para repetir a demonstração; a base da regressão conserva separadamente o único lançamento comprovado.
|
|
|
|
Fingerprint de origens/obrigações/decisões/recibos financeiros, concessões e membros igual ao baseline da fixture, antes/depois de todos os ensaios. O Payables continua a ter uma obrigação de 60 MZN; o diário é outro efeito, não uma segunda dívida. Stock/orçamento **não têm tabelas nesta composição mínima**, pelo que não se inventou uma prova de exercício desses motores. O núcleo não chama os seus escritores. Dados/roles/demos anteriores não foram escritos; os seis registos protegidos e a cache bloqueada não foram objecto de decisão/limpeza.
|
|
|
|
Preparação: Node fixado, `scripts/ledger-run.mjs` cria a nova base/role e configura apenas as identidades QA. Fases nomeadas recusam repetir provas concluídas. `scripts/ledger-ui-check.mjs <tag>` compila/renderiza apenas em storage privado; `scripts/ledger-http.mjs <tag>` cria e encerra só o seu servidor de prova loopback 8047. O demo 8048 é um processo/base distintos, conservados para a equipa. `scripts/summarize-ledger.mjs <tag>` consolida sem voltar a executar testes. Settings, passwords, cookies, UUIDs de repetição e logs ficam privados. Não se criou checkpoint.
|
|
|
|
## Limites mantidos
|
|
|
|
Primeiro efeito de reconhecimento apenas, sem importação/lançamento histórico automático, IVA/contas reais, classificação de compras, pagamentos/recebimentos contabilizados, integração nativa SGC, valorização de stock, correcção/estorno, fecho/reabertura, reconciliação ou contabilidade geral completa. O período fechado foi só uma mutação adversarial de fixture, revertida, não uma funcionalidade operacional.
|
|
|
|
Configuração/fonte futura deve seguir a mesma ordem de bloqueio da empresa; não há API de escrita de configuração neste incremento. Não foram medidos volumes sustentados ou implantação; o relatório financeiro anterior conserva a limitação de 12,6 s para 10.000 posições. Sem publicação, activação de Compras ou concessões reais. Revisão visual, aceitação e capacidade de implantação continuam separadas.
|