Appearance
Diseño de negocio: inventario, colaboración y offline
Documento migrado desde
franmc01/ninaku-core-api.
Estado: propuesta de contratos para el refinamiento. No implementa funcionalidad nueva. El objetivo de producto es crecer desde un restaurante pequeño sin obligarlo a configurar una suite ERP completa.
1. Complejidad progresiva con el mismo modelo
| Escenario | Experiencia inicial | Capacidad adicional cuando haga falta |
|---|---|---|
| Restaurante pequeño | Producto, venta, cobro e impresión desde teléfono | Recetas, lotes, cocina, conteos y compras |
| Restaurante con varias ubicaciones | Stock por ubicación y traslados visibles | Tránsito, diferencias de recepción, compras centralizadas |
| Retail | Variantes, códigos, stock directo, venta y devolución | Lotes, serialización si el caso lo exige, abastecimiento |
| Hotel con restaurante | Un tenant con capacidades combinadas | Estadías/folios propios; cargo de consumo mediante contrato explícito |
El usuario puede ver una sola sucursal y una ubicación predeterminada. Internamente el contexto legal, moneda, unidad y propiedad sigue siendo explícito. No exigir al pequeño comercio nómina, contabilidad completa, créditos o lotes si su operación no los requiere. No definir precios, demanda ni promesas comerciales sin validación con clientes.
2. Inventario profesional
Propietarios
Catalog representa lo comercial. Inventory representa el recurso físico y su custodia. Production explica transformaciones. Procurement conserva el compromiso y los documentos de compra. Accounting representa consecuencias económicas. La botella vendida puede tener un enlace directo a stock; una hamburguesa requiere receta/configuración congelada y consumo explicado.
Conservar del baseline items, packages, locations, lots, stock_movements, stock_ledger_entries, reservas, transferencias, conteos y valoración. Antes de añadir tablas, comprobar qué garantía falta en esas estructuras.
Contratos que hay que demostrar
| Área | Regla | Ejemplo de aceptación |
|---|---|---|
| Identidad física | Unidad base e incremento explícitos; significado congelado tras primer uso | Un borrador persistido impide reinterpretar kg como g; rollback no fabrica historial |
| Conversiones | Conversión dimensional y presentación comercial separadas | Una caja contiene 12 unidades; factor, precio y cantidad física tienen contratos distintos |
| Lotes | Cantidad, origen y caducidad trazables cuando aplica | Identificar qué recepciones abastecieron un consumo |
| Disponibilidad | Cantidad utilizable separada de reservada, bloqueada y en tránsito | No descontar dos veces cuarentena y reservas solapadas; definir conjuntos/estados disjuntos |
| Saldo | Fuente histórica y lectura operativa coherentes | Reconstrucción produce el mismo saldo; admisión concurrente usa estado actualizado bajo bloqueo |
| Reservas | Crear, consumir, liberar y expirar sin perder capacidad | Dos compradores no reservan la misma última unidad bajo política estricta |
| Transferencia | Despacho, tránsito, recepción y diferencia separados | De 4 despachadas, 3 recibidas y 1 pendiente; no crear pérdida hasta resolverla |
| Conteo | Punto de corte y movimientos posteriores definidos | Contar mientras se vende produce un ajuste explicado, no sobrescribe ventas |
| Valoración | Método y vigencia separados de movimiento físico | Corrección de costo modifica valor con trazabilidad, no cantidad |
| Reversos | Consecuencias históricas conservadas | Corregir un consumo no borra qué ocurrió ni reinterpreta una receta anterior |
FEFO para selección por caducidad y FIFO para valoración son conceptos distintos. Definir método de costo por entidad/política antes de publicar movimientos; no escoger un método contable por conveniencia técnica. Consignación, seriales, landed cost y múltiples propietarios de stock son extensiones a justificar con clientes concretos; no afirmar que el baseline ya las cubre.
El bloqueo debe proteger el ámbito que comparte capacidad (producto/ubicación/lote y reservas aplicables). Orden consistente de adquisición, reintentos limitados de la operación completa y clave idempotente. Un saldo de dashboard eventualmente actualizado no autoriza una salida estricta. PostgreSQL documenta que Read Committed no impide por sí solo anomalías de serialización: aislamiento.
3. Conectar negocios sin compartir su verdad
Tres casos distintos
| Caso | Contrato |
|---|---|
| Dos ubicaciones de la misma entidad legal | Transferencia interna con tránsito |
| Dos entidades legales del mismo tenant | Hechos de venta/compra y consecuencias por entidad según el proceso aplicable |
| Dos tenants independientes | Acuerdo autorizado de intercambio, documentos locales y mensajes correlacionados |
El baseline ya restringe transferencias ordinarias a una entidad legal. No relajarlo para resolver B2B. Una empresa en Party del comprador no es automáticamente el tenant del vendedor, ni un RUC coincidente prueba consentimiento o autoriza vinculación.
Contrato mínimo de colaboración propuesto
- Acuerdo entre participantes autenticados, aceptación de ambas partes, alcance, vigencia y revocación.
- Correlación de solicitud/confirmación/expedición; versión del mensaje y clave de entrega.
- Cada módulo conserva puentes tipados a sus documentos locales; no una tabla universal entity_type/entity_id.
- Mapeo aceptado entre producto del vendedor y recurso del comprador, presentación/unidad y lote externo si corresponde. No compartir el mismo item_id entre tenants.
- Snapshot de lo intercambiado; cambios del catálogo del vendedor no alteran la compra aceptada.
- Bandejas de envío/recepción durables, reintentos, rechazo, mensajes fuera de orden y conciliación visible.
- Cancelación posterior a despacho produce un proceso compensatorio; no elimina documentos del otro participante.
- Recepción parcial, faltante, exceso y rechazo registrados por quien recibe. Despacho no confirma recepción.
- Compartir solo campos consentidos: no revelar margen, costo interno, clientes ni stock completo por defecto.
El intercambio interno usa una autoridad de servicio estrecha y entrega cada mensaje en el contexto autorizado del destinatario; el tenant emisor nunca obtiene capacidad de ejecutar SQL como el receptor. Revocación impide nuevos intercambios pero conserva la evidencia histórica necesaria. No se implementa un proveedor ni un motor B2B en este PR.
4. Offline como contrato de producto
Persistencia local y servidor
SQLite es la propuesta para clientes móviles/escritorio. Un cliente web requiere seleccionar y probar almacenamiento durable compatible; no asumir que el navegador ejecuta el mismo SQLite nativo. Solo se sincroniza el subconjunto autorizado por dispositivo/scope. No replicar los 800 objetos de PostgreSQL ni ejecutar triggers PostgreSQL en el cliente.
Cada operación local conserva command_id, dispositivo, tenant, contrato/versiones, identidad autorizada, datos del comando y estado local de resultado. El cambio local y su cola deben persistirse atómicamente. La hora del cliente sirve como evidencia, no como orden global confiable.
Online y replay convergen en el mismo caso de uso del servidor. Las validaciones locales ayudan a operar; no sustituyen seguridad e invariantes servidor. Versiones de catálogo/precios/receta usadas se conservan para explicar lo sucedido; un cambio posterior puede producir aceptación según política o conciliación, nunca modificación silenciosa del cobro histórico.
Matriz inicial de admisión propuesta
| Operación | Offline propuesto | Reconciliación/condición |
|---|---|---|
| Venta directa y efectivo | Permitido con configuración sincronizada | Preservar hecho físico/cobro; discrepancias se resuelven, no se borran |
| Comanda e impresión local | Permitido en dispositivos habilitados | No reimprimir por replay; resultado incierto requiere decisión explícita |
| Stock no estricto | Permitido bajo política visible | Registrar discrepancias/faltantes al reconectar sin alterar hechos |
| Stock estrictamente limitado | Capacidad asignada previamente o coordinación local | No permitir gasto concurrente del mismo saldo global |
| Crédito y puntos globales | Online inicialmente; offline solo con asignación explícita | Evitar que dos terminales gasten el mismo límite/saldo |
| Tarjeta | Depende de contrato y hardware del proveedor | Pendiente no equivale a capturado; no guardar datos sensibles de tarjeta en Ninaku |
| Recepción física | Registro local permitido según autorización | Vincular a pedido/recepción al reconectar, conservar diferencias |
| Conteo | Captura local | Aprobación/ajuste necesita punto de corte y conciliación con movimientos |
| Transferencia entre ubicaciones aisladas | Registro de cada hecho local | No inferir recepción del despacho; resolver correlación al reconectar |
| Nueva relación B2B o cambio de permisos | Online | Requiere aceptación y autoridad actual |
| Emisión fiscal | Solo bajo contrato regulatorio/proveedor implementado | Número reservado no demuestra autorización fiscal; validar jurisdicción por separado |
Capacidad exclusiva
Si quedan 10 unidades, asignar 6 a A y 4 a B consume esa capacidad del pool compartido. Cada uno gasta como máximo su asignación. Una expiración en el servidor no permite reasignar sin saber si el dispositivo desconectado gastó: hace falta cierre/reconciliación o una prueba de revocación efectiva. De lo contrario se recupera capacidad ficticia. El contrato debe incluir reinicio de dispositivo, duplicación de archivos y recuperación de sesión.
No imponer coordinador local a un negocio que opera con un teléfono. Para varios terminales, distinguir internet caído con LAN disponible de partición entre terminales. Un coordinador opcional necesita autoridad/fencing y no puede permitir dos líderes gastar el mismo saldo. Es una etapa posterior, no un requisito del primer cliente.
Sincronización y seguridad
Bootstrap necesita snapshot coherente + cursor compatible; no usar MAX(id), UUIDv7 o la secuencia asignada antes de commit como prueba de orden de publicación. Procesar cambios según posición de publicación estable y estrategia comprobada contra commits fuera de orden. Ack solo después de aplicar durablemente. Retención y expiración del cursor requieren rebootstrap seguro sin perder comandos pendientes.
La identidad offline requiere concesión acotada y almacenamiento protegido. La revocación inmediata no es posible sin comunicación. Distinguir rechazo de nuevas intenciones de revisión de efectivo/mercadería ya entregados. Toda decisión queda atribuida; nunca ampliar scope por haber aceptado un payload local.
La impresión física tiene una ventana entre enviar bytes y persistir confirmación. Un fallo allí puede dejar resultado desconocido: no prometer exactly-once físico. Registrar intentos, confirmaciones y reimpresiones explícitas. La deduplicación de comandos reduce duplicados lógicos, no prueba que el papel salió una sola vez.
5. Referencias de producto y límites de las inferencias
Revisión pública al 2026-09-12, fuentes primarias. Se toman patrones de operación; no se afirma disponibilidad de proveedores en Ecuador, precios, liderazgo de mercado ni paridad de producto.
| Fuente | Evidencia acotada | Inferencia para Ninaku |
|---|---|---|
| Odoo: multi-company | La documentación de la función describe compraventa entre compañías de una base | Separar intercompany de un traslado ordinario. Consulta mediante resultado indexado; apertura completa no disponible |
| Odoo: inventory management | Documenta ubicaciones de tránsito para operaciones entre compañías/almacenes | Hacer visible mercancía despachada pendiente de recepción. Consulta mediante resultado indexado |
| Shopify: POS offline features | Distingue funciones disponibles offline, sincronización posterior, captura de tarjeta y conectividad local de impresoras | Definir una matriz por operación; desacoplar falta de internet de impresión por Bluetooth/LAN |
| Square: pagos offline | La función depende de configuración/dispositivo y posterior carga de pagos | Un cobro pendiente del proveedor necesita estado explícito; no copiar límites horarios o compatibilidad sin contrato local |
Estas referencias no justifican reconstruir un ERP completo. La prioridad comercial propuesta es continuidad de caja e impresión, stock explicable y recepción/traslado sin pérdidas. B2B requiere validar un proveedor y comprador reales antes de generalizar una red comercial. La validación de mercado pendiente debe observar operaciones actuales, costo de errores y disposición a usar/pagar, sin inventar métricas.