Al terminar esta lección
- Reconstruir la cadena de decisiones de una defensa real, desde la preocupación del cliente hasta la señal de revisión.
- Distinguir hipótesis de valor, resultado medido, compromiso comercial y promesa indebida.
- Escribir un one-pager de decisión y revisar una minuta de aceptación marcando cada promesa sin evidencia.
- Registrar un cambio de alcance en un changelog con impacto en plazo, costo, riesgo y pruebas.
- Respaldar un número con una consulta SQL o una prueba antes de presentarlo.
12.7 Cómo decir que el cliente puede estar equivocado sin romper la relación
El cliente conoce su negocio, pero puede describir una solución innecesaria, una política idealizada o una excepción como si fuera regla. Tu responsabilidad no es obedecer literalmente ni corregir con soberbia. Mostrá evidencia: "Entiendo que quieren bloquear todo pedido sobre el límite. En los últimos tres meses vimos siete autorizaciones manuales válidas. Si bloqueamos sin flujo de excepción, esos casos van a terminar fuera del sistema. ¿Queremos eliminar esa práctica o modelarla con autoridad y auditoría?". La conversación cambia de opinión contra opinión a decisión sobre evidencia.
La simulación siguiente pone a prueba ese método. Estás en una reunión de alcance del piloto con Marta (dueña) y Laura (administración y crédito). Hay una salida buena, varias riesgosas y dos finales que muestran cómo se llega a cada una. Probá primero las riesgosas: el feedback te explica por qué fallan.
Marta quiere bloquear todo lo que supera el límite
Reunión de alcance del piloto. Marta quiere que el primer release no deje pasar ningún pedido por encima del límite de crédito. Laura conoce las excepciones reales y sabe cómo se resolvieron.
Marta (dueña)
Quiero que el primer release no deje pasar ningún pedido que supere el límite de crédito. Ni uno. Ya vimos demasiadas excepciones.
¿Qué respondés?
12.8 Cómo reconocer que nosotros podemos estar equivocados
La misma disciplina vale para el equipo técnico. Si un operador te muestra que tu modelo no explica un pedido real, corregís el modelo. Si un test descubre que la garantía escrita era imposible bajo una integración existente, volvés a discutir la garantía. Si un cliente demuestra que el costo de una arquitectura supera el riesgo que controla, simplificás. Defender una decisión profesionalmente no significa aferrarse a ella. Significa poder explicar por qué existe y qué evidencia la haría cambiar.
El caso de Nexo tiene un ejemplo concreto. El primer diseño de la reserva leía el stock disponible, verificaba que alcanzara y después escribía la reserva. Con dos pedidos concurrentes por la última unidad, los dos leían 1, los dos pasaban la verificación y los dos reservaban. La garantía que el equipo había escrito, "nunca se vende una unidad de más", era falsa con esa implementación. El equipo no defendió el diseño viejo: cambió la reserva por una actualización condicional en una sola sentencia (ADR-002), agregó la prueba de carrera T06 y volvió a escribir la garantía con su condición.
"Con lo que sabíamos, esta decisión era razonable. Este dato cambia una de las condiciones que la justificaban. Voy a revisar el impacto antes de sostenerla o cambiarla." Reconocer un cambio de evidencia fortalece la confianza más que fingir que siempre tenías razón.
12.9 Vender valor sin vender humo
La propuesta comercial debe conectar esfuerzo con impacto y riesgo. No vendas "Clean Architecture, PostgreSQL y agentes". Vendé menor retrabajo, precio trazable, menos promesas duplicadas, autorización auditable y una base que puede crecer sin rehacer el flujo crítico. Cuando una mejora todavía no tiene métrica, presentala como hipótesis de valor y acordá cómo medirla.
Acá aparecen cuatro cosas que suenan parecido y no son lo mismo. Una hipótesis de valor es una expectativa con método, pero sin resultado. Un resultado medido es un dato obtenido con una fuente, una línea base y una ventana. Un compromiso comercial es algo que el equipo se obliga a entregar (un reporte, una demo, una medición). Una promesa indebida es un resultado futuro garantizado sin medición. Clasificá estas frases antes de leer la explicación.
Hipótesis, resultado, compromiso o promesa
Elegí la categoría que describe la frase. Fijate si la frase trae una fuente o un método: eso cambia la categoría.
Esperamos que el tiempo medio de confirmación baje durante el piloto. La línea base sale de los pedidos de la semana previa.
En la muestra de 60 pedidos observados, 37 necesitaron corregir algún SKU y 9 pasaron por autorización de crédito.
Entregamos un reporte de quiebres en picking cada viernes durante el piloto.
Con este diseño, el retorno de la inversión del primer año será del 300 %.
Estimamos que la administración deja de cargar a mano el comprometido diario. La línea base sale de la planilla de la semana previa.
En el piloto hubo menos pedidos con intervención posterior que en la línea base. La consulta adjunta tiene filtros y fecha.
El sistema tendrá una disponibilidad del 99,9 % desde el día uno, sin medición previa.
Qué puede hacer el agente: preparar una presentación, traducir decisiones técnicas a consecuencias, simular objeciones y detectar afirmaciones demasiado fuertes.
Qué no debe decidir: prometer ROI, tiempos o capacidades sin evidencia; inventar métricas; responder una objeción comercial con una decisión que nadie aprobó.
Contexto mínimo útil: Sprint, métricas existentes, riesgos, decisiones, alcance y límites.
Cómo verificar: cada afirmación cuantitativa debe tener fuente. Cada promesa futura debe tener alcance, criterio y condición. Si el agente propone un número que no aparece en la propuesta, lo tratás como una hipótesis a medir, no como un dato.
12.10 Una decisión técnica se vende explicando la consecuencia
El cliente no necesita que escondamos la técnica, pero sí que la conectemos con su problema. "Usamos idempotency keys" puede ser correcto y poco útil. "Si la conexión se corta y el cliente vuelve a confirmar, garantizamos que no se cree un segundo pedido" explica valor. "Usamos una transacción" se traduce en "si algo falla al confirmar, no quedan reservas sin pedido".
Esto también obliga al equipo a justificar arquitectura. Si no podemos explicar qué consecuencia de negocio produce una pieza técnica, puede ser sobreingeniería. La defensa comercial se vuelve una auditoría adicional del diseño.
Idempotencia: la frase técnica y la frase con consecuencia
"Usamos idempotency keys con un hash del payload en la tabla de requests."
"Si la conexión se corta mientras el vendedor confirma, el reintento devuelve el mismo pedido. Si alguien reutiliza el mismo identificador con datos distintos, el sistema responde conflicto y no crea nada. Por eso no vas a encontrar pedidos duplicados por un reintento."
La tabla que sostiene esa frase es parte de la evidencia. Está en la migración que crea la clave de idempotencia (ADR-005 y ADR-006):
CREATE TABLE idempotency_keys (
request_id text PRIMARY KEY,
request_hash text NOT NULL,
fingerprint_version integer NOT NULL,
order_id uuid NOT NULL REFERENCES orders (id),
created_at timestamptz NOT NULL DEFAULT now()
);
La clave primaria sobre request_id no es un detalle: es lo que impide que dos transacciones creen dos pedidos para la misma intención. Si alguien la quita durante una migración, la consulta de control de la sección de evidencia debería detectarlo. Esa es la diferencia entre decir "usamos idempotencia" y poder mostrar dónde vive la garantía.
12.11 Manejar objeciones sin defender el ego
Una objeción puede revelar información nueva. Si el cliente dice "pero nosotros sí necesitamos facturar en el primer release", no respondemos automáticamente con el documento aprobado. Preguntamos qué cambió, qué evento hace necesaria esa capacidad y qué costo tendría posponerla. Puede aparecer un requisito real que no habíamos capturado. La especificación no existe para ganar discusiones.
También hay objeciones que son preferencias. "Quiero microservicios porque son más modernos" merece una explicación de trade-offs: más despliegues, observabilidad distribuida, contratos y costo operativo sin un riesgo actual que lo justifique. El equipo puede recomendar una opción más simple y dejar explícito qué señales harían revisarla.
Cuando la objeción cambia el alcance, el recorrido no termina en la reunión. El diagrama muestra cómo entra un cambio de evidencia, desde el dato del cliente hasta la entrada cerrada en el changelog.
Nexo B2B · La reunión de defensa completa
Dueño: "No entiendo por qué tardaron tanto en definir antes de programar". Equipo: "Parte de ese tiempo evitó construir tres supuestos que resultaron falsos: el saldo del ERP no era la exposición usada por ventas, la sustitución no tenía reglas estructuradas y el stock tenía un problema físico además de concurrencia. Si hubiéramos programado el brief original, esas correcciones habrían ocurrido dentro del código".
Dueño: "¿Por qué PostgreSQL y no algo más escalable?". Equipo: "El volumen actual no exige distribución. Sí necesitamos transacciones y una forma sólida de proteger reservas. PostgreSQL cubre eso con menor costo operativo. Si el volumen o aislamiento cambian, el ADR deja registrado qué señales justificarían revisar la decisión".
Responsable comercial: "Quiero que la IA apruebe automáticamente los clientes buenos". Equipo: "Hoy la categoría 'bueno' todavía combina información tácita y excepciones. Podemos usar IA para analizar antecedentes o sugerir, pero convertirla en autoridad de crédito sin una política validable haría imposible explicar por qué un pedido fue aprobado. Primero estructuramos la regla y la evidencia".
Depósito: "El sistema va a decir que hay stock, pero si físicamente no está seguimos igual". Equipo: "Correcto. La reserva evita que dos pedidos digitales usen la misma unidad, pero no corrige movimientos físicos mal registrados. Ese segundo problema necesita un proceso de ajuste/conteo. Lo dejamos explícito para no vender una garantía que el software no puede cumplir solo".
Esta conversación demuestra madurez porque el equipo no intenta ganar todos los puntos. Reconoce límites, separa problemas y muestra dónde una decisión es provisional. La confianza profesional surge más de explicar incertidumbre que de fingir certeza.
12.12 Cerrar con próximos pasos verificables
El cierre debe dejar decisiones, responsables y evidencia pendiente. Si se aprueba avanzar, el cliente debe saber qué se construye primero, qué verá en la siguiente demo y qué información todavía debe aportar. Una buena propuesta conecta precio y calendario con slices y resultados, no con capas técnicas.
Los cambios de alcance que aparecieron en la negociación se registran en un changelog. No es un documento de historia: es el registro que permite decir, en la siguiente reunión, qué cambió, por qué, quién lo aprobó y qué se movió en plazo, costo, riesgo y pruebas. Cada entrada apunta a la decisión vinculada.
proyecto: nexo-b2b-release-1
cambios:
- id: CL-001
fecha: inicio del Sprint de defensa
cambio: la cuenta corriente completa pasa de IN a OUT
alcance_queda: vista del saldo del ERP y estado de crédito del pedido, con su fuente
alcance_sale: notas de crédito, reclamos y conciliación
motivo: el pedido pedía saldos, comprobantes, cheques, notas de crédito y reclamos; la evidencia muestra que el problema del piloto es la reserva y la confirmación
impacto:
plazo: el primer corte se mantiene
costo: la cuenta corriente completa se presupuesta en una fase posterior
riesgo: el cliente puede esperar conciliación en el primer release
pruebas: se retiran los casos de conciliación del plan del release
decision_vinculada: DEC-04-01
aprobado_por: dueña de Nexo
- id: CL-002
fecha: revisión de la propuesta
cambio: la sustitución automática de SKU pasa a BLOCKED
motivo: el depósito pide sustitutos automáticos, pero no hay matriz de compatibilidad ni preferencia definida
impacto:
plazo: sin cambio en el primer corte
costo: sin costo adicional hasta validar la matriz
riesgo: las sustituciones siguen siendo manuales en picking
pruebas: sin pruebas en el release; queda como caso de la fase posterior
estado: BLOCKED
duenos: [responsable de depósito, comercial]
- id: CL-003
fecha: revisión de la propuesta
cambio: la reserva blanda no expira automáticamente (RN-07 BLOCKED)
motivo: no hay dato validado sobre cuánto tarda una autorización en la operación real
impacto:
plazo: sin cambio
costo: sin costo adicional; se requiere medición en la primera semana
riesgo: las reservas de pedidos pendientes pueden congelar stock hasta que alguien resuelva
pruebas: el caso de expiración se modela como pendiente y no se prueba en el release
aprobado_por: dueña de Nexo
Este changelog cumple una regla: cada entrada tiene motivo, impacto en los cinco frentes y quién aprobó. Si una entrada no tiene aprobador, el cambio no existe para el cliente, aunque el equipo ya lo esté construyendo. Fijate también en CL-003: el campo riesgo dice lo que puede pasar, no lo que el equipo espera que pase. Esa diferencia es la que permite defender el cambio.
12.13 Convertir la defensa en una propuesta económica
El precio profesional no necesita exponer cada hora interna, pero sí debe reflejar alcance, riesgo y valor. El Sprint permite agrupar entregables por slices y señalar qué supuestos sostienen la estimación. Elementos BLOCKED pueden cotizarse después de discovery adicional o como opciones condicionadas.
Una propuesta también debe describir responsabilidades del cliente: disponibilidad de stakeholders, acceso a sistemas, validación de reglas, datos de prueba y tiempos de respuesta. Si esas dependencias no se explicitan, un retraso de evidencia parece retraso de desarrollo.
Nexo B2B · Cierre comercial sin promesas falsas
La propuesta no promete "eliminar todos los errores de stock". Promete evitar sobreventa por concurrencia dentro del stock registrado y hacer visible el quiebre físico cuando se detecta. Tampoco promete "automatizar crédito con IA". Promete aplicar políticas confirmadas y auditar excepciones. La precisión comercial refleja la precisión de ingeniería.
Microtaller · Reescribir promesas infladas
Reescribí cinco frases comerciales vagas: "cero errores", "100 % automatizado", "escalable infinitamente", "IA inteligente", "tiempo real". Convertí cada una en una promesa verificable o eliminála si no puede sostenerse. Para cada una, indicá qué medirías y con qué fuente.
12.14 Defender una solución es reconstruir la cadena de decisiones
Una defensa técnica no necesita impresionar con nombres de patrones. Necesita poder recorrer la cadena desde una preocupación del cliente hasta una decisión y su consecuencia. "Usamos PostgreSQL porque es robusto" es débil. "La reserva concurrente debe preservar disponibilidad no negativa, el volumen actual es moderado y necesitamos una transacción clara; por eso concentramos esa invariante en PostgreSQL y la probamos con operaciones simultáneas" es una explicación que el cliente puede cuestionar.
Los trade-offs se presentan con lo que ganamos, lo que pagamos y qué señal haría revisar la decisión. Monolito modular gana simplicidad operativa y consistencia local, paga menor aislamiento independiente. Automatización parcial de crédito gana seguridad frente a políticas todavía no unificadas, paga intervención humana en excepciones. La honestidad sobre el costo vuelve la propuesta más defendible, no menos.
Decir "todavía no lo sabemos" también necesita estructura. Nombrá qué falta, por qué importa, qué se hará para resolverlo y qué decisión queda bloqueada mientras tanto. "No sabemos cuánto dura una reserva y necesitamos política comercial antes de automatizar expiración; por ahora el release no liberará por TTL automático" transmite control. "Eso lo vemos después" transmite olvido.
Cuando el cliente pide una capacidad fuera del alcance, la respuesta debe volver al objetivo y al impacto. No se trata de defender el documento por orgullo. Tal vez la nueva información justifique cambiar el Sprint. Pero el cambio debe hacerse visible en tiempo, costo, riesgo y pruebas. Un alcance profesional puede moverse; lo que no debe hacer es expandirse silenciosamente.
La propuesta comercial gana precisión cuando se apoya en slices y evidencia. En vez de vender "automatización integral", se puede vender una primera capacidad con resultados verificables, explicar qué decisiones quedan para fases posteriores y qué señales dispararán esas fases. Esto reduce promesas difusas y permite que precio y alcance compartan una misma estructura.
La cadena completa de esta defensa, con la decisión que vamos a documentar en el one-pager de la siguiente sección, se ve así:
La IA puede preparar preguntas difíciles, actuar como reviewer escéptico y detectar afirmaciones sin respaldo en una presentación. No debe inventar ROI ni convertir estimaciones en resultados garantizados. Usala para ensayar la defensa: pedile objeciones técnicas, operativas y comerciales, luego obligate a responder con evidencia del proyecto.
Nexo B2B · La reunión donde el cliente discute cada decisión importante
El dueño abre: "Yo esperaba que el portal sacara a los vendedores del medio". El equipo no responde "eso estaba OUT". Explica que la evidencia mostró que los vendedores no solo transcriben, también resuelven códigos, precios y excepciones. El primer release automatiza el camino estándar y vuelve explícitas las decisiones que todavía requieren criterio. El objetivo es reducir intervención innecesaria sin esconder los casos que todavía necesitan autoridad humana.
Ventas pregunta por qué el precio no viene directo del ERP si eso sería más simple. El equipo muestra los acuerdos especiales encontrados y la decisión de autoridad. La respuesta incluye un costo: habrá que normalizar acuerdos y mantener vigencia. También incluye una ganancia: el cliente no puede enviar un precio manipulado y el sistema puede explicar qué política se aplicó. La decisión deja de parecer complejidad técnica gratuita.
Sergio (depósito) cuestiona la palabra "reserva": "si el físico está mal, igual pueden prometer algo que no existe". El equipo coincide. La reserva evita sobreventa lógica entre pedidos concurrentes, no corrige inventario físico. Por eso el sistema registra quiebre durante picking y la métrica de diferencias queda en la operación. El cliente escucha una limitación concreta en lugar de una promesa de stock perfecto.
Sistemas pregunta por microservicios. El equipo responde con volumen, transacciones y costo operativo. Hoy separar servicios agregaría coordinación y despliegues sin una necesidad demostrada. Se deja una señal de revisión: si aparecen equipos independientes, escalado muy desparejo o aislamiento requerido, se reevalúa. La arquitectura se presenta como decisión contextual, no como identidad tecnológica de Eje Z.
Administración pregunta qué pasa con cheques pendientes. El equipo muestra BLOCKED y no lo disfraza. La fuente actual no actualiza con la frecuencia necesaria y no hay política acordada para una estimación. El primer release deriva esos casos a revisión. Nexo acepta porque la alternativa sería automatizar con datos que la propia empresa considera incompletos.
Luego aparece la pregunta comercial: "¿qué recibimos al final de esta etapa?". La respuesta no enumera documentos. Nexo recibe un slice operativo y verificable, reglas explicitadas, decisiones arquitectónicas justificadas, pruebas de los riesgos principales, runbook de despliegue y un backlog donde cada fase futura tiene condiciones. Los artefactos son parte de esa capacidad, no el producto vendido.
La reunión termina con próximos pasos y métricas: tiempo medio de confirmación, porcentaje de pedidos que requieren intervención, quiebres físicos detectados, autorizaciones y errores de precio. No se promete un porcentaje de mejora inventado. Se acuerda línea base y ventana de medición. La defensa técnica se convierte así en una conversación comercial seria: qué valor se espera, qué evidencia lo demostrará y qué riesgos siguen abiertos.
Guion de defensa de referencia (8 minutos)
El guion es el artefacto que organiza la voz de la defensa. Esta versión de referencia sirve para comparar con la tuya en la lección 12.3. Cada bloque tiene tiempo, una idea y la evidencia que la sostiene. No es un texto para leer de corrido: es el orden en que aparecen las afirmaciones, con su respaldo al lado.
# Guion · Defensa del release 1 de Nexo B2B (8 minutos)
## 0:00 a 2:00 · El problema, con un hecho
- Hecho: el pedido 48172 pidió 3 unidades de AX-442 en CBA. El ERP mostraba 8, la pizarra registraba 6 reservadas y el disponible real era 2. La falta apareció en picking.
- Evidencia: foto del pedido y registro del ERP.
- Qué mostramos: que el problema es la coordinación del stock, no la voluntad de los vendedores.
## 2:00 a 4:30 · Tres decisiones con consecuencia
- Decisión 1 (DEC-12-01, ADR-002): la disponibilidad se controla en PostgreSQL, dentro de la transacción del pedido. Consecuencia: no hay sobreventa dentro del stock registrado. Señal: quiebres en picking por semana.
- Decisión 2 (ADR-001): monolito modular con un proceso de apoyo. Consecuencia: pedido y reserva se confirman juntos. Señal: p95 del registro de pedido frente a NFR-01.
- Decisión 3 (ADR-006): huella del request para la idempotencia. Consecuencia: un reintento devuelve el mismo pedido y un conflicto de datos no crea nada.
## 4:30 a 6:30 · Evidencia, no adjetivos
- La prueba T06 con dos reservas concurrentes sobre la última unidad. Mostramos el control negativo: sin la condición, la prueba falla.
- La consulta de control sin-sobreventa: debe devolver 0 filas en cada ensayo de carga.
- Lo que todavía no medimos: el p95 del registro de pedido con la carga acordada. Se valida con prototipo.
## 6:30 a 7:30 · Límites, dichos en voz alta
- La reserva no corrige el stock físico. El quiebre se registra, se ajusta con auditoría y se mide.
- El tiempo de vida de la reserva blanda (RN-07) está BLOCKED: dueños, depósito y comercial.
- La tolerancia Platino (RN-02) está BLOCKED: dueños, Marta y Laura.
- La emisión de comprobantes con CAE queda fuera del primer release. El pedido queda pendiente de facturación.
## 7:30 a 8:00 · Próximos pasos con métrica
- Línea base: muestra de 60 pedidos observados antes del piloto.
- Medimos durante cuatro semanas: tiempo medio de confirmación, pedidos con intervención posterior, quiebres en picking, autorizaciones y errores de precio.
- Pregunta al cliente: qué dato de la tolerancia Platino pueden fijar antes del piloto.
Fijate en tres cosas del guion. Cada bloque abre con un hecho o una decisión, nunca con una garantía. Los límites están dichos en frases completas, no en un anexo. Y el cierre es una pregunta sobre un dato faltante, que es la forma de devolverle la decisión al cliente.
Evidencia: la frase que vamos a poder decir
Frase que queremos poder sostener frente al depósito: "En la prueba de carrera, dos pedidos no reservan la última unidad". Para decirla hacen falta tres piezas: la sentencia que reserva, la prueba que la ejercita y una consulta de control sobre los datos. Si falta una, la frase es una opinión.
La sentencia de reserva es una sola actualización condicional. Si la condición no se cumple, no se actualiza ninguna fila, y el adaptador responde "sin stock":
-- Reserva atómica (ADR-002): si la condición no se cumple, no se actualiza ninguna fila.
UPDATE stock_level
SET reserved = reserved + $3
WHERE product_id = $1
AND warehouse_id = $2
AND on_hand - reserved >= $3;
Además, la base rechaza cualquier estado que viole la invariante, aunque el código tenga un error:
ALTER TABLE stock_level
ADD CONSTRAINT reserva_no_excede_stock CHECK (reserved <= on_hand);
La prueba de carrera arranca dos transacciones a la vez, con una barrera que las obliga a competir por la última unidad:
it("solo una reserva gana la última unidad", async () => {
await stock.setAvailable(depotId, sku, 1);
const start = barrier(2);
const reserve = (orderId: string) =>
db.transaction(async tx => {
await start.wait();
return repo(tx).reserve({ orderId, depotId, sku, quantity: 1 });
});
const [a, b] = await Promise.all([reserve("O-A"), reserve("O-B")]);
expect([a, b].filter(x => x.kind === "Reserved")).toHaveLength(1);
expect([a, b].filter(x => x.kind === "InsufficientStock")).toHaveLength(1);
expect(await stock.available(depotId, sku)).toBe(0);
});
Esta es la forma que debería tener el resultado de la ejecución. Es una salida de ejemplo para que reconozcas el formato. No la cites como evidencia de tu entrega hasta haber corrido la prueba en tu entorno:
✓ tests/integration/stock-reservation.test.ts (1 test) 212ms
✓ solo una reserva gana la última unidad
Test Files 1 passed (1)
Tests 1 passed (1)
Una prueba que nunca falla no demuestra nada. Por eso también hay que correr el control negativo: cambiar la sentencia por una lectura seguida de una escritura sin condición, y verificar que la misma prueba falle. La salida esperada de ese control es la que sigue:
FAIL tests/integration/stock-reservation.test.ts > solo una reserva gana la última unidad
AssertionError: expected [ { kind: 'Reserved' }, { kind: 'Reserved' } ] to have a length of 1 but got 2
Si la prueba pasa con la lectura seguida de escritura, la prueba no sirve, y la frase "dos pedidos no reservan la última unidad" no se puede decir.
Por último, la consulta de control se corre sobre los datos después de cada ensayo de carga. Debe devolver cero filas. Si devuelve una, la invariante se rompió y el release no sale.
-- Debe devolver 0 filas. Cualquier fila es una violación de INV-01 (disponibilidad negativa).
SELECT product_id, warehouse_id, on_hand, reserved
FROM stock_level
WHERE reserved > on_hand;
Y para el número de pedidos duplicados, la consulta valida que ningún requestId quedó asociado a más de un pedido:
-- Debe devolver 0 filas: ningún requestId asociado a más de un pedido (AC-07, RN-06).
SELECT k.request_id, COUNT(DISTINCT k.order_id) AS pedidos
FROM idempotency_keys k
GROUP BY k.request_id
HAVING COUNT(DISTINCT k.order_id) > 1;
Esta consulta tiene un límite que conviene decir en voz alta. Con la clave primaria sobre request_id, el resultado siempre va a ser cero: su trabajo es ser la alarma si una migración la quita. No prueba que dos intenciones distintas del mismo cliente con el mismo contenido no sean duplicados comerciales. Esa es una regla de negocio abierta, y hay que preguntarla al cliente, no asumirla. Si en tu entrega escribís "cero pedidos duplicados" sin esta aclaración, estás prometiendo más de lo que la consulta mide.
One-pager de la decisión DEC-12-01
El one-pager es el artefacto que el dueño puede leer en cinco minutos y discutir sin el equipo. Tiene una decisión, lo que descartó, lo que garantiza, lo que no garantiza y lo que necesita del cliente. Así se ve para la decisión de reserva de stock:
# DEC-12-01 · Dónde se controla la disponibilidad de stock
Estado: propuesta para la reunión de cierre.
Para: Marta (dueña), Laura (administración y crédito), Sergio (depósito).
Autor: equipo Eje Z.
## Problema que resuelve
- El pedido 48172 pidió 3 unidades de AX-442 en CBA. El ERP mostraba 8, pero la pizarra registraba 6 reservadas con pedidos anteriores. Disponible real: 2. Faltó 1 y apareció en picking, a las 10:31.
- Hoy el ERP no registra reservas. Dos vendedores pueden prometer la misma unidad si no consultan la pizarra.
## Decisión
La disponibilidad por depósito y SKU se controla en PostgreSQL, dentro de la transacción del pedido. La reserva se confirma solo si la actualización condicional afecta una fila (ADR-002, RN-05).
## Alternativas descartadas
- Caché en Redis con bloqueo: agrega un segundo lugar donde vive el stock. No hay evidencia de que la latencia sea el problema.
- Reservar en el ERP: el ERP no tiene reservas y su cambio excede la etapa 1. Sigue siendo el maestro de productos.
- Cola de reservas: agrega latencia y estados intermedios sin resolver la concurrencia.
## Qué garantiza
- Dos pedidos concurrentes no reservan más unidades que las registradas en el sistema para un depósito y un SKU (AC-06, T06).
- Ninguna reserva deja disponibilidad negativa por depósito y SKU (INV-01).
- Un pedido con un mismo requestId no genera dos pedidos (RN-06, AC-07).
## Qué no garantiza
- No corrige el stock físico. Un quiebre en picking se registra, se ajusta con auditoría y se mide (RSK-01).
- No fija cuánto dura una reserva blanda: RN-07 queda BLOCKED.
## Costo y riesgo que asumimos
- Una base transaccional concentra la escritura de stock. Se mide contra NFR-01 (p95 menor a 800 ms en el registro de pedido, con 30 usuarios concurrentes). Hoy no hay medición: se valida con prototipo.
## Qué haría cambiar la decisión
- Una medición de NFR-01 que incumple el umbral por causa de la base y no de una consulta.
- Un segundo sistema que necesite reservar stock con otra fuente de verdad.
## Evidencia
- Prueba T06 (última unidad concurrente) en integración, con su control negativo.
- Consulta de control sin-sobreventa: debe devolver 0 filas en cada ensayo de carga.
## Lo que necesitamos de ustedes
- Confirmar que CBA y CEN registran los quiebres en picking con el mismo evento.
- Marta y Laura: decidir RN-02 antes del piloto. Depósito y comercial: decidir RN-07 con la medición de la primera semana.
Dos decisiones de redacción conviene notar. La primera es que el one-pager dice "hoy no hay medición" en la sección de costo: no oculta que el umbral no se midió. La segunda es que la sección "Qué no garantiza" es tan larga como la de garantías. Un one-pager cuya sección de límites es corta casi siempre oculta un límite.
Minuta de aceptación: revisá antes de firmar
La minuta de aceptación es el documento que el cliente firma para cerrar el alcance del release. Si una promesa queda escrita ahí, es contractual en la práctica, aunque nadie la discuta después. Por eso la revisión es más estricta que la de cualquier otro artefacto.
Revisá esta minuta, que el equipo redactó con prisa antes de la reunión. Hay cinco líneas que prometen algo sin criterio, sin medición o fuera de alcance. Marcá las líneas. Para cada una, preguntate quién puede comprobarla y con qué instrumento.
Cinco promesas que no pasan la firma
Hacé clic en cada línea que prometa un comportamiento sin criterio, sin medición, fuera de alcance o contra una decisión BLOCKED. Las líneas correctas pueden tener condiciones o declarar que el dato se confirma después.
Después de corregir la minuta, la versión correcta de esas cinco líneas no debe sonar más débil. "El sistema impide que dos pedidos confirmen la misma unidad del stock registrado (AC-06)" es una frase fuerte porque tiene criterio, prueba y frontera. La versión inflada, en cambio, es la que el cliente va a usar como argumento el día que aparezca el primer faltante en picking.
Comprobá tu criterio
El cliente pregunta cuánto va a mejorar el negocio. ¿Qué respuesta podés defender?
Errores frecuentes
- Síntoma: el cliente acepta el one-pager y después dice que "no sabía" que una parte no estaba incluida. Causa: la sección "Qué no garantiza" es corta o está escrita en lenguaje técnico. Corrección: escribí los límites con la misma longitud y el mismo nivel de detalle que las garantías, y leelos en voz alta con el dueño.
- Síntoma: un número de la presentación no lo puede explicar nadie cuando lo preguntan. Causa: el número se tomó de una nota de trabajo o de un ejemplo. Corrección: cada número tiene fuente, consulta o prueba que lo respalda. Si no la tiene, se presenta como hipótesis con su método de medición.
- Síntoma: la minuta de aceptación tiene promesas que el equipo nunca validó. Causa: se redactó a partir de la conversación y no de los artefactos. Corrección: revisá cada línea de promesas con la pregunta de quién la comprueba y con qué instrumento, antes de que alguien la firme.
- Síntoma: la prueba de concurrencia pasa siempre, incluso con una implementación incorrecta. Causa: nunca se corrió el control negativo. Corrección: cambiá la implementación a propósito por una lectura seguida de escritura y verificá que la prueba falle antes de confiar en ella.
- Síntoma: el changelog tiene entradas sin aprobador. Causa: el cambio se aceptó en la reunión y nadie lo registró formalmente. Corrección: no se construye un cambio de alcance sin entrada en el changelog con quién lo aprobó.
Para llevarte
- Un hecho sin fuente es una creencia. Antes de presentar un número, buscá la consulta, la prueba o el registro que lo sostiene.
- Distinguí hipótesis de valor, resultado medido, compromiso comercial y promesa indebida. Solo el primero y el tercero pueden aparecer sin medición, y siempre con su método.
- El one-pager tiene que mostrar con la misma claridad lo que garantiza y lo que no garantiza.
- Una prueba que nunca falla no demuestra nada: el control negativo es parte de la evidencia.
- Cada cambio de alcance entra al changelog con motivo, impacto en plazo, costo, riesgo y pruebas, y con quién lo aprobó.
¿Cómo valoras el contenido técnico de esta lección?
Tu feedback nos ayuda a mejorar los laboratorios prácticos de Eje Z.