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

# Autenticación y roles

> NextAuth, los tres roles y la matriz de permisos.

## NextAuth

`src/auth.ts` exporta `authOptions`: NextAuth v4, estrategia de sesión JWT,
adapter de Prisma. El provider de Google solo se registra si
`AUTH_GOOGLE_ID`/`AUTH_GOOGLE_SECRET` están presentes en el entorno.

El rol del usuario viaja en el JWT y se refleja en `session.user.role`; las
ampliaciones de tipo de NextAuth (para que `role` exista en `Session` y en
`JWT`) están en `src/types/next-auth.d.ts`. En servidor, la sesión se
resuelve con `getServerSession(authOptions)`.

## Roles

CamellApp tiene tres roles:

* `ADMIN`: administra usuarios, servicios, camellos y asigna trabajos.
* `CAMELLOS`: el prestador de servicios.
* `CLIENTES`: el usuario final; es el rol por defecto al registrarse.

## Login con Google

El botón oficial de Google Identity Services (GIS) y el One Tap (con acceso
automático) envían un JWT a NextAuth mediante un provider de credenciales
dedicado. El servidor verifica ese token con `AUTH_GOOGLE_ID` y:

* crea un usuario `CLIENTES` si el email no existe todavía, o
* enlaza la cuenta de Google a un usuario existente si ya hay uno con ese
  correo.

Como respaldo existe el flujo OAuth clásico por redirección. Al cerrar
sesión se llama `google.accounts.id.disableAutoSelect()` para evitar que el
One Tap vuelva a iniciar sesión automáticamente en el siguiente visitante.

## Matriz de permisos

<Note>
  `SI` indica acceso permitido; `NO`, acceso denegado. El asterisco (`*`)
  se explica en la nota al pie de la tabla.
</Note>

| Endpoint                             | ADMIN | CAMELLOS | CLIENTES | Publico      |
| ------------------------------------ | ----- | -------- | -------- | ------------ |
| `POST /api/register`                 | SI    | SI       | SI       | SI           |
| `POST /api/register/camello`         | SI    | SI       | SI       | SI           |
| `GET /api/auth/signin`               | SI    | SI       | SI       | SI           |
| `GET /api/auth/session`              | SI    | SI       | SI       | SI           |
| `GET /api/camellos`                  | SI    | SI       | SI       | SI           |
| `GET /api/camellos/meta`             | SI    | SI       | SI       | SI           |
| `GET /api/categories`                | SI    | SI       | SI       | SI           |
| `POST /api/search/interpret`         | SI    | SI       | SI       | SI           |
| `POST /api/camellos/:id/reviews`     | NO    | NO       | SI       | NO           |
| `GET /api/admin/users`               | SI    | NO       | NO       | NO           |
| `PATCH /api/admin/users/:id/role`    | SI    | NO       | NO       | NO           |
| `GET /api/notifications`             | SI    | SI       | SI       | NO           |
| `GET /api/admin/notifications`       | SI    | NO       | NO       | NO           |
| `GET /api/jobs`                      | SI    | SI       | SI       | NO           |
| `POST /api/jobs`                     | SI    | NO       | SI       | NO           |
| `GET /api/jobs/:id`                  | SI    | SI\*     | SI\*     | NO           |
| `POST /api/jobs/:id/accept`          | NO†   | SI\*     | NO       | NO           |
| `POST /api/jobs/:id/reject`          | NO†   | SI\*     | NO       | NO           |
| `POST /api/jobs/:id/complete`        | NO†   | SI\*     | SI\*     | NO           |
| `POST /api/jobs/:id/cancel`          | SI    | NO       | SI\*     | NO           |
| `POST /api/admin/jobs/:id/assign`    | SI    | NO       | NO       | NO           |
| `GET /api/admin/jobs/:id/candidates` | SI    | NO       | NO       | NO           |
| `GET /api/health`                    | —     | —        | —        | SI (publico) |
| `GET /api/admin/health`              | SI    | NO       | NO       | NO           |

\* Según visibilidad del Job (dueño, camello asignado o admin).

† No es por el rol `ADMIN`: aceptar, rechazar y completar comprueban
identidad respecto al Job (ser el camello asignado, o además el cliente
dueño en el caso de completar) — no el rol de sesión. Un `ADMIN` que no sea
ninguna de esas partes recibe `404`. Si ese mismo usuario `ADMIN` también
tiene esa identidad, actúa por ella, no por su rol: el camello asignado
puede aceptar, rechazar o completar; el dueño (cliente) puede completar.
Es distinto de `cancel`, que
sí tiene un bypass explícito por rol: ahí `ADMIN` puede siempre, sin
depender de ser dueño ni camello.
