Saltar al contenido
Todos los posts
6 de diciembre de 2024·2 min de lectura·Diogo Hudson

El ledger append-only: la mejor idea aburrida del inventario

Un log de cada movimiento, nunca modificado. Sin gracia, sin fuegos artificiales, y la mayor ganancia estructural que un sistema de distribución puede tener.

El ledger append-only: la mejor idea aburrida del inventario

Todo sistema de inventario confiable comparte una propiedad: su fuente de la verdad es un log de lo que pasó, no un total corriente. Los bancos lo hacen. El software contable lo hace. La mayoría de los ERPs lo hacen — y lo esconden detrás de una interfaz que pretende lo contrario.

El modelo de total corriente es seductor porque es rápido. Una sola fila por producto, un solo entero que actualizar, una sola lectura para responder '¿cuántos tenemos?' También es frágil, porque ese único entero es un valor derivado sin procedencia. Cuando está mal — y eventualmente va a estar mal — no hay forma de saber por qué, cuándo, ni por quién. Solo puedes corregirlo sobrescribiéndolo, lo que destruye la evidencia del error.

Por qué append-only Si cada cambio escribe una fila y ninguna fila se edita, la auditoría es trivial. '¿Cuál era el inventario de SKU AB-001 el 14 de marzo?' es un SUM de SQL. '¿Quién movió esto?' es un JOIN simple.

La diferencia operacional es enorme. En un sistema mutable, responder una pregunta histórica requiere confianza — confianza en que nadie editó el historial, en que el backup es preciso, en que la persona que hizo el cambio recordó registrarlo en otro lado. En un sistema append-only, responder una pregunta histórica requiere un query. La respuesta es determinística, reproducible, y admisible en una disputa con un cliente o auditor.

Sin botón de delete El admin de StockMovement deshabilita add/change/delete explícitamente — incluso para superuser. Las correcciones pasan por POST /api/stock/{id}/adjust/, que graba una fila ADJUSTMENT con nota obligatoria. El ledger se mantiene honesto.

Esta es la disciplina que hace que append-only funcione. Si hay una puerta trasera — un DBA que puede hacer UPDATE stock_movement SET quantity = 5 WHERE id = 1234 — entonces el ledger es solo un log con asterisco. Al deshabilitar toda operación mutante en el admin de Django y proveer un único camino de corrección auditable, garantizamos que cada número en el ledger tiene trazabilidad. Incluso las correcciones tienen trazabilidad — la nota de ajuste es obligatoria, tiene timestamp, y está atribuida al admin que la hizo.

Caché, no verdad StockItem.on_hand y StockItem.reserved son caché, actualizados en la misma transacción que la escritura del ledger. Si llegan a divergir, el ledger los reconstruye.

El caché existe por rendimiento — no quieres hacer SUM de seis años de movimientos de inventario cada vez que renderizas la página de inventario. Pero el caché es descartable por diseño. Un comando de management puede poner a cero cada StockItem y reconstruirlo desde el ledger en una sola pasada. Este patrón de diseño — caché como optimización, ledger como verdad — se toma prestado de los sistemas contables y se aplica al inventario. No es novedoso, pero es correcto, y la corrección en inventario vale más que la novedad.

Cómo está construida la plataforma de Quotery.

Todos los posts
Textos cortos sobre cotizar, inventario, IA y cómo los distribuidores pequeños despachan mucho volumen sin tanto rodeo.