Files
SGF/docs/STOCK_RECEIPT_LINK_DELIVERY.md
2026-11-02 20:29:34 +02:00

10 KiB

Recepção aceite → movimento único → consulta SGF

Continuação delimitada: Oficina → saída física conferida. A prova de recepção deste documento mantém o seu âmbito; a continuação usa outro cenário sintético e não representa um percurso integral instalado.

02/11/2026. COMMON-RECEIPT-STOCK-SIM-v1. Primeiro fluxo de escrita ligado e comprovado: o circuito real de recepção de Compras valida e confirma uma recepção sintética, delega a gravação física no núcleo comum e o SGF consulta o mesmo movimento no livro de origem. Não se copiou o saldo para outro livro nem se criou uma recepção fictícia no SGF.

Continua a consulta nas duas composições e o plano entre módulos. É um incremento delimitado: a preparação/confirmação de recepções na interface SGF ainda não está entregue; a autoridade de recepção exercitada é a implementação existente de Compras. O ensaio não equivale à instalação completa do módulo de Compras no ERP.

Implementação e responsabilidades

packages/inventory-write/src/ReceiptMovementWriter.php extrai a gravação antes feita directamente em ReceiptWorkflow. Há agora uma chamada única pelo adaptador nativo ReceiptStockMovement; não há fallback para outro escritor de recepções. O pacote é distribuído como artefacto local verificado em Compras, packages/inventory-write/releases/0.1.0. Manifesto SHA-256 f0b99e591f9a4df135e685f64ceffad77bed259222debe0f34c20f95e3cad800. A distribuição compara os dois ficheiros com a fonte e recusa substituir uma versão imutável com conteúdo diferente. Não depende da pasta SGF em runtime.

O circuito nativo mantém: ordem emitida, recebedor autorizado distinto do emissor, conflito de interesses, quantidades cumulativas, qualidade/rejeição, unidade, mapeamento artigo/armazém, equipamento/peça quando aplicável, lotes, sinais existentes e auditoria. Não foram substituídos por regras sintéticas no motor. A fixture prepara as etapas anteriores como origem sintética; não comprova novamente todo o procurement anterior à ordem.

O escritor comum exige a transacção do host e uma callback de autorização. Lê a linha/recepção no âmbito certo, confere quantidade física aceite e recebedor original, obtém o hash da origem, bloqueia e revalida esse hash antes de gravar. Usa a unicidade existente de goods_receipt_item_id; não precisa de migração de stock nova ou outra tabela de saldos.

A fotografia do movimento conserva os campos anteriores e acrescenta referência documental e inventory_source_hash. O hash representa a versão dos factos da linha/recepção, não uma versão inventada da ordem. Número/estado final do pai ficam fora do hash porque a finalização ocorre depois na mesma transacção. Mesmo hash/origem recupera o movimento; hash antigo ou movimento histórico incompatível recusa, sem reescrever/adoptar o original. A repetição de recepções antigas pelo circuito existente conserva a sua resolução prévia; não houve importação/replay de histórico.

O writer não faz commit: recepção, itens, entrada física, lotes, finalização e auditoria continuam na transacção nativa. Não confirma facturas, obrigações, pagamentos ou lançamentos por arrasto. Os restantes movimentos de StockWorkflow mantêm os seus serviços existentes; este incremento só extraiu entradas por recepção.

Ligação ao SGF sem duplicar o efeito

O adaptador de consulta SGF recebeu um binding de fonte exclusivamente QA. Para o ensaio, liga ao livro nativo local através de uma role técnica nova com SELECT apenas em artigos, armazéns e movimentos, sem leitura das recepções/auditoria, sem escrita, sem poderes de criação de bases/roles, replicação ou bypass. A role tem leitura por omissão e cada consulta usa READ ONLY / REPEATABLE READ. O teste também tentou uma escrita inócua (DELETE ... WHERE false) e confirmou recusa, sem alterar dados.

Guardas conferem ambiente testing, identidade física do SGF, host loopback, porta 55439, nome da base nativa de regressão, role correspondente e cluster. O contexto SGF é mapeado explicitamente para tenant/armazém da origem. A referência cifrada é vinculada também à base/role/cluster efectivos, não só ao nome lógico da ligação. Não se inferem identidades ou empresas por igualdade de números. Parâmetro de armazém fora do binding é recusado.

Isto é uma ligação de observação do ensaio local, não um conector remoto obrigatório do produto. Permite provar que o consumidor vê o movimento realmente produzido pela recepção, em vez de o simular noutra fixture. A composição final continua a exigir instalação/adaptadores locais do núcleo comum e namespace/contexto delimitados. Nenhuma configuração de origem operacional foi activada; os bindings por omissão permanecem vazios.

