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 incluyecamelloId.REQUEST: el cliente pidió el servicio sin elegir camello (por ejemplo desde/trabajos/nuevo); no haycamelloIdy el admin asigna uno después.
Ciclo de vida
PENDIENTE, EN_PROGRESO, COMPLETADO y CANCELADO. En texto:
- El cliente crea el Job (
POST /api/jobs). - El admin asigna un camello a un Job
PENDIENTEsin camello (POST /api/admin/jobs/:id/assign). - El camello acepta (
POST /api/jobs/:id/accept): pasa dePENDIENTEaEN_PROGRESO. O rechaza (POST /api/jobs/:id/reject): se le quita elcamelloIdy el Job vuelve a quedar sin asignar. complete(POST /api/jobs/:id/complete) solo es válido desdeEN_PROGRESO.cancel(POST /api/jobs/:id/cancel) es válido mientras el Job no esté yaCOMPLETADO.
Quién puede cada transición
Restricciones de asignación
POST /api/admin/jobs/:id/assign exige que:
- el Job esté
PENDIENTEy sincamelloIdtodavía; - el camello esté
ACTIVO; - el camello tenga
userId(esté vinculado a una cuenta de usuario, no sea solo una ficha del catálogo).
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.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.
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.