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

# Organizer api

# API de Organizador

Este documento recopila y estandariza la documentación de la API para Organizadores.

## Autenticación

* Bearer Token (Sanctum Personal Access Tokens)
* Scope requerido: `organizer-api`
* Acceso restringido al `organizador_id` del propietario del token

### Supervisor

* Bearer Token (Sanctum Personal Access Tokens)
* Scope requerido: `supervisor-api`
* Acceso a participantes de todos los eventos

## Límite de peticiones

* RateLimiter: `organizer-api`
* Valor por defecto: 60 req/min, configurable por organizador

## Endpoints

### GET /api/v1/organizer/participants

Obtiene participantes de eventos del organizador autenticado.

### GET /api/v1/supervisor/participants

Obtiene participantes de todos los eventos (requiere rol Supervisor o Administrador).

Parámetros (query): iguales a los del organizador.

Paginación por cursor (recomendado para grandes volúmenes):

* `pagination=cursor` habilita cursor pagination.
* `per_page` tamaño de página (recomendado 1000–2000 para 20k+).
* Respuesta incluye `meta.cursor.next_cursor` y `meta.cursor.prev_cursor`.
* Con cursor sólo se permite `order_by=id`.

Ejemplos:

```bash theme={null}
# Obtener todos los participantes
curl -H "Authorization: Bearer <TOKEN_SUPERVISOR>" "https://TU_DOMINIO/api/v1/supervisor/participants?per_page=2000"

# Primera página con cursor (recomendado)
curl -H "Accept: application/json" \
  -H "Authorization: Bearer <TOKEN_SUPERVISOR>" \
  "https://TU_DOMINIO/api/v1/supervisor/participants?pagination=cursor&per_page=2000"

# Siguiente página con cursor
curl -H "Accept: application/json" \
  -H "Authorization: Bearer <TOKEN_SUPERVISOR>" \
  "https://TU_DOMINIO/api/v1/supervisor/participants?pagination=cursor&per_page=2000&cursor=<NEXT_CURSOR>"
```

Parámetros (query):

* `participant_id` (opcional, integer) - Filtrar por ID específico de participante
* `event_id` (opcional, integer) - Filtrar por ID de evento
* `status` (opcional, string) - Filtrar por estado del participante
* `bib` (opcional, string) - Filtrar por número de BIB
* `from` (opcional, Y-m-d) - Fecha de inicio para filtrar por fecha de creación
* `to` (opcional, Y-m-d) - Fecha de fin para filtrar por fecha de creación
* `search` (opcional, string) - Búsqueda en nombre, apellido, email, teléfono, locator, notas
* `order_by` (opcional, string) - Campo de ordenación: id|created\_at|status|bib|evento\_id
* `order_dir` (opcional, string) - Dirección de ordenación: asc|desc
* `per_page` (opcional, integer) - Número de elementos por página (respeta límites de configuración)

Respuesta: colección de `ParticipantResource` con `meta.filters`.

Ejemplos:

```bash theme={null}
# Obtener todos los participantes
curl -H "Authorization: Bearer <TOKEN>" "https://TU_DOMINIO/api/v1/organizer/participants?per_page=50"

# Obtener un participante específico por ID
curl -H "Authorization: Bearer <TOKEN>" "https://TU_DOMINIO/api/v1/organizer/participants?participant_id=123"

# Filtrar por evento específico
curl -H "Authorization: Bearer <TOKEN>" "https://TU_DOMINIO/api/v1/organizer/participants?event_id=456"

# Combinar filtros
curl -H "Authorization: Bearer <TOKEN>" "https://TU_DOMINIO/api/v1/organizer/participants?event_id=456&status=active&per_page=20"
```

### GET /api/v1/organizer/events/{event_id}/form

### GET /api/v1/supervisor/events/{event_id}/form

Devuelve la definición completa del formulario de inscripción del evento indicado: todos los campos
configurados con sus nombres, tipos, obligatoriedad, visibilidad, opciones y subpreguntas condicionales.

Mismas reglas de seguridad que el endpoint de participantes:

* Bearer Token (Sanctum) con scope `organizer-api` / `supervisor-api`.
* Organizador o Administrador (organizador), o permiso `supervisor-api-participants` (supervisor).
* Respeta `enabled` de `organizer_api_settings` / `supervisor_api_settings`.
* El evento debe pertenecer al organizador del token; en caso contrario devuelve `404 ORGAPI_404_EVENT_NOT_FOUND`.
* Cada consulta queda registrada en los logs de la API.

Parámetros:

* `event_id` (obligatorio, integer, en la ruta) - Evento cuyo formulario se consulta.

Campos devueltos por cada entrada de `data.form.fields`:

* `position` - Orden del campo dentro del formulario.
* `name` - Nombre interno configurado en el formulario.
* `input_name` - Clave con la que la respuesta del participante viaja en `form_data` / `details`.
* `field_key` - Clave estable del campo cuando el formulario la define.
* `title` / `titles` - Etiqueta mostrada al participante y sus traducciones cuando existen.
* `description`, `type`, `required`, `visible`.
* `is_group_question`, `hide_for_group`, `is_checkout_addon` - Reglas de visibilidad por tipo de tarifa.
* `show_by_date`, `start_date`, `end_date` - Ventana temporal de publicación del campo.
* `conditional_logic`, `rate_visibility`, `category_config` - Configuración avanzada tal cual está guardada.
* `options` - Lista de `{value, label}` para select/radio/checkbox, con las `subquestions` que desbloquea cada opción.
* `subquestions` - Subpreguntas anidadas del campo.

