Picko PdV · Pizza de Verdad
Picko PdV es el fork de Picko (pedidos por WhatsApp Flows, CRM, cocina y reparto) adaptado a Pizza de Verdad, una cadena de sedes franquiciadas. La plataforma es de un equipo; mi parte fueron tres módulos. Delivery con terceros: desde «¿Quién lo lleva?» la sede pide el viaje a Yummy Rides o Armi, o Picko lo pide solo al pasar el pedido a «Listo»; los estados llegan por webhook y por una reconciliación periódica, y mueven el pedido por el mismo camino que un repartidor propio. Disciplina y Auditoría (en producción): mide cada sede por semana con datos que la plataforma ya registra (respuesta de chats, entregas, pagos, calificaciones), calcula una nota ponderada por regla y le da al auditor excepciones, multas, bitácora y un reporte en PDF. Para Alberca, la distribuidora del grupo, escribí el backend inicial de cobranza sobre su propia base Supabase: un motor que planifica avisos, cobros y recordatorios por días hábiles con feriados de Venezuela, más la ingesta de clientes y facturas desde Galac.
Crear un viaje no es idempotente
Ni Yummy ni Armi tienen idempotencia al crear, y la cuenta de cada uno es prepagada: reintentar tras un timeout puede pagar dos viajes. Solución: el servidor vuelve a cotizar, compara con el precio que vio la sede y escribe una fila «pidiendo» antes de llamar al proveedor; un índice único permite un solo viaje activo por pedido. El create nunca se reintenta: si queda sin respuesta, el webhook adopta el viaje por el id del pedido o la sede lo descarta.
Yummy no cancela sin conductor
Si al minuto nadie tomó el viaje, la sede puede pasar el pedido a un motorizado propio, pero Yummy no deja cancelar mientras busca conductor: el que llegue después iría a buscar un pedido que ya salió. Solución: cada adaptador declara si cancela sin conductor. Armi se cancela en el acto; el viaje de Yummy queda marcado como liberado y se cancela solo en cuanto el proveedor informa un conductor.
Una nota que se pueda defender
El auditor multa a partir de la nota, así que el número y la evidencia no pueden contradecirse. Solución: una función SQL lista cada evento que cuenta para una regla, y de esa misma lista salen la medición y los casos que ve la sede. La semana se congela el sábado para respetar el plazo de excepción, y la multa y el PDF de una semana cerrada usan los números del cierre.
Capa común con adaptadores
Un contrato AdaptadorProveedor (conectar, validarParaCrear, cancelaSinConductor, habilitado) aísla lo propio de cada API. La capa común hace el resto: permiso y alcance por sede, interruptor por sede, snapshot del precio en la moneda del proveedor con su tasa, bitácora idempotente de eventos que solo avanza el estado y aviso push a la sede. Así Yummy y Armi se construyeron en paralelo sin tocar lo común.
No cargar al proveedor
Disyuntor por tenant: tras 3 fallos seguidos corta 30 s y deja salir una sola llamada de prueba. Ningún POST se reintenta; un GET, una vez, con pausa aleatoria de 250 a 750 ms y nunca ante un timeout. La reconciliación corre cada 2 minutos como red de seguridad del webhook: una pasada a la vez, con 40 s de presupuesto y espera creciente por viaje que falla (de 2 a 30 min).
Galac sin abrir puertos
Un agente en PowerShell 5.1 corre junto a la base de Galac con el Programador de tareas, lee con un usuario de solo lectura y empuja lotes por HTTPS a un endpoint con llave propia. Cada ejecución cierra un run con los totales esperados, que el panel contrasta (ok, con errores o fallida); ante un 5xx reintenta el mismo lote sin duplicar, porque la ingesta es un upsert. El motor solo cobra facturas vistas en la última sincronización buena y nace apagado: planifica, no envía.