# Round robin

Los dos carriles de rotación —WaTel y formulario—, el par consultar/confirmar y cómo se resuelve a qué asesor va un prospecto.

La **rotación** decide qué asesor atiende. Cada campaña lleva **dos carriles
independientes**, cada uno con su propio cursor.

| Carril                         | Qué reparte                            |
| ------------------------------ | -------------------------------------- |
| **WaTel** (WhatsApp y llamada) | Los clics en los botones de contacto.  |
| **Formulario**                 | Los envíos del formulario de contacto. |

:::caution
Son **hermanos**, no uno principal y otro derivado: **un prospecto nunca gasta un turno
de WaTel, ni al revés**. Por eso el formulario funciona con WaTel apagado.

Un clic de WaTel gasta turno pero **no genera un prospecto**, y por eso su carril se
cuenta aparte en los reportes.
:::

## Consultar y confirmar

Cada carril tiene su par:

- **`peek`** — contesta quién sigue **sin gastar el turno**. Es de solo lectura, así que
  se puede llamar en cada render sin desordenar la rotación.
- **`commit`** — toma el turno: asigna y **avanza el cursor**.

El cursor guarda el **último** puesto usado, así que el turno vivo es siempre
`cursor + 1`. Los dos calculan ese mismo puesto: por eso devuelven a la misma persona, y
la diferencia es que uno no escribe nada.

Ese par es lo que permite que una página **muestre el asesor que va a atender** antes de
que la persona termine de enviar el formulario, sin gastar el turno si al final no lo
envía.

## A quién va un prospecto

Por orden de prioridad:

1. **`sale_agent_id`** — el visitante llegó desde el perfil público de un asesor. Se le
   asigna directo y **no avanza ningún cursor**: es una referencia, no un turno.
2. **`lead_form_agent_id`** — el que la página ya mostró, tomado de `peekLeadForm()`.
   Este **sí** gasta el turno, que es lo que hace que quien aparece en pantalla sea quien
   recibe el prospecto.
3. **Ninguno de los dos** — la rotación decide en el momento del envío.

Si el asesor reservado salió de la rotación entre el `peek` y el envío, el paso 2 cae
solo al paso 3.

## Rutas

| Método del SDK           | Ruta                                                                   |
| ------------------------ | ---------------------------------------------------------------------- |
| `peek()`                 | `GET /api/v1/campaigns/{id}/rotation?key=`                             |
| `peekLeadForm()`         | `GET /api/v1/campaigns/{id}/rotation?lane=lead-form&key=`              |
| `attachCommitHandlers()` | `POST /api/v1/campaigns/{id}/rotation?type=whatsapp\|tel&key=&source=` |
| `submit()`               | `POST /api/v1/campaigns/{id}/leads`                                    |

## Una rotación sin participantes activos

Consultar el turno (`peek()`, `peekLeadForm()` o el clic de WaTel) responde `404` con
`No active agents` cuando nadie de la rotación está activo: no hay asesor que mostrar.

Enviar el formulario (`submit()`) **no** falla por eso: el prospecto se guarda sin
asesor en el almacén de prospectos y la respuesta es un `200` con `assigned_to: null` y
`vaulted: true`. Trátalo como un envío correcto — no le muestres un error al visitante ni
el nombre de un asesor.

El barrido diario de desactivación **nunca** apaga al dueño de una campaña propia.

---

Índice completo del centro de ayuda: https://help.linkerestate.com/llms.txt