Falha da ligação/fonte devolve 503 genérico sem SQL, credenciais ou stack trace; depois de reposta, a consulta recupera. A referência/hash da fonte anterior exige actualização quando o livro/contexto muda. A API continua somente de leitura e não tem comando de recepção ou saída física.

Cenário, evidência e concorrência

Evento sintético na ordem de 10 unidades Recebido Aceite Rejeitado Efeito físico
Primeira recepção com reservas e fundamento 6 4 2 Um movimento de +4
Repetição idêntica Mesmo evento — — Mesmo comprovativo; nenhum movimento/auditoria adicional
Segunda recepção, totalmente não conforme 2 0 2 Sem movimento

Saldo final desse âmbito: 4 unidades, um movimento, duas confirmações de recepção auditadas (a aceite parcialmente e a totalmente rejeitada). O pós-check verificou autor/data nas duas auditorias e hash de origem no movimento. O SGF devolveu o ID/referência do mesmo movimento e 4 000 milésimos; os contadores do livro de origem e do livro QA SGF não mudaram pela consulta. Reservado, bloqueado e disponível não foram presumidos.

Uma falha injectada imediatamente depois do INSERT comum desfez recepção, linhas, movimento e auditoria. A nova tentativa concluiu com um movimento. Num cenário separado, dois processos PHP reais confirmaram a mesma recepção/chave: observou-se a espera transactionid e o PID do bloqueador, libertou-se a primeira transacção com commit, e o segundo recuperou o mesmo ID; ficou uma recepção e um movimento. Não se fez confirmação real nem se decidiu qualquer associação protegida.

Esta versão preserva a serialização por empresa da origem. Não a remove nem declara maior débito de escrita. Hash/locks/revalidação introduzem trabalho por linha confirmada; esse custo e a duração de locks em recepções grandes ainda não foram medidos. Não substituir essa evidência por tempos de listagem nem apresentar a ausência de N+1 na consulta como prova de escalabilidade das escritas.

Testes e limites da prova

Verificação Resultado
Fluxo nativo, hash/repetição, rollback/retoma e concorrência entre processos 1 teste / 33 asserções
Regressão afectada de recepções/Stock 31 testes / 193 asserções
Recortes de recepção sob controlo de lotes/política 3 testes / 20 asserções
Repetição com o adaptador final sem segundo efeito 1 teste / 8 asserções
Consulta SGF funcional afectada 2 testes / 77 asserções
SGF sobre o livro realmente produzido, RO, falha da ligação e recuperação 1 teste / 31 asserções

Passaram também sintaxe e verificação de whitespace. Os casos de lotes cobrem quarentena, repetição exacta, vencimento com rollback e regra de recepção vigente para chegadas futuras. Não se repetiram as suites alheias, os 72 pedidos de carga anteriores, a matriz de associações ou o build: não houve alteração de interface nesta passagem.

Foi preciso ajustar o launcher Pest para carregar o Pest.php da cópia QA, e não o do caminho de origem; a primeira tentativa falhou na inicialização do teste, antes da fixture. Retomou-se apenas essa prova afectada, na sua base QA. Os testes de recepção e lotes usam bases descartáveis novas próprias e as migrações existentes apenas nelas. Os cenários e a base de ligação foram conservados. O dispatch do adaptador explicita o driver; a prova deste incremento é PostgreSQL, sem afirmar validação noutros drivers.

Prova sanitizada, hashes, contadores e pós-checks. Tokens, credenciais, inputs dos trabalhadores e referências completas da fixture ficam no directório privado. O núcleo de leitura não mudou, pelo que a prova de carga anterior conserva as suas condições/fontes; não mede este fluxo de escrita nem a ligação QA adicional.

Preservação e próximo incremento

Somente bases/roles novas QA e a regressão SGF foram usadas; não se consultaram bases de cliente/demos para este fluxo. O pós-check SGF confirmou zero stock.view temporários, restrição anterior reposta e bindings por omissão vazios. Os seis registos protegidos, a cache bloqueada, demonstrações e alterações alheias ficaram intactos; os hashes das provas válidas anteriores foram conferidos. Sem migração/concessão real, activação de candidata Purchasing, publicação, checkpoint ou aceitação presumidos.

Próximo incremento: oficina → consumo de material da empresa, reutilizando autorização/origem verificada e o escritor de saídas existente, com stock suficiente, material do cliente separado, origem única e correcção por compensação. Permanecem também a preparação/confirmação de recepção na composição ERP SGF, a demonstração persistente própria e a extracção dos restantes movimentos. O ensaio de observação não encerra essas pendências.

Revisão visual e capacidade de implantação continuam pendentes e independentes. A prova cobre API/kernel e serviços com actores sintéticos, não login/MFA/rede/servidor implantado ou experiência visual. Não se voltou à via de navegador bloqueada.