Maioria dos sistemas de estoque tem um número que muda. O Quotery tem um movimento tipado para cada mudança — então 'por que esse produto caiu 3?' não é mistério, é JOIN.
A abordagem de número único é sedutora na sua simplicidade. UPDATE stock_item SET quantity = quantity - 3 WHERE sku = 'AB-001'. Uma query, pronto. Mas essa query não te diz nada sobre por que 3 unidades se moveram. Foi uma venda? Uma devolução? Um ajuste de almoxarifado? Uma correção de contagem errada do mês passado? O número mudou, o motivo evaporou. Seis meses depois, quando o auditor pergunta, a resposta é 'não sei — o sistema diz que a gente expediu.' O sistema está correto mas é inútil para entender.
Os seis tipos RESERVE (cotação fechada), RELEASE (cotação cancelada de closed), SHIP (nota de entrega postada), RETURN (nota de devolução postada), RECEIVE (recebimento de fornecedor postado), ADJUSTMENT (correção manual só para admin). Cada tipo tem sinal esperado e documento-fonte esperado.
O sistema de tipos é o que dá ao ledger seu poder explicativo. Um movimento RESERVE significa algo diferente de um movimento SHIP, mesmo que movam a mesma quantidade. O tipo te diz o evento de negócio que causou o movimento. A FK do documento-fonte te diz exatamente qual cotação, entrega, devolução ou recebimento disparou. O timestamp te diz quando. O usuário que iniciou a transação te diz quem. Cada dimensão do 'por que' está capturada na linha.
Delta com sinal
RESERVE escreve on_hand=0, reserved=+N. SHIP escreve on_hand=-N, reserved=-N. O ledger guarda o delta; o cache guarda o saldo corrente.
A separação de delta e total é o que torna o ledger reconstruível. Cada linha é autocontida: registra a mudança exata em on_hand e reserved naquele momento. Para computar o estado em qualquer ponto no tempo, some todos os deltas até aquele ponto. Não precisa confiar no cache — o cache é só uma view materializada do ledger, e qualquer discrepância é resolvida re-somando, nunca editando o ledger.
Um documento-fonte, um movimento Postar uma DeliveryNote cria um movimento SHIP com o id da entrega. Cancelar uma Quote fechada cria um RELEASE com o id da cotação. A FK é opcional só para ADJUSTMENT — e mesmo ali exigimos nota não vazia.
A nota obrigatória no ADJUSTMENT é a válvula de segurança. Correções manuais acontecem — contagem de inventário varia, produtos danificam, amostras são retiradas para teste de qualidade. Quando um admin ajusta estoque manualmente, o campo de nota captura a explicação humana: 'Contagem física encontrou 2 unidades a menos que o sistema — provavelmente danificadas durante onda de calor de junho.' Essa nota é visível no ledger e na trilha de auditoria. Não substitui um processo adequado, mas é um registro durável de um evento excepcional.
