Saltar al contenido
Todos los posts
7 de noviembre de 2025·2 min de lectura·Diogo Hudson

Permisos sin el dolor de cabeza de la matriz

Cuatro roles, una matriz, cero código custom por tenant. El modelo de permisos de Quotery mantiene la complejidad en el grupo, no en la fila.

Permisos sin el dolor de cabeza de la matriz

La mayoría de los apps CRUD empieza con 'roles' que terminan hardcodeados por endpoint. Un año después nadie sabe responder '¿quién puede aprobar una devolución?' sin leer el código.

El descenso al caos de permisos sigue un camino predecible. Primero, un simple if user.is_staff en los endpoints más sensibles. Luego algunas clases de permiso personalizadas. Luego overrides por tenant porque 'nuestro cliente más grande tiene una estructura de equipo diferente.' En un año, los permisos están dispersos en views, serializers y condicionales del frontend, y la única forma de saber lo que un usuario puede hacer es iniciar sesión como él y probar.

Cuatro grupos, una matriz Quotery entrega cuatro grupos: admin, manager, commercial, warehouse. La matriz de permisos está documentada en CLAUDE.md — una tabla mostrando quién hace CRUD sobre qué. Cada feature nueva empieza con 'agrega la fila en la matriz, después cablea el check'.

La matriz es deliberadamente plana y deliberadamente pequeña. Admin puede todo. Manager puede todo excepto cambios de configuración a nivel de tenant. Commercial puede crear y gestionar cotizaciones, ver sus propios clientes, y ver disponibilidad de inventario (no ajustarla). Warehouse puede gestionar inventario, postear entregas, procesar devoluciones, y ver datos relacionados con fulfillment. Cuatro filas, tal vez ocho columnas. Si un permiso no cabe en esta matriz, el diseño de la feature probablemente es demasiado complejo.

Visibilidad por fila Los usuarios commercial ven sus propias cotizaciones; admin y manager ven todo el tenant. El service layer impone esto — la view solo pasa request.user adelante.

Esta es la parte sutil. La membresía de grupo controla el acceso grueso (¿puede este usuario cerrar cotizaciones?). El alcance por fila controla el acceso fino (¿cuáles cotizaciones puede cerrar este usuario?). Los usuarios commercial pasan ambos checks: tienen el permiso 'puede cerrar cotización', y su consulta está scopeada a las cotizaciones que poseen. Un usuario de warehouse falla el primer check — nunca llega al segundo. Los dos mecanismos son independientes pero se componen limpiamente.

Por qué no ACL fino Escogimos basado en grupo porque el costo del ACL fino se paga en cada request, para siempre. Un equipo de 20 no tiene 20 roles; tiene 4. La jerarquía es plana por diseño.

El ACL fino (permisos a nivel de usuario sobre recursos individuales) es la respuesta correcta para algunos dominios — plataformas de compartición de documentos, herramientas de gestión de proyectos, cualquier cosa donde el compartir ad-hoc sea una funcionalidad central. Las operaciones de distribución no son ese dominio. Los flujos de trabajo son estructurados, los roles son estables, y las fronteras de permisos se alinean con las fronteras organizacionales. Un modelo basado en grupos mapea limpiamente al negocio real: los vendedores hacen cosas de ventas, los del almacén hacen cosas de almacén, los gerentes supervisan ambos, los admins configuran el sistema. Agregar ACL por usuario a este modelo añadiría complejidad sin añadir capacidad.

Cómo está construida la plataforma de Quotery.

Todos los posts
Textos cortos sobre cotizar, inventario, IA y cómo los distribuidores pequeños despachan mucho volumen sin tanto rodeo.