Ejemplos:

```bash theme={null}
# Formulario de un evento (organizador)
curl -H "Accept: application/json" \
  -H "Authorization: Bearer <TOKEN>" \
  "https://TU_DOMINIO/api/v1/organizer/events/456/form"

# Formulario de un evento (supervisor)
curl -H "Accept: application/json" \
  -H "Authorization: Bearer <TOKEN_SUPERVISOR>" \
  "https://TU_DOMINIO/api/v1/supervisor/events/456/form"
```

Respuesta:

```json theme={null}
{
  "data": {
    "event": { "id": 456, "name": "IRONMAN", "organizer_id": 1 },
    "form": {
      "title": "Registration Form",
      "description": "Complete all required fields to register",
      "fields_count": 2,
      "fields": [
        {
          "position": 1,
          "name": "name",
          "input_name": "name",
          "title": "Nombres",
          "type": "text",
          "required": true,
          "visible": true,
          "options": [],
          "subquestions": []
        },
        {
          "position": 2,
          "name": "gender",
          "input_name": "gender",
          "title": "Género",
          "type": "select",
          "required": true,
          "visible": true,
          "options": [
            { "value": "hombre", "label": "Hombre" },
            { "value": "mujer", "label": "Mujer" }
          ],
          "subquestions": []
        }
      ]
    }
  },
  "meta": {
    "organizer_id": 1,
    "filters": { "event_id": 456 }
  }
}
```

## Configuración por organizador

Tabla: `organizer_api_settings`

* `enabled`
* `rate_limit_per_minute`
* `default_page_size`
* `max_page_size`
* `ip_allowlist`

## Roadmap

* Nuevos endpoints bajo `/api/v1/organizer/*`
* Versionado por encabezado o prefijo v2
* OpenAPI/Swagger auto-generado

### POST /api/v1/organizer/participants

Actualiza participantes por id (masivo por lotes). Sólo se permiten campos no autogenerados.

### POST /api/v1/supervisor/participants

Actualiza participantes por id (masivo por lotes). Sólo se permiten campos no autogenerados. Requiere rol Supervisor o Administrador y scope `supervisor-api`.

Carga masiva (mejores prácticas):

* Se aceptan lotes grandes (ej. 20k). Si el array `updates` supera 1000 elementos, el servidor lo divide en chunks y procesa en background con la cola.
* Respuesta inmediata con `202 Accepted` y meta de chunks. Consulta logs para ver el progreso.
* Tamaños ≤1000 se procesan de forma síncrona con respuesta 200.

Body (JSON) y respuesta: iguales al endpoint de organizador.

Ejemplo cURL:

```bash theme={null}
curl -X POST \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <TOKEN_SUPERVISOR>" \
  -d '{
    "updates": [
      {"id": 123, "bib": "A-102"},
      {"id": 124, "observations": "Nota"}
    ]
  }' \
  "https://TU_DOMINIO/api/v1/supervisor/participants"
```

Ejemplo masivo (recibirá 202 Accepted):

```bash theme={null}
curl -X POST \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <TOKEN_SUPERVISOR>" \
  -d @payload_20000.json \
  "https://TU_DOMINIO/api/v1/supervisor/participants"
```

* Autorización: Bearer Token (Sanctum) con scope `organizer-api`.
* Roles: Organizador o Administrador.
* Seguridad adicional: Cabecera opcional `X-Organizer-Id` para reforzar pertenencia.
* Validaciones: Solo JSON; rechazo de contenido sospechoso (script, javascript:, on\* handlers, data:text/html) en objetos `competition_results` y `details`.

Campos permitidos por participante:

* `bib` (String, opcional) - Número de BIB del participante
* `observations` (String, opcional) - Observaciones generales sobre el participante
* `participation_notes` (String, opcional) - Notas específicas de participación
* `competition_results` (JSON Object, opcional) - Resultados de competición en formato JSON
* `details` (JSON Object, opcional) - Detalles adicionales del participante en formato JSON

Campos prohibidos (se rechazan): `evento_id`, `locator`, `order_id`, `user_id`, `created_by`, `updated_by`, `deleted_by`, `status`.

Body (JSON):

```json theme={null}
{
  "updates": [
    {
      "id": 123,
      "bib": "A-102",
      "observations": "Llegó con retraso de 2m",
      "participation_notes": "Usa chip nuevo",
      "competition_results": {
        "tiempo_chip": "00:45:12",
        "posicion_final": 12
      },
      "details": {
        "talla": "M"
      }
    },
    { "id": 124, "observations": "Nota actualizada" }
  ]
}
```

Respuesta 200:

```json theme={null}
{
  "data": [
    { "id": 123, "updated": true },
    { "id": 124, "updated": false, "message": "No se enviaron campos actualizables" }
  ],
  "errors": [
    { "id": 999, "code": "ORGAPI_404_NOT_FOUND", "message": "Participante no encontrado" }
  ],
  "meta": { "updated_count": 1, "failed_count": 1 }
}
```

Ejemplo cURL:

```bash theme={null}
curl -X POST \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <TOKEN>" \
  -H "X-Organizer-Id: <ID_ORGANIZADOR>" \
  -d '{
    "updates": [
      {"id": 123, "bib": "A-102"},
      {"id": 124, "observations": "Nota"}
    ]
  }' \
  "https://TU_DOMINIO/api/v1/organizer/participants"
```
