> ## Documentation Index
> Fetch the complete documentation index at: https://wiki.vivla.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Permisos

> Qué permisos de Auth0 existen en el Panel, qué desbloquea cada uno y cómo se comprueban en el código

# Permisos

El acceso a cada módulo del Panel depende de los **permisos** de tu usuario en Auth0. Hay un permiso de lectura y otro de edición por módulo, más un permiso comodín de acceso total.

El panel no asigna permisos: solo los lee. Viajan en el claim `permissions` del access token que devuelve Auth0 al hacer login. Si necesitas más acceso, pídelo a quien administre Auth0.

## Permisos disponibles

| Constante | Valor en Auth0 | Qué te permite |
| - | - | - |
| `READ_KEYS` | `read:exchanges` | Ver **Sistema de llaves** (`/`) |
| `WRITE_KEYS` | `edit:exchanges` | Asignar llaves y editar la valoración |
| `READ_HOMES` | `read:homes` | Ver **Propiedades** y la ficha de cada casa |
| `WRITE_HOMES` | `edit:homes` | Crear casas, editar su ficha y generar el documento de check-in |
| `READ_BOOKINGS` | `read:bookings` | Ver **Reservas** y su detalle |
| `WRITE_BOOKINGS` | `edit:bookings` | Crear reservas, editarlas y cambiar sus flags |
| `READ_USERS` | `read:users` | Ver **Usuarios** y su detalle |
| `WRITE_USERS` | `edit:users` | Crear, editar y borrar usuarios, y editar huéspedes de una estancia |
| `READ_CALENDAR_MANAGER` | `read:calendar-manager` | Ver **Calendarios** |
| `WRITE_CALENDAR_MANAGER` | `edit:calendar-manager` | Editar los días del calendario de una casa |
| `FULL_ACCESS` | `*` | Todo lo anterior. Salta cualquier comprobación |

<Note>
  El valor de llaves es `exchanges`, no `keys`. Es el nombre que usa la API para el intercambio de llaves.
</Note>

<Warning>
  **Calendarios usa nombres distintos en el panel y en la API.** El panel muestra la sección con `read:calendar-manager` y deja editar con `edit:calendar-manager`. En cambio, los endpoints `/v2/admin/calendars` de `vivla-api` exigen `read:calendars` y `edit:calendars`. Para que Calendarios funcione, tu usuario necesita las dos parejas de permisos, o `*`. Con solo `read:calendar-manager` ves la sección, pero la API rechaza las llamadas.
</Warning>

## Qué desbloquea cada permiso de edición

Los permisos de lectura protegen las rutas y el menú. Los de edición, además, muestran u ocultan botones y controles dentro de las pantallas.

| Permiso | Rutas | Controles en pantalla |
| - | - | - |
| `edit:exchanges` | — | Sección de asignación de llaves en `/`, edición en la tabla de valoración |
| `edit:homes` | `/homes/create`, `/homes/:id/checkin-doc` | Botón de alta en el listado, edición de secciones en la ficha y en la vista previa, edición del documento de planificación desde una reserva |
| `edit:bookings` | `/bookings/create` | Botón de alta en el listado, edición en el detalle de la reserva, selector de flags en la tabla |
| `edit:users` | `/users/create`, `/users/:id/edit` | Botón de alta en el listado, acciones del detalle de usuario, activar o desactivar el calendario de una casa del usuario, edición de huéspedes en una estancia |
| `edit:calendar-manager` | — | Clic en los días del Calendar Manager para editarlos |

<Warning>
  Ocultar un botón no es seguridad. El panel oculta lo que no puedes hacer para que no lo intentes, pero quien valida de verdad cada operación es `vivla-api` con el mismo token.
</Warning>

## Cómo se resuelve el acceso

```
Login → Auth0 devuelve el access token
          └─ claim "permissions": ["read:homes", "edit:homes", …]
                └─ useAuth().permissions
                      ├─ Sidebar: filterByPermission(navigableRoutes)
                      ├─ Router: <PermissionGuard requiredPermission=…>
                      └─ Pantallas: useHasPermission(PERMISSIONS.WRITE_…)
```

* **Menú lateral**: solo aparecen las secciones cuyo permiso de lectura tienes (`filterByPermission` sobre `navigableRoutes`).
* **Rutas**: cada ruta va dentro de un `PermissionGuard`. Si no tienes el permiso, `PermissionBasedRedirect` te manda a la primera sección accesible del menú. Si no tienes ninguna, vas a `/unauthorized`.
* **Controles**: los componentes usan `useHasPermission` o envuelven el control en `<PermissionGuard>` sin fallback, así que simplemente no se pintan.

Un `requiredPermission` puede ser un permiso o una lista. Con una lista basta con tener **uno** de ellos (lógica OR). Para exigir todos a la vez existe `useHasAllPermissions` (lógica AND). En ambos casos `*` da acceso.

## Cambios de permisos

El panel recalcula tus permisos cada vez que cambia el token. Renueva el token al menos cada 10 minutos, así que un cambio en Auth0 aparece en el siguiente refresh.

<Tip>
  Si te acaban de dar un permiso y no ves la sección, cierra sesión desde el menú de la cabecera y vuelve a entrar. El nuevo token ya trae el permiso.
</Tip>

## Código

| Pieza | Dónde |
| - | - |
| Constantes de permisos | `src/features/auth/constants/index.ts` |
| Lectura del claim del JWT | `src/features/auth/utils/jwtUtils.ts` (`extractPermissions`) |
| Lógica OR / AND y filtrado | `src/features/auth/utils/permissionUtils.ts` |
| Hooks | `src/features/auth/hooks/usePermissions.ts` (`useHasPermission`, `useHasAllPermissions`) |
| Guard de componentes y rutas | `src/features/auth/components/PermissionGuard/` |
| Redirección sin permiso | `src/router/PermissionBasedRedirect.tsx` |
| Menú y permiso de cada sección | `src/config/routes.ts` |
