PROJECT_CONTEXT.md
Contexto del Proyecto
1. Nombre del proyecto
Nombre: Venuo Descripción breve: ERP SaaS multi-tenant para comercios de mostrador físicos (ferreterías, librerías, almacenes) con POS de alta velocidad, resiliencia offline y control de stock multi-sucursal. Diseñado para el mercado argentino.
2. Problema que resuelve
Situación actual
- Los comercios de mostrador carecen de sistemas de gestión integrados o usan soluciones lentas y desconectadas.
- El POS se bloquea ante microcortes de red, deteniendo la operación del mostrador.
- El stock no está sincronizado entre sucursales en tiempo real.
- No existe control de integridad en el cierre de caja (el cajero conoce el saldo esperado).
- Los catálogos de productos de rubros distintos requieren estructuras de datos diferentes, forzando cambios de esquema costosos.
Dolor principal
Un corte de internet de 5 minutos no puede detener la venta de mostrador de un comercio físico.
3. Objetivo del sistema
El sistema debe permitir:
- Operar el POS sin interrupción ante microcortes de red mediante caché local y cola de sincronización asíncrona.
- Gestionar stock multi-sucursal con alertas automáticas de stock mínimo.
- Controlar el cierre de caja de forma ciega: el cajero declara efectivo físico sin conocer el saldo esperado.
- Adaptar el catálogo de productos a cualquier rubro comercial sin alterar el esquema de base de datos.
- Habilitar o bloquear funcionalidades avanzadas según el plan de suscripción del tenant, validado exclusivamente en el backend.
4. Usuarios principales
| Actor | Descripción | Necesidad principal |
|---|---|---|
| Súper Administrador | Gestión global del SaaS — opera en esquema public |
Administrar tenants, planes y accesos globales |
| Empresa (Tenant) | Dueño del comercio, posee su propio esquema de DB | Configurar sucursales, usuarios y catálogo base |
| Sucursal | Local físico dependiente de la Empresa | Gestionar su stock, caja y ventas locales |
| Cajero / Empleado | Opera el POS y la caja de su sucursal | Vender rápido, cerrar caja, operar sin internet |
| Vendedor | Opera el POS sin acceso a caja | Registrar ventas únicamente |
| Entidad Comercial | Clientes y proveedores del tenant | Ser gestionado como contacto comercial y fiscal |
5. Alcance inicial — Fase 1 (MVP)
Incluido en el MVP
- Wizard de onboarding inicial (nombre comercial, moneda, rubro base).
- Gestión de Empresas y Sucursales (
app_empresas). - Suscripciones y Feature Flags por plan (
app_suscripciones). - Inventario con atributos dinámicos por rubro via JSONB (
app_inventario). - Actualización masiva de precios por proveedor o categoría en el backend.
- Importador masivo asíncrono de productos (Excel/CSV).
- Caja con apertura, movimientos y cierre ciego (
app_caja). - POS táctil con resiliencia offline (IndexedDB + cola de sincronización).
Fuera de alcance — Fase 1
- Facturación electrónica ARCA/AFIP (módulo visible pero deshabilitado en UI).
- Escáner por cámara en PWA.
- Cuentas corrientes avanzadas (crédito a clientes, saldos proveedores).
- Portal E-commerce.
- Modo offline completo con sincronización bidireccional avanzada.
6. Reglas del negocio
| Regla | Descripción | Impacto técnico |
|---|---|---|
| Cierre de caja ciego | El cajero declara efectivo físico sin ver el saldo esperado del sistema | Backend calcula descuadre y lo reporta solo al Administrador |
| Feature flags en backend | Las funcionalidades avanzadas se bloquean en el backend, nunca solo en el frontend | Validación en core_api antes de cualquier operación avanzada. Error 403 si el plan no lo permite |
| Atributos dinámicos de producto | Los atributos por rubro se validan contra PlantillaRubro y AtributoConfig, no son JSON libre |
Índices GIN sobre Producto.especificaciones (JSONB) para búsquedas eficientes |
| Aislamiento de tenants | Cada empresa opera en su propio esquema PostgreSQL (django-tenants) |
SET search_path TO tenant_id en cada request. Nunca queries globales sin scope |
| Resiliencia offline del POS | El catálogo esencial se cachea en IndexedDB. Las ventas offline se encolan y sincronizan al recuperar la conexión | Estado PENDIENTE_SYNC en Venta. Celery para sincronización asíncrona |
| Actualización masiva de precios | Variaciones porcentuales aplicadas en el backend, filtrando por proveedor o categoría | Endpoint optimizado con transacción atómica. Sin actualizaciones unitarias en loop |
| SQL optimizado en POS | select_related y prefetch_related obligatorios en endpoints del POS e inventario |
Revisión obligatoria en code review de cualquier query del POS |
7. Glosario del dominio
| Término | Definición |
|---|---|
| Tenant | Empresa cliente con su propio esquema de base de datos aislado |
| Sucursal | Local físico dependiente de un Tenant, dueño de su stock y caja |
| POS | Point of Sale — interfaz de venta de mostrador, táctil y de teclado |
| Rubro | Tipo de comercio (ferretería, librería, almacén). Define los atributos de producto |
| Cierre ciego | Proceso donde el cajero declara efectivo físico sin conocer el saldo esperado |
| Feature Flag | Funcionalidad habilitada o deshabilitada según el plan de suscripción del tenant |
| ARCA | Organismo fiscal argentino (ex-AFIP). Requerido para facturación electrónica (Fase 2) |
| Entidad Comercial | Tabla unificada de Clientes y Proveedores con campo tipo (CLIENTE / PROVEEDOR) |
| PlantillaRubro | Configuración de atributos válidos para un rubro comercial específico |
| AtributoConfig | Definición de un atributo: nombre, tipo (texto/número/lista) y opciones válidas |
| Descuadre | Diferencia entre el efectivo declarado por el cajero y el saldo esperado del sistema |
| PENDIENTE_SYNC | Estado de una venta generada offline, en espera de sincronización con el servidor |
8. Métricas de éxito
El proyecto será considerado exitoso si:
- El POS opera sin bloqueo ante cortes de red de hasta 30 minutos.
- La sincronización de ventas offline se completa sin pérdida de datos al recuperar la conexión.
- El cierre de caja ciego no expone el saldo esperado al cajero bajo ninguna circunstancia.
- Los datos de un tenant son inaccesibles desde el contexto de otro tenant.
- La carga masiva de un catálogo de 10.000 productos se completa de forma asíncrona sin timeout.
9. Restricciones conocidas
- Técnica:
django-tenantsrequiere PostgreSQL obligatoriamente — no hay alternativa de motor de DB. - Legal/Fiscal: La facturación electrónica (ARCA/AFIP) está fuera del MVP — solo se muestra el módulo deshabilitado.
- Presupuestaria: MVP sin integraciones externas de pago ni pasarelas de cobro.
- Temporal: Ninguna feature de Fase 2 o Fase 3 puede iniciarse antes de completar el MVP de Fase 1.
10. Criterios de aceptación del MVP
- Wizard de onboarding completo y funcional para nuevos tenants.
- POS operativo con resiliencia offline demostrable (modo avión + venta + sincronización).
- Cierre de caja ciego: el descuadre es invisible para el cajero y visible para el administrador.
- Importador masivo de productos desde Excel/CSV procesado de forma asíncrona.
- Feature flags bloqueando funcionalidades avanzadas en el backend para planes básicos.
- Aislamiento de datos verificado: ningún usuario puede acceder a datos de otro tenant.