WORKFLOW.md
Workflow, Estados y Transiciones
1. Objetivo
Definir cómo se mueven las entidades del sistema, qué estados existen, qué transiciones son válidas y qué reglas las gobiernan. Ningún agente IA puede inventar flujos fuera de lo definido aquí.
2. Entidades con workflow
| Entidad |
Tiene estados |
App |
Caja |
Sí |
app_caja |
Venta |
Sí |
app_caja |
Suscripcion |
Sí |
app_suscripciones |
Empresa (Tenant) |
Sí — Onboarding |
app_empresas |
3. Workflow: Caja
Estados
| Estado |
Descripción |
Visible para cajero |
Estado final |
CERRADA |
Estado inicial y post-cierre |
Sí |
No |
ABIERTA |
Caja en operación |
Sí |
No |
PENDIENTE_REVISION |
Cierre ciego declarado, pendiente de revisión por administrador |
Sí (solo estado) |
No |
Transiciones
| Desde |
Hacia |
Quién |
Validaciones |
CERRADA |
ABIERTA |
cajero, sucursal_admin, empresa_admin |
No haya otra caja abierta en la misma sucursal |
ABIERTA |
PENDIENTE_REVISION |
cajero, sucursal_admin |
Cajero declara monto físico. Backend calcula descuadre internamente |
PENDIENTE_REVISION |
CERRADA |
sucursal_admin, empresa_admin |
Administrador revisa y confirma el cierre |
Transiciones prohibidas
| Desde |
Hacia |
Motivo |
CERRADA |
PENDIENTE_REVISION |
El cajero no puede cerrar sin abrir primero |
PENDIENTE_REVISION |
ABIERTA |
No se puede reabrir sin confirmar el cierre previo |
Regla crítica
El monto esperado del sistema nunca se expone al cajero en ninguna transición ni endpoint. El descuadre es solo visible para sucursal_admin y superiores tras confirmar el cierre.
4. Workflow: Venta
Estados
| Estado |
Descripción |
Visible para vendedor |
Estado final |
BORRADOR |
Venta iniciada pero no confirmada |
Sí |
No |
CONFIRMADA |
Venta procesada con conexión activa |
Sí |
Sí |
PENDIENTE_SYNC |
Venta generada offline, en cola de sincronización |
Sí |
No |
SINCRONIZADA |
Venta offline confirmada por el servidor |
Sí |
Sí |
ANULADA |
Venta cancelada (solo por admin) |
Sí |
Sí |
Transiciones
| Desde |
Hacia |
Quién |
Validaciones |
BORRADOR |
CONFIRMADA |
vendedor, cajero (con conexión) |
Stock disponible, caja abierta, precios vigentes |
BORRADOR |
PENDIENTE_SYNC |
vendedor, cajero (sin conexión) |
Caja abierta. Stock no validado hasta sincronización |
PENDIENTE_SYNC |
SINCRONIZADA |
Sistema (Celery) |
Stock disponible al momento de sync, precios válidos |
PENDIENTE_SYNC |
ANULADA |
Sistema (Celery) |
Si la validación falla al sincronizar (stock insuficiente) |
CONFIRMADA |
ANULADA |
sucursal_admin, empresa_admin |
Motivo obligatorio. Auditoría requerida |
Transiciones prohibidas
| Desde |
Hacia |
Motivo |
CONFIRMADA |
BORRADOR |
Una venta confirmada no puede volver a borrador |
SINCRONIZADA |
PENDIENTE_SYNC |
Una venta sincronizada no puede volver a cola |
ANULADA |
Cualquier estado |
La anulación es irreversible |
Reglas de resolución de conflictos en sincronización
Decisión formal: docs/adr/ADR-004-resolucion-conflictos-sync-offline.md
| Conflicto |
Regla |
Estado final |
Visible para |
| Stock insuficiente al sincronizar |
Venta aceptada — stock queda negativo. Se genera alerta |
SINCRONIZADA + flag conflicto_stock=True |
sucursal_admin |
| Precio modificado durante desconexión |
Venta aceptada con precio offline — diferencia registrada como evento auditable |
SINCRONIZADA + flag conflicto_precio=True |
empresa_admin |
| Caja cerrada durante desconexión |
Venta rechazada — motivo: CAJA_CERRADA_DURANTE_SYNC |
ANULADA |
sucursal_admin (notificación) |
Toda la lógica de resolución vive en app_caja/services.py — nunca en la tarea Celery ni en el frontend.
5. Workflow: Suscripción
Estados
| Estado |
Descripción |
Estado final |
TRIAL |
Período de prueba gratuito |
No |
ACTIVA |
Plan vigente y pago al día |
No |
SUSPENDIDA |
Plan vencido o pago pendiente. Features bloqueadas |
No |
CANCELADA |
Tenant dado de baja |
Sí |
Transiciones
| Desde |
Hacia |
Quién |
Validaciones |
TRIAL |
ACTIVA |
super_admin |
Confirmación de pago o activación manual |
ACTIVA |
SUSPENDIDA |
super_admin / Sistema |
Vencimiento de pago |
SUSPENDIDA |
ACTIVA |
super_admin |
Regularización de pago |
ACTIVA |
CANCELADA |
super_admin |
Confirmación explícita |
SUSPENDIDA |
CANCELADA |
super_admin |
Confirmación explícita |
6. Workflow: Onboarding de Empresa (Tenant)
Estados
| Estado |
Descripción |
Estado final |
PENDIENTE |
Empresa creada, wizard no completado |
No |
WIZARD_COMPLETADO |
Datos básicos cargados, rubro seleccionado |
No |
ACTIVO |
Tenant operativo |
No |
Transiciones
| Desde |
Hacia |
Quién |
Validaciones |
PENDIENTE |
WIZARD_COMPLETADO |
empresa_admin |
Nombre comercial, moneda y rubro seleccionados |
WIZARD_COMPLETADO |
ACTIVO |
Sistema |
AtributoConfig precargados según rubro |
7. Reglas de implementación
- Todas las transiciones se validan en el backend — el frontend puede ocultar botones pero no decide la validez final.
- Cada transición relevante genera un evento auditable.
- Las transiciones de
Venta en modo offline se procesan por Celery — nunca de forma síncrona.
- El cierre de caja nunca expone el saldo esperado al cajero en ningún endpoint ni respuesta.
- El backend rechaza toda transición inválida con error
400 Bad Request y mensaje descriptivo.
8. Sprint 0
Durante Sprint 0 no se programan features de negocio. Sprint 0 construye:
- Proyecto Django con
django-tenants configurado.
- Schemas
public y tenant funcionales.
- Modelo de
Usuario y autenticación JWT.
- Estructura modular de apps.
- Docker Compose completo (PostgreSQL, Redis, Celery, Nginx).
- Frontend base React + Vite + PWA shell.
- CI/CD inicial.
- Documentación viva completa.
9. Definition of Done para un flujo
Un flujo está completo si:
- El backend valida todas las transiciones.
- El frontend muestra solo las acciones permitidas al rol activo.
- Hay tests de transiciones válidas e inválidas.
- Hay auditoría en cada transición relevante.
- Respeta los permisos de
RBAC.md.
- Respeta el aislamiento multi-tenant.