> ## 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.

# Trabajos (Jobs)

> Ciclo de vida de un trabajo, de la solicitud al cierre.

Un `Job` es la unidad de trabajo entre un cliente y un camello: se crea, se asigna, se acepta o se rechaza, y se cierra por finalización o cancelación.

## Origen: `EXPLORE` vs `REQUEST`

Un Job nace de dos maneras distintas, y el campo `source` registra cuál:

* **`EXPLORE`**: el cliente eligió un camello concreto en el explorador y el body de creación incluye `camelloId`.
* **`REQUEST`**: el cliente pidió el servicio sin elegir camello (por ejemplo desde `/trabajos/nuevo`); no hay `camelloId` y el admin asigna uno después.

## Ciclo de vida

```text theme={null}
creación REQUEST (sin camelloId)  ──► PENDIENTE (sin camello)
creación EXPLORE (con camelloId)  ──► PENDIENTE (con camello)

PENDIENTE (sin camello)
  --[POST /api/admin/jobs/:id/assign, solo ADMIN]--> PENDIENTE (con camello)

PENDIENTE (con camello)
  --[POST /api/jobs/:id/accept, solo el camello]--> EN_PROGRESO
  --[POST /api/jobs/:id/reject, solo el camello]--> PENDIENTE (sin camello)

EN_PROGRESO
  --[POST /api/jobs/:id/complete, cliente dueño o camello asignado]--> COMPLETADO

PENDIENTE | EN_PROGRESO
  --[POST /api/jobs/:id/cancel, cliente dueño o admin]--> CANCELADO
```

Los cuatro estados son `PENDIENTE`, `EN_PROGRESO`, `COMPLETADO` y `CANCELADO`. En texto:

* El cliente crea el Job (`POST /api/jobs`).
* El admin asigna un camello a un Job `PENDIENTE` sin camello (`POST /api/admin/jobs/:id/assign`).
* El camello acepta (`POST /api/jobs/:id/accept`): pasa de `PENDIENTE` a `EN_PROGRESO`. O rechaza (`POST /api/jobs/:id/reject`): se le quita el `camelloId` y el Job vuelve a quedar sin asignar.
* `complete` (`POST /api/jobs/:id/complete`) solo es válido desde `EN_PROGRESO`.
* `cancel` (`POST /api/jobs/:id/cancel`) es válido mientras el Job no esté ya `COMPLETADO`.

## Quién puede cada transición

| Transición               | Quién                                    |
| ------------------------ | ---------------------------------------- |
| Crear (`POST /api/jobs`) | Cliente dueño (rol `CLIENTES` o `ADMIN`) |
| Asignar camello          | Solo `ADMIN`                             |
| Aceptar / rechazar       | Solo el camello del Job                  |
| Completar                | Cliente dueño o camello asignado         |
| Cancelar                 | Cliente dueño o admin                    |

<Warning>
  El rol `CAMELLOS` no puede crear Jobs: `POST /api/jobs` responde `403` para ese rol. Un camello participa en el ciclo solo a partir de la asignación.
</Warning>

## Restricciones de asignación

`POST /api/admin/jobs/:id/assign` exige que:

* el Job esté `PENDIENTE` y sin `camelloId` todavía;
* el camello esté `ACTIVO`;
* el camello tenga `userId` (esté vinculado a una cuenta de usuario, no sea solo una ficha del catálogo).

<Note>
  El endpoint de asignación **no comprueba que el camello ofrezca el `serviceId` del Job**: ese filtro solo aplica al pool de `GET /api/admin/jobs/:id/candidates`, así que "mismo servicio" es una convención de la UI del admin (que asigna desde ese pool), no una garantía que imponga `/assign`.
</Note>

## Visibilidad de `GET /api/jobs`

La lista de trabajos depende del rol de la sesión: el cliente ve los que creó, el camello los que tiene asignados a su perfil, y el admin los ve todos.

<Note>
  Un Job ajeno responde **404**, no 403, tanto en `GET /api/jobs/:id` como en las acciones sobre un Job concreto. Es intencional: no se revela que el recurso existe a quien no tiene visibilidad sobre él.
</Note>

## Coordinación por WhatsApp

Tras la aceptación, WhatsApp queda como canal de coordinación secundaria entre cliente y camello; no reemplaza el estado del Job ni sus transiciones.

## Roles y permisos

La matriz completa de qué rol puede llamar a cada endpoint —incluyendo los de Jobs— vive en [Autenticación y roles](/docs/handbook/arquitectura/auth-y-roles).
