# Instantáneas de resultados de ejecución

> Carga de intento de solo lectura para un evento de marca en una ejecución.

Cada vez que un caso **se completa** en una ejecución (marca a nivel de caso o marca por
paso que deja el caso distinto de `untested`), la API añade una fila `test_results` e
instantáneas `test_result_step_snapshots`. Las filas de paso congeladas apuntan a ese resultado
mediante `snapshot_id`.

Usa este endpoint para el panel de intento de solo lectura en clientes e integraciones.

## Obtener instantánea

`GET /api/v1/runs/{runUlid}/results/{resultUlid}`

Requiere `viewer`+ en el proyecto de la ejecución. Devuelve **404** si la ejecución o el
resultado están fuera de la organización del llamador.

### Respuesta

| Campo               | Descripción                                                                                                                                                                                                                                                                                                      |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `result`            | Fila del log append-only (`status`, `executedAt`, `executedByUlid`, `executedByApiToken`, `hasSnapshot`, …); ver [Quién lo ejecutó](#quién-lo-ejecutó)                                                                                                                                                           |
| `case`              | Cabecera del caso (`titleSnapshot`, `caseNumber`, pre/post condiciones, …)                                                                                                                                                                                                                                       |
| `steps`             | Filas congeladas por paso con `status`, `actualResult` y `actualResultDocument`, `attachments[]` y `keyword` (la palabra clave Gherkin; `null` en un paso clásico)                                                                                                                                               |
| `resultAttachments` | Los adjuntos actuales del resultado, cada uno con su `stepIndex` (`null` para un archivo del resultado); ver [Adjuntos de resultados](https://docs.probara.net/es/developers/api/result-attachments/)                                                                                                                                    |
| `parameters`        | Los parámetros que un reporte de CI envió con el resultado, `[{ name, value }]` en el orden enviado; `[]` si no hay                                                                                                                                                                                              |
| `links`             | Los enlaces que un reporte de CI envió con el resultado, `[{ url, name }]` en el orden enviado (`name` es `null` si no se envió; `url` es siempre una URL absoluta `http:`/`https:`); `[]` si no hay                                                                                                             |
| `resultSteps`       | Los pasos que un reporte de CI envió con el resultado, aplanados en profundidad y en preorden: `{ position, parentPosition, action, status, durationMs, error, expected, data }`, donde `position` es el índice del paso desde 0 y `parentPosition` el de su padre (`null` en el nivel superior); `[]` si no hay |

`steps` es `[]` cuando el caso no tenía pasos. `parameters`, `resultSteps` y `links` se devuelven
con independencia de `steps`: un resultado que registró un reporte de CI los lleva aunque su caso no
tenga pasos propios. `resultSteps` no es
`steps`: `steps` son los pasos propios del caso congelados al marcar, `resultSteps` lo que reportó
la ejecución. Reconstruye el árbol a partir de `parentPosition`; la `position` de un paso es el
`stepIndex` que llevan sus adjuntos.

### Quién lo ejecutó

`result.executedByUlid` es el miembro que registró el resultado: el usuario con sesión iniciada, o
el propietario del token de API personal que lo escribió. `result.executedByApiToken` es el token de
API que lo escribió, `{ ulid, name, app }`: `app` es el reporter de CI (`junit`, `playwright`,
`jest`, `cypress`, `vitest`, `cucumber`) de un [token de aplicación](https://docs.probara.net/es/developers/authentication/#tokens-de-aplicación) y `null`
para un token de API personal. Es `null` para un resultado registrado en la aplicación y una vez
eliminado el token. Un token de aplicación no tiene usuario, así que un resultado que reportó tiene
`executedByUlid: null` y solo nombra el token.

### Ejemplo

```bash
curl -sS \
  -H "Authorization: Bearer $PROBARA_API_TOKEN" \
  "https://app.probara.net/api/v1/runs/$RUN/results/$RESULT"
```

## Listar resultados

`GET /api/v1/runs/{runUlid}/results` no cambia salvo que cada elemento incluye
`hasSnapshot: boolean` y `executedByApiToken` (ver [Quién lo ejecutó](#quién-lo-ejecutó)). Las vistas de Historial suelen filtrar `hasSnapshot: true` en
listas globales; los desplegables por caso pueden mostrar todas las filas.
