Roles y permisos
Los tres roles
Sección titulada «Los tres roles»Estado: ✅ Confirmada — definidos por Aquazaku.
El sistema tiene exactamente tres roles. No hay más, y agregar uno nuevo es una decisión de negocio, no una comodidad de implementación.
| Rol | Quién es | Dónde opera | Cómo vende |
|---|---|---|---|
admin |
Dueño / administración | Web | — (supervisa) |
seller |
Vendedor de ruta | Mobile | Va al cliente |
pos |
Punto de venta fijo | Web / terminal | El cliente viene |
La diferencia entre seller y pos no es de jerarquía: es de contexto de
operación. Uno vende en la calle, sin señal, contra la carga de su vehículo.
El otro vende en el mostrador, con conexión, contra el stock de bodega.
Esa distinción atraviesa todo el sistema —stock por ubicación, modo offline, rendición— y por eso son dos roles y no uno con un flag.
El error que casi todos cometen
Sección titulada «El error que casi todos cometen»Un permiso tiene dos ejes, no uno. La mayoría de los sistemas modela solo el primero y después parchea el segundo a mano por toda la aplicación.
| Eje | Pregunta | Ejemplo |
|---|---|---|
| Acción | ¿Qué puede hacer? | ventas:ver |
| Alcance | ¿Sobre qué datos? | Solo las suyas |
Un seller “puede ver ventas” — pero solo las suyas. Eso no es un flag
booleano: es un filtro de datos. Si tratás el alcance como un if suelto en cada
endpoint, tarde o temprano hay un endpoint donde te olvidaste, y un vendedor ve
la facturación completa de la empresa.
Alcances definidos
Sección titulada «Alcances definidos»| Alcance | Significa |
|---|---|
todo |
Todos los registros del sistema |
ruta |
Solo los de la ruta que tiene abierta |
propio |
Solo los registros que él mismo creó |
| — | Sin acceso |
Nomenclatura de permisos
Sección titulada «Nomenclatura de permisos»ventas:anular │ └── acción └───────── recursoMinúsculas, sin acentos, recurso:accion. El mismo string se usa en el backend,
en el frontend y en esta documentación. Una sola fuente de verdad.
Matriz de permisos
Sección titulada «Matriz de permisos»Leyenda: ✅ alcance todo · 🟡 alcance limitado (se indica) · ❌ sin acceso
Ventas y cobros
Sección titulada «Ventas y cobros»| Permiso | admin |
seller |
pos |
|---|---|---|---|
ventas:ver |
✅ | 🟡 propio |
🟡 propio |
ventas:crear |
✅ | 🟡 ruta |
✅ |
ventas:anular ⚠️ |
✅ | ❌ | ❌ |
cobros:ver |
✅ | 🟡 propio |
🟡 propio |
cobros:registrar |
✅ | 🟡 ruta |
✅ |
Clientes
Sección titulada «Clientes»| Permiso | admin |
seller |
pos |
|---|---|---|---|
clientes:ver |
✅ | 🟡 ruta |
✅ |
clientes:crear |
✅ | 🟡 ruta |
✅ |
clientes:verificar_documento |
✅ | 🟡 ruta |
✅ |
clientes:editar |
✅ | ❌ | ❌ |
clientes:habilitar_credito |
✅ | ❌ | ❌ |
Stock de producto
Sección titulada «Stock de producto»| Permiso | admin |
seller |
pos |
|---|---|---|---|
stock:ver |
✅ | 🟡 ruta |
🟡 BODEGA |
stock:cargar_ruta ⚠️ |
✅ | ❌ | ❌ |
stock:ajustar |
✅ | ❌ | ❌ |
insumos:ver |
✅ | ❌ | ❌ |
insumos:ajustar |
✅ | ❌ | ❌ |
Botellones — por cantidad
Sección titulada «Botellones — por cantidad»| Permiso | admin |
seller |
pos |
|---|---|---|---|
botellones:ver |
✅ | 🟡 ruta |
🟡 BODEGA |
botellones:entregar |
✅ | 🟡 ruta |
✅ |
botellones:recibir_retorno |
✅ | 🟡 ruta |
✅ |
botellones:registrar |
✅ | ❌ | ❌ |
botellones:descartar |
✅ | ❌ | ❌ |
Bases — por unidad identificada
Sección titulada «Bases — por unidad identificada»| Permiso | admin |
seller |
pos |
|---|---|---|---|
bases:ver |
✅ | 🟡 ruta |
✅ |
bases:prestar ⚠️ |
✅ | 🟡 ruta |
✅ |
bases:retirar |
✅ | 🟡 ruta |
✅ |
bases:registrar |
✅ | ❌ | ❌ |
bases:descartar |
✅ | ❌ | ❌ |
Producción y agua
Sección titulada «Producción y agua»| Permiso | admin |
seller |
pos |
|---|---|---|---|
produccion:ver |
✅ | ❌ | ❌ |
produccion:registrar_cierre ⚠️ |
✅ | ❌ | ❌ |
tanques:ver |
✅ | ❌ | ❌ |
tanques:registrar_reposicion |
✅ | ❌ | ❌ |
tanques:ajustar |
✅ | ❌ | ❌ |
configuracion:equivalencias |
✅ | ❌ | ❌ |
Proveedores y compras
Sección titulada «Proveedores y compras»| Permiso | admin |
seller |
pos |
|---|---|---|---|
proveedores:ver |
✅ | ❌ | ❌ |
proveedores:crear |
✅ | ❌ | ❌ |
compras:crear |
✅ | ❌ | ❌ |
compras:recibir ⚠️ |
✅ | ❌ | ❌ |
| Permiso | admin |
seller |
pos |
|---|---|---|---|
rutas:ver |
✅ | 🟡 propio |
❌ |
rutas:abrir ⚠️ |
✅ | ❌ | ❌ |
rutas:rendir |
✅ | 🟡 propio |
❌ |
rutas:cerrar_con_faltante |
✅ | ❌ | ❌ |
Administración
Sección titulada «Administración»| Permiso | admin |
seller |
pos |
|---|---|---|---|
productos:ver |
✅ | ✅ | ✅ |
productos:editar_precios |
✅ | ❌ | ❌ |
usuarios:* |
✅ | ❌ | ❌ |
reportes:operativos |
✅ | ❌ | ❌ |
reportes:financieros |
✅ | ❌ | ❌ |
configuracion:* |
✅ | ❌ | ❌ |
La consecuencia de tener solo tres roles
Sección titulada «La consecuencia de tener solo tres roles»Con este modelo, admin concentra todas las funciones de control: ajusta
stock, anula ventas, cambia precios, descarta botellones y bases, y administra
usuarios.
Eso es perfectamente razonable en una operación chica. Pero hay que decirlo en voz alta, porque tiene una consecuencia directa:
Las dos preguntas que hay que hacerle a Aquazaku:
- ¿Cuántas personas van a tener rol
admin? Si son varias, ¿está bien que todas puedan anular ventas y ajustar stock? - ¿Hace falta un
adminde solo lectura, para un contador externo o para el dueño que quiere mirar sin poder romper nada?
Reglas de acceso
Sección titulada «Reglas de acceso»RN-ACC-01 — Un usuario tiene exactamente un rol
Sección titulada «RN-ACC-01 — Un usuario tiene exactamente un rol»Estado: 🟡 Supuesto
No hay acumulación de roles: un usuario es admin, seller o pos.
Por qué: la combinación de roles multiplica los casos a probar y hace que nadie pueda responder “¿qué ve exactamente esta persona?”.
RN-ACC-02 — La UI oculta, la API prohíbe
Sección titulada «RN-ACC-02 — La UI oculta, la API prohíbe»Estado: ✅ Confirmada (decisión técnica)
El permiso se valida siempre en el servidor. Que el frontend no muestre el botón es comodidad para el usuario, no seguridad.
Por qué: ocultar un botón no impide llamar al endpoint. Toda validación que viva únicamente en el cliente ya está rota, solo que todavía no lo sabés.
RN-ACC-03 — El alcance se aplica en la capa de datos
Sección titulada «RN-ACC-03 — El alcance se aplica en la capa de datos»Estado: ✅ Confirmada (decisión técnica)
El filtro por alcance (propio, ruta, todo) se aplica en un único lugar del
acceso a datos, no repetido endpoint por endpoint.
Por qué: repetir el filtro garantiza que algún día falte en uno. Y ese uno va a ser el de reportes.
RN-ACC-04 — Toda acción sensible queda auditada
Sección titulada «RN-ACC-04 — Toda acción sensible queda auditada»Estado: 🟡 Supuesto
Anulaciones, ajustes de stock, bajas de botellones y bases, préstamo y retiro de bases, cambios de precio, habilitación de crédito y cierres con faltante registran quién, cuándo y por qué.
Por qué: con admin concentrando todo el poder de corrección, la auditoría
es el único mecanismo de control que queda. Todas las reglas de inmutabilidad
del dominio (RN-VEN-02, RN-RUT-04)
dependen de que exista.
RN-ACC-05 — Un usuario no se borra, se desactiva
Sección titulada «RN-ACC-05 — Un usuario no se borra, se desactiva»Estado: 🟡 Supuesto
Un usuario con historial se desactiva y pierde el acceso, pero sus registros mantienen la referencia a él.
Por qué: borrar al usuario deja huérfanas todas las ventas que registró.
Preguntas abiertas
Sección titulada «Preguntas abiertas»- ¿
pospuede anular una venta del día, o siempre tiene que pedírselo aadmin? Es la fricción operativa más probable del modelo. - ¿
posvende contra el stock de bodega directamente, o el punto de venta tiene su propia ubicación de stock? - ¿
sellerpuede registrar clientes nuevos en la calle, o los crea la oficina? - ¿Quién carga la ruta del
sellerpor la mañana — unadminsiempre? - ¿Hay más de un punto de venta?