# API de configuraciones

> Crear, listar, obtener, actualizar y eliminar grupos de configuración y sus valores anidados en la API para integradores.

Los grupos de configuración representan ejes de la matriz de pruebas (por ejemplo "Navegador", "Sistema operativo") y sus valores de configuración anidados son las celdas individuales de ese eje (por ejemplo "Chrome", "Firefox"). Los grupos y los valores son por proyecto, admiten eliminación lógica (soft-delete) y reciben ULIDs asignados por el servidor.

## Grupos de configuración

### Crear un grupo

`POST /api/v1/projects/{projectId}/configuration-groups`

`{projectId}` es el **código** del proyecto (por ejemplo `ACME`).

#### Cuerpo de la petición

| Campo  | Obligatorio | Notas                                  |
| ------ | ----------- | -------------------------------------- |
| `name` | sí          | Cadena no vacía, máximo 120 caracteres |

Los campos `ulid` enviados por el cliente son rechazados.

#### Respuesta

`201` con el objeto del grupo de configuración creado. Ver [Campos de respuesta del grupo](#campos-de-respuesta-del-grupo).

Un nombre duplicado entre grupos activos del proyecto devuelve `409 conflict`. Un `name` vacío devuelve `422 validation_failed`.

#### Ejemplo

```bash
curl -sS -X POST \
  -H "Authorization: Bearer $PROBARA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"Navegador"}' \
  "https://app.probara.net/api/v1/projects/ACME/configuration-groups"
```

### Listar grupos

`GET /api/v1/projects/{projectId}/configuration-groups`

Devuelve los grupos de configuración activos (no eliminados) del proyecto.

#### Parámetros de consulta

| Parámetro  | Notas                                                                          |
| ---------- | ------------------------------------------------------------------------------ |
| `page`     | Número de página (base 1, por defecto `1`)                                     |
| `pageSize` | Elementos por página (por defecto `20`)                                        |
| `include`  | Pasa `values` para incluir los valores de configuración anidados en cada grupo |

#### Respuesta

`200` con `{ items, page, pageSize, total }`. Con `include=values`, cada ítem incluye un array `values`.

#### Ejemplo

```bash
curl -sS \
  -H "Authorization: Bearer $PROBARA_API_TOKEN" \
  "https://app.probara.net/api/v1/projects/ACME/configuration-groups?include=values"
```

### Obtener un grupo

`GET /api/v1/configuration-groups/{groupUlid}`

Devuelve un único grupo de configuración activo en el ámbito de la organización activa. Añade `?include=values` para incluir los valores anidados.

Devuelve `404 not_found` si el grupo no pertenece a la organización activa o ha sido eliminado.

#### Ejemplo

```bash
curl -sS \
  -H "Authorization: Bearer $PROBARA_API_TOKEN" \
  "https://app.probara.net/api/v1/configuration-groups/01JXXXXXXXXXXXXXXXXXXXXXXXXX"
```

### Actualizar un grupo

`PATCH /api/v1/configuration-groups/{groupUlid}`

Actualización parcial. Se requiere al menos un campo; un cuerpo vacío devuelve `422 validation_failed`.

#### Cuerpo de la petición

| Campo  | Obligatorio | Notas                                  |
| ------ | ----------- | -------------------------------------- |
| `name` | no          | Cadena no vacía, máximo 120 caracteres |

Un nombre duplicado entre grupos activos del proyecto devuelve `409 conflict`. Devuelve `404 not_found` si el grupo no pertenece a la organización activa.

#### Ejemplo

```bash
curl -sS -X PATCH \
  -H "Authorization: Bearer $PROBARA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"Navegador web"}' \
  "https://app.probara.net/api/v1/configuration-groups/01JXXXXXXXXXXXXXXXXXXXXXXXXX"
```

### Eliminar un grupo

`DELETE /api/v1/configuration-groups/{groupUlid}`

Elimina de forma lógica el grupo de configuración y todos sus valores anidados. Devuelve `204` si tiene éxito. Un `GET` posterior devuelve `404 not_found` y el grupo queda excluido de los resultados del listado.

Devuelve `404 not_found` si el grupo no pertenece a la organización activa.

#### Ejemplo

```bash
curl -sS -X DELETE \
  -H "Authorization: Bearer $PROBARA_API_TOKEN" \
  "https://app.probara.net/api/v1/configuration-groups/01JXXXXXXXXXXXXXXXXXXXXXXXXX"
```

### Campos de respuesta del grupo

Los endpoints de mutación (`POST`, `PATCH`) y `GET /api/v1/configuration-groups/{groupUlid}` devuelven un único objeto de grupo de configuración con los siguientes campos.

| Campo         | Tipo          | Notas                                        |
| ------------- | ------------- | -------------------------------------------- |
| `ulid`        | string (ULID) | Identificador único asignado por el servidor |
| `projectUlid` | string (ULID) | El proyecto al que pertenece este grupo      |
| `name`        | string        | Nombre para mostrar                          |
| `position`    | number        | Orden de clasificación relativo              |
| `createdAt`   | number        | Milisegundos desde epoch Unix                |
| `updatedAt`   | number        | Milisegundos desde epoch Unix                |

Con `include=values`, cada grupo también incluye un array `values` con [objetos de valor de configuración](#campos-de-respuesta-del-valor).

---

## Valores de configuración

Los valores de configuración están anidados dentro de un grupo de configuración.

### Crear un valor

`POST /api/v1/configuration-groups/{groupUlid}/configurations`

#### Cuerpo de la petición

| Campo  | Obligatorio | Notas                                  |
| ------ | ----------- | -------------------------------------- |
| `name` | sí          | Cadena no vacía, máximo 120 caracteres |

Los campos `ulid` enviados por el cliente son rechazados.

#### Respuesta

`201` con el objeto del valor de configuración creado. Ver [Campos de respuesta del valor](#campos-de-respuesta-del-valor).

Un nombre duplicado entre valores activos del grupo devuelve `409 conflict`. Un `name` vacío devuelve `422 validation_failed`.

#### Ejemplo

```bash
curl -sS -X POST \
  -H "Authorization: Bearer $PROBARA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"Chrome"}' \
  "https://app.probara.net/api/v1/configuration-groups/01JXXXXXXXXXXXXXXXXXXXXXXXXX/configurations"
```

### Listar valores

`GET /api/v1/configuration-groups/{groupUlid}/configurations`

Devuelve todos los valores de configuración activos del grupo, ordenados por posición.

#### Respuesta

`200` con `{ items, page, pageSize, total }`.

#### Ejemplo

```bash
curl -sS \
  -H "Authorization: Bearer $PROBARA_API_TOKEN" \
  "https://app.probara.net/api/v1/configuration-groups/01JXXXXXXXXXXXXXXXXXXXXXXXXX/configurations"
```

### Actualizar un valor

`PATCH /api/v1/configurations/{configurationUlid}`

Actualización parcial. Se requiere al menos un campo; un cuerpo vacío devuelve `422 validation_failed`.

#### Cuerpo de la petición

| Campo  | Obligatorio | Notas                                  |
| ------ | ----------- | -------------------------------------- |
| `name` | no          | Cadena no vacía, máximo 120 caracteres |

Un nombre duplicado entre valores activos del grupo devuelve `409 conflict`. Devuelve `404 not_found` si el valor no pertenece a la organización activa.

#### Ejemplo

```bash
curl -sS -X PATCH \
  -H "Authorization: Bearer $PROBARA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"Google Chrome"}' \
  "https://app.probara.net/api/v1/configurations/01JXXXXXXXXXXXXXXXXXXXXXXXXX"
```

### Eliminar un valor

`DELETE /api/v1/configurations/{configurationUlid}`

Elimina el valor de configuración de forma lógica. Devuelve `204` si tiene éxito. Un `GET` posterior devuelve `404 not_found`.

Devuelve `404 not_found` si el valor no pertenece a la organización activa.

#### Ejemplo

```bash
curl -sS -X DELETE \
  -H "Authorization: Bearer $PROBARA_API_TOKEN" \
  "https://app.probara.net/api/v1/configurations/01JXXXXXXXXXXXXXXXXXXXXXXXXX"
```

### Campos de respuesta del valor

| Campo         | Tipo          | Notas                                                 |
| ------------- | ------------- | ----------------------------------------------------- |
| `ulid`        | string (ULID) | Identificador único asignado por el servidor          |
| `groupUlid`   | string (ULID) | El grupo de configuración al que pertenece este valor |
| `projectUlid` | string (ULID) | El proyecto al que pertenece este valor               |
| `name`        | string        | Nombre para mostrar                                   |
| `position`    | number        | Orden de clasificación relativo dentro del grupo      |
| `createdAt`   | number        | Milisegundos desde epoch Unix                         |
| `updatedAt`   | number        | Milisegundos desde epoch Unix                         |

## Etiquetar una ejecución con configuraciones

Una ejecución puede llevar una combinación de valores de configuración — por ejemplo `Chrome` + `Windows` — establecida al crearla o reemplazada después, en cualquier ejecución (con o sin plan de pruebas vinculado).

### Crear con configuraciones

`POST /api/v1/projects/{projectId}/runs` acepta un arreglo opcional `configurationUlids` (máximo 20 entradas, sin duplicados):

```bash
curl -sS -X POST \
  -H "Authorization: Bearer $PROBARA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Smoke — Chrome / Windows",
    "caseUlids": ["01J...CASE"],
    "configurationUlids": ["01J...CHROME", "01J...WINDOWS"]
  }' \
  "https://app.probara.net/api/v1/projects/ACME/runs"
```

Cada ULID enviado debe resolver a un valor de configuración **vigente** en el propio proyecto de la ejecución; un ULID desconocido, eliminado, de otro proyecto o de otra organización devuelve `404 not_found` y no se crea ninguna ejecución. Se permite como máximo un valor por grupo de configuración — dos valores del mismo grupo devuelven `422 validation_failed` con `details.code = "duplicate_group"`.

### Reemplazar al actualizar

`PATCH /api/v1/runs/{runUlid}` acepta el mismo campo `configurationUlids`, aplicado como un **conjunto de reemplazo**:

- Un arreglo no vacío reemplaza toda la combinación de la ejecución por exactamente esos valores.
- `[]` limpia todas las configuraciones de la ejecución.
- Omitir la propiedad deja las configuraciones de la ejecución sin cambios.

Aplican las mismas reglas de resolución y de un valor por grupo. Un `PATCH` que solo cambie configuraciones se acepta en una ejecución **abierta** o **cerrada no abortada**; una ejecución **abortada** lo rechaza con `409 conflict`, igual que cualquier otra mutación de metadatos.

### Forma de la respuesta

Todo `RunResponse` incluye un arreglo `configurations` — ver [Forma de `RunResponse`](https://docs.probara.net/es/developers/api-reference/#forma-de-runresponse).

## Eventos de auditoría

Las mutaciones de configuración emiten los siguientes eventos en el feed de actividad de la organización:

- `configuration_group.created`, `configuration_group.updated`, `configuration_group.deleted`
- `configuration.created`, `configuration.updated`, `configuration.deleted`

Ver [Eventos de auditoría](https://docs.probara.net/es/developers/api/audit-events/).
