Skip to content

Otorgar permisos

Los permisos son los pequeños verbos que la plataforma realmente verifica. ¿Puede este usuario registrar una donación? ¿Puede eliminar un miembro? ¿Puede aprobar un informe? Cada verbo tiene una llave como giving.record o members.delete, y la respuesta es sí si alguno de los roles del usuario tiene esa llave activada en role_permissions_v2.

Hay 68 llaves. Vienen con la plataforma — no puedes agregar nuevas, no puedes renombrar las existentes, y no cambian entre iglesias. Lo que controlas es el cableado: qué roles otorgan qué llaves. Ese cableado vive en la matriz de permisos.

Matriz de permisos

Abrir la matriz

Desde Usuarios y Roles, haz clic en la pestaña Roles y Permisos. La matriz aparece debajo de la lista de roles, con una fila por permiso y una columna por rol. El cuadro de filtro en la esquina superior izquierda reduce las filas visibles por recurso, acción, llave o descripción — escribe giving para ver solo las siete llaves de donaciones, o delete para ver cada permiso destructivo en todos los módulos a la vez.

Cómo está organizada la matriz

Los permisos están agrupados por recursomembers, giving, reports, events, etc. Dentro de cada grupo están ordenados por acción (view antes de edit antes de delete). El agrupamiento es puramente visual; bajo el capó cada permiso es una llave plana. La taxonomía completa:

RecursoAcciones que verás
dashboardview
membersview, create, edit, delete, merge
attendanceview, mark
givingview, record, manage, donate
reportsview, view_all, submit, manage, delete, export, approve, unlock
org_unitsview, create, edit, delete, manage
schoolsview, manage
demographicsview
mapview, manage
ministriesview, manage
groupsview, manage
eventsview, create, edit
messagingview, send
notificationsview, send
usersmanage
custom_fieldsview, manage
configmanage
billingmanage
websitemanage, publish, blog, sermons
podcastmanage
workflowsview, manage, execute, enroll
formssubmit, manage, view_submissions
zapierview, manage

Eso es 68 en total. La lista canónica vive en src/shared/lib/access-policy.ts en el frontend y supabase/functions/_shared/access-policy.ts en el backend — ambos archivos se mantienen sincronizados.

Alternar un permiso

Encuentra la fila (el permiso) y la columna (el rol), luego mueve el interruptor. El cambio se escribe en role_permissions_v2 inmediatamente — no hay botón de guardar, no hay paso de confirmación. Los usuarios con ese rol recogen el nuevo comportamiento en su próxima navegación de página o refetch de React Query (típicamente en cuestión de segundos).

El interruptor es simétrico: apagarlo elimina la fila de role_permissions_v2; encenderlo la inserta. Ambas acciones se escriben en el registro de auditoría con el correo del actor y la marca de tiempo, así que siempre puedes reconstruir quién cambió qué.

Combinaciones comunes

Los roles más útiles agrupan algunas llaves juntas. Una referencia para los patrones que vemos más a menudo:

Leer + escribir un recurso

members.view + members.edit — el par más común. Permite a alguien actualizar números de teléfono y direcciones sin poder agregar o eliminar a nadie. Bueno para un miembro del equipo de calidad de datos.

giving.view + giving.record — registrar donaciones y ver historial. La forma clásica de Tesorero. Agrega giving.manage si también crea fondos; déjalo desactivado si quieres un gestor de fondos separado.

attendance.view + attendance.mark — exactamente lo que el voluntario de check-in necesita. Empareja con permisos limitados para limitarlos a un servicio o sede.

Crear + editar pero no eliminar

members.create + members.edit (sin members.delete). Común para líderes de ministerio — pueden agregar visitantes y actualizar registros existentes pero no pueden eliminar a nadie. Las eliminaciones típicamente requieren un admin.

events.create + events.edit (sin delete) — la misma forma para el trabajo de calendario. Permite a un líder de alabanza agregar la serie de ensayos sin poder remover el archivo del año pasado.

Solo lectura en general

Cada llave view con nada más es el rol Viewer. Útil para miembros de junta, auditores y personal en período de prueba. Hay un dashboard.view dedicado para que un Viewer pueda aterrizar en algún lugar que se vea significativo.

Manage vs verbos inferiores

Para algunos recursos, manage es un superset que implica los verbos inferiores. giving.manage incluye la capacidad de registrar y ver en la UI pero los permisos explícitos giving.record y giving.view aún necesitan estar activados para que las edge functions y RLS permitan las operaciones. Siempre otorga los verbos inferiores junto con manage — la matriz no los otorga automáticamente.

config.manage es la única gran excepción: es un solo interruptor que controla cada página de configuración (channels, modules, PWA, configuración de visitantes, registros de datos). No hay llaves separadas de lectura/escritura para esas.

Dónde se ejecuta realmente la verificación

Un permiso no se verifica una sola vez — se verifica en tres lugares, en este orden:

  1. La UI usa usePermissions().has("giving.record") para ocultar botones. Esto es puramente cosmético; una petición de cliente falsificada aún puede llamar al API.
  2. La edge function llama a assertPermission(ctx, "giving.record") desde _shared/caller-context.ts. Si el usuario no tiene la llave, la función devuelve 403 antes de tocar la base de datos.
  3. Row-Level Security en Postgres re-verifica vía el helper SQL has_permission() para la capa final de defensa.

Esta verificación de tres capas significa que un rol mal configurado nunca puede filtrar datos accidentalmente — incluso si la UI se desincroniza de la base de datos, la edge function y RLS rechazarán la petición.

Filtrar la matriz

Para iglesias con muchos roles personalizados, la matriz puede ser ancha. La entrada de filtro la reduce al escribir:

  • giving — solo la sección de donaciones.
  • delete — cada acción destructiva en toda la plataforma.
  • members.merge — encuentra una llave específica.
  • report — también coincide con reports.

El filtro verifica recurso, acción, llave y descripción — el que coincida primero gana.

Siguiente