permisos de agenda: selector de acciones por usuario (ver, agendar, editar, eliminar, visitas)
- roles.py: AGENDA_PERMS, AGENDA_PERM_KEYS, WRITE_RANK_MIN, agenda_defaults_for, resolve_agenda_perms, AGENDA_STATUS_PERM, AGENDA_STATE_PERM, _agenda_status_perm - frontend_user.py: campo agenda_perms, _agenda_perms_list(), to_public_dict() expone agenda_perms y agenda_perms_custom - auth.py: require_agenda(perm) decorador + agenda_perm_error() - frontend.py: @require_agenda aplicado a 22 endpoints + branch en update_appointment_status por accion - auth_users_update: whitelist acepta agenda_perms - Odoo upgrade: columna skeen_frontend_user.agenda_perms - Frontend: types AgendaPerm, AGENDA_PERM_ITEMS, canAgenda() en auth.tsx - UsuariosPanel: checkboxes de permisos de agenda en modal de permisos - Agenda.tsx: gates por permiso en crear/editar/eliminar/visitas/dragdrop/bloqueos - EstadoChecklist/BloqueosModal/ListaEspera: hide actions without permission Verificacion API: 18/18 tests OK (admin hereda, recorte=403, lect=403, restore=null)
This commit is contained in:
@@ -44,6 +44,57 @@ ROLE_RANKS = {
|
||||
|
||||
MENU_ROLES_KEY = 'skeen.menu_roles'
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Permisos de ACCIÓN dentro de la Agenda (selector por usuario).
|
||||
#
|
||||
# No son visibilidad de menú: deciden qué se puede HACER una vez dentro.
|
||||
# Claves estables (se guardan como JSON en skeen.frontend.user.agenda_perms).
|
||||
# ------------------------------------------------------------------
|
||||
AGENDA_PERMS = [
|
||||
('ver', 'Consultar agenda'),
|
||||
('agendar', 'Agendar cita'),
|
||||
('editar', 'Editar citas'),
|
||||
('eliminar', 'Eliminar citas'),
|
||||
('visitas', 'Generar visitas'),
|
||||
]
|
||||
AGENDA_PERM_KEYS = tuple(k for k, _ in AGENDA_PERMS)
|
||||
|
||||
# Acciones que requieren rango de escritura (recepción para arriba): quien no
|
||||
# tiene lista propia configurada hereda esto, que es exactamente lo que ya
|
||||
# permitía @require_role('recepcion'). Así el selector puede QUITAR sin
|
||||
# configurar nada y no cambia el comportamiento actual de nadie.
|
||||
WRITE_RANK_MIN = 'recepcion'
|
||||
|
||||
# Roles sin rango propio en ROLE_RANKS no existen; el default se resuelve por
|
||||
# rango, no por nombre, para no duplicar la lista de roles.
|
||||
|
||||
|
||||
def agenda_defaults_for(user):
|
||||
"""Permisos de agenda por defecto de un usuario (sin lista propia)."""
|
||||
ver = ['ver']
|
||||
if user is None:
|
||||
return list(ver)
|
||||
if user.role == 'admin':
|
||||
return list(AGENDA_PERM_KEYS)
|
||||
if user.role_rank() >= ROLE_RANKS.get(WRITE_RANK_MIN, 50):
|
||||
return list(AGENDA_PERM_KEYS)
|
||||
return list(ver)
|
||||
|
||||
|
||||
def resolve_agenda_perms(user):
|
||||
"""Permisos de agenda vigentes: los del usuario si tiene lista, si no el default.
|
||||
|
||||
'ver' nunca se quita: sin él no hay pantalla que mostrar y el resto de las
|
||||
acciones carece de sentido. Se fuerza al subir.
|
||||
"""
|
||||
custom = user._agenda_perms_list() if user is not None else None
|
||||
if custom is None:
|
||||
return agenda_defaults_for(user)
|
||||
valid = [k for k in AGENDA_PERM_KEYS if k in custom]
|
||||
if 'ver' not in valid:
|
||||
valid.insert(0, 'ver')
|
||||
return valid
|
||||
|
||||
# Defaults = MENU_ROLES de src/lib/auth.tsx (4 roles originales).
|
||||
# 'gerencia' (gerencia de la clínica) ve toda la
|
||||
# operación EXCEPTO /configuracion (solo admin del sistema), /mis-ventas,
|
||||
|
||||
Reference in New Issue
Block a user