API de configuración de ejecución
Cada proyecto tiene doce configuraciones de ejecución que gobiernan el comportamiento del
marcado durante la ejecución de pruebas: si un run cerrado sigue aceptando escrituras de
resultado, si aplica un bloqueo por responsable asignado, qué ocurre después de registrar un
resultado, y más. Once de las doce heredan a través de una cadena de tres niveles,
proyecto → organización → valor por defecto del código; la duodécima,
defaultAssigneeUserId, es exclusiva del proyecto y no hereda en absoluto.
{projectId} es el código del proyecto (por ejemplo ACME) en todo lo siguiente; {orgUlid}
es el ULID de la organización del solicitante.
Vocabulario y valores por defecto del código
Sección titulada «Vocabulario y valores por defecto del código»| Clave | Tipo | Valor por defecto | ¿Hereda? |
|---|---|---|---|
autoCompleteRun | boolean | true | Sí |
allowResultsInClosedRuns | boolean | true | Sí |
fastPass | boolean | true | Sí |
defectToggleDefault | boolean | true | Sí |
autoAssignOnOpen | boolean | true | Sí |
failCaseOnStepFail | boolean | false | Sí |
autoPassWhenAllStepsPass | boolean | false | Sí |
assigneeResultLock | boolean | false | Sí |
requireCommentOnNegativeResult | boolean | false | Sí |
afterAddingResult | "stay" | "next_pending_by_number" | "next_pending_visual" | "next_pending_visual" | Sí |
timeTracking | "off" | "optional" | "required" | "optional" | Sí |
defaultAssigneeUserId | ULID de miembro | null | null | No — exclusiva del proyecto |
Un proyecto y una organización que no almacenan ningún valor para ninguna clave se comportan
exactamente como el producto lo hacía antes de que existiera esta capacidad — cada valor por
defecto del código anterior reproduce el comportamiento observable de hoy, con una excepción
deliberada: allowResultsInClosedRuns tiene por defecto true, lo que formaliza un
comportamiento de relajación del congelamiento que ya estaba vigente en la ruta de marcado
individual antes de que esta capacidad se publicara. Una organización que prefiera el
comportamiento anterior, más estricto, puede fijarlo en false.
Qué gobierna cada configuración
Sección titulada «Qué gobierna cada configuración»autoCompleteRun— si un run se cierra automáticamente en cuanto todos sus casos tienen un resultado. Cuando esfalse, el run permanece abierto hasta que un miembro lo cierra explícitamente.allowResultsInClosedRuns— si un run cerrado y no abortado sigue aceptando escrituras de resultado (marcados, marcados de paso, ediciones de notas de resultado, adjuntos de resultado). Un run abortado permanece congelado sin importar el valor de esta configuración, siempre. Consulta Casos de ejecución para el comportamiento exacto del409.fastPass/defectToggleDefault/requireCommentOnNegativeResult— experiencia de ejecución exclusiva del cliente web: si marcarpassed/skippedomite el modal de resultado, el valor inicial del interruptor de defecto en el modal, y si un resultado negativo exige un comentario antes de enviarlo. Consulta la limitación conocida más abajo para la única configuración de este grupo sin contraparte en el servidor.autoAssignOnOpen— si abrir un caso sin asignar autoasigna al usuario que actúa.failCaseOnStepFail/autoPassWhenAllStepsPass— si un resultado a nivel de paso deriva automáticamente el estado del caso padre. Precedencia cuando ambas aplican: un paso fallido gana sobre un paso bloqueado, que gana sobre un conjunto de pasos completamente aprobado.assigneeResultLock— si solo el tester asignado (o un solicitante exento) puede registrar un resultado para un caso asignado. Consulta Casos de ejecución para el comportamiento del403.afterAddingResult— qué caso enfoca el tablero de ejecución después de un marcado, únicamente en el cliente web. No es observable a través de la API.timeTracking— sielapsedMses opcional u obligatorio en un marcado individual con estado terminal. Consulta Casos de ejecución para el comportamiento del422.defaultAssigneeUserId— precompleta el responsable predeterminado de un run nuevo. Consulta Precedencia en la creación de runs más abajo.
Cadena de resolución y source
Sección titulada «Cadena de resolución y source»Cada una de las once claves heredables se resuelve en este orden: un override explícito a nivel
de proyecto gana; si no, un valor por defecto explícito a nivel de organización gana; si
no, aplica el valor por defecto del código. Un null almacenado en cualquier nivel significa
“sin override en ese nivel” — nunca se trata como el valor false o una cadena vacía.
La respuesta de cada clave heredable incluye:
| Campo | Significado |
|---|---|
value | El valor efectivo resuelto — lo que realmente gobierna el comportamiento ahora mismo |
source | "project", "organization" o "default" — qué nivel produjo value |
projectValue | El override crudo almacenado a nivel de proyecto, o null |
organizationValue | El override crudo almacenado a nivel de organización, o null |
organizationEffective | El valor efectivo propio de la organización (su override, o el valor por defecto del código) |
source es lo que un cliente debe usar para mostrar el indicador de “sobrescrito” / “heredado de
la organización” / “por defecto” — nunca comparar value contra organizationEffective. Un
valor de proyecto que coincide con el valor efectivo de la organización sigue siendo un
override almacenado: debe seguir mostrándose como tal y seguir siendo posible borrarlo, o un
cambio posterior del valor por defecto de la organización afectaría silenciosamente a un
proyecto que el usuario creía fijo.
defaultAssigneeUserId está exenta de la cadena — no tiene nivel de organización en
absoluto, así que su entrada solo incluye value y source ("project" o "default"), nunca
projectValue, organizationValue ni organizationEffective.
Configuración del proyecto
Sección titulada «Configuración del proyecto»Leer la configuración del proyecto
Sección titulada «Leer la configuración del proyecto»/api/v1/projects/{projectId}/run-settingsAbierto a cualquier lector del proyecto (viewer o superior). Devuelve 200 con las doce
entradas.
{ "settings": { "autoCompleteRun": { "value": true, "source": "default", "projectValue": null, "organizationValue": null, "organizationEffective": true }, "fastPass": { "value": false, "source": "project", "projectValue": false, "organizationValue": null, "organizationEffective": true }, "timeTracking": { "value": "required", "source": "organization", "projectValue": null, "organizationValue": "required", "organizationEffective": "required" }, "defaultAssigneeUserId": { "value": "01J...MEMBER", "source": "project" } }}(Abreviado — la respuesta real incluye las doce claves.)
Actualizar la configuración del proyecto
Sección titulada «Actualizar la configuración del proyecto»/api/v1/projects/{projectId}/run-settingsCada clave es opcional — una clave ausente se deja sin cambios, y un null
explícito restablece esa clave a heredar (para defaultAssigneeUserId, de vuelta a ningún
precompletado). Se requiere al menos una clave; un cuerpo vacío se rechaza con
422 validation_failed. Las claves desconocidas se rechazan de la misma manera (.strict()).
{ "fastPass": false, "requireCommentOnNegativeResult": null }defaultAssigneeUserId acepta el ULID de un miembro, nunca el id entero interno, resuelto
contra la membresía activa de la organización del proyecto — un ULID desconocido o ajeno se
rechaza con 404 not_found, y no se persiste nada.
Devuelve 200 con la respuesta completa recién resuelta (misma forma que GET).
Autorización
Sección titulada «Autorización»Requiere el permiso projects.manage (que tienen owner/admin), o el
propietario actual del proyecto. Un miembro que solo puede leer el proyecto
(viewer/member) recibe 403 forbidden.
Ejemplo
Sección titulada «Ejemplo»curl -sS -X PATCH \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"fastPass": false, "assigneeResultLock": true}' \ "https://app.probara.net/api/v1/projects/ACME/run-settings"Valores predeterminados de la organización
Sección titulada «Valores predeterminados de la organización»Leer los valores predeterminados de la organización
Sección titulada «Leer los valores predeterminados de la organización»/api/v1/orgs/{orgUlid}/run-settingsAbierto a cualquier miembro de la organización. Devuelve 200 con las once claves
heredables únicamente — defaultAssigneeUserId nunca aparece aquí, porque no tiene nivel de
organización.
{ "settings": { "autoCompleteRun": { "value": true, "source": "default", "organizationValue": null }, "fastPass": { "value": true, "source": "organization", "organizationValue": true } }}(Abreviado — la respuesta real incluye las once claves.)
Actualizar los valores predeterminados de la organización
Sección titulada «Actualizar los valores predeterminados de la organización»/api/v1/orgs/{orgUlid}/run-settingsMisma semántica de “ausente = sin cambios” / “null explícito restablece al valor por defecto
del código” que el endpoint de proyecto, restringida a las once claves heredables. Enviar
defaultAssigneeUserId aquí se rechaza con 422 validation_failed como clave desconocida —
nunca como un no-op silencioso, ya que el esquema solo declara las once claves heredables.
{ "timeTracking": "required" }Autorización
Sección titulada «Autorización»Requiere el permiso org-settings.manage.
Ejemplo
Sección titulada «Ejemplo»curl -sS -X PATCH \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"autoCompleteRun": false}' \ "https://app.probara.net/api/v1/orgs/01J...ORG/run-settings"«Fijar como valor predeterminado de la organización»
Sección titulada ««Fijar como valor predeterminado de la organización»»Cambiar un valor predeterminado de la organización mueve el valor efectivo de cada proyecto
que no almacena un override propio para esa clave — un proyecto que ya tiene su propio override
con source: "project" no se ve afectado. El panel de configuración de proyecto de la
aplicación web ofrece una acción «Fijar como valor predeterminado de la organización» en el menú
de la fila de cualquier clave sobrescrita a nivel de proyecto (visible solo para quien tiene
org-settings.manage), que es exactamente un PATCH al endpoint de organización con el valor
de esa única clave a nivel de proyecto — no existe una superficie de API separada para ello.
Limitación conocida: requireCommentOnNegativeResult se aplica solo en el cliente
Sección titulada «Limitación conocida: requireCommentOnNegativeResult se aplica solo en el cliente»Esta única configuración no tiene contraparte en el servidor. El texto del comentario llega
en una solicitud separada de la del propio marcado
(PATCH /api/v1/runs/{runUlid}/results/{resultUlid}), así que ninguna solicitud individual al
servidor puede observar “este caso se marcó como fallido sin comentario” — aplicarlo en el
servidor implicaría ampliar la solicitud de marcado con un cambio disruptivo desproporcionado
para una única configuración de interfaz, o un barrido posterior sin disparador natural. Un
cliente de API o de reportes puede marcar un caso como failed o blocked sin comentario
mientras esta configuración está activa — el modal de resultado de la aplicación web es el
único lugar donde se aplica esta regla. Cada una de las demás configuraciones de este documento
hereda hacia un comportamiento del lado del servidor o tiene una brecha explícita y documentada
por separado (consulta Casos de ejecución para la aplicación en
el servidor de timeTracking, que sí es real).
Dónde aplica y dónde no timeTracking: "required"
Sección titulada «Dónde aplica y dónde no timeTracking: "required"»El rechazo 422 elapsed_ms_required de timeTracking: "required" (consulta
Casos de ejecución) solo se activa en una ruta de código que
realmente invoca la lógica de marcado individual. Esta tabla es la auditoría completa de la
superficie:
| Superficie | ¿Llega al control? | Aplica o está exenta |
|---|---|---|
Marcado individual — PATCH /api/v1/runs/{runUlid}/cases/{runCaseUlid} | Sí, directamente | Aplica el 422 |
Herramienta MCP mark_run_case | Sí — despacha al mismo endpoint textualmente | Aplica — sin manejo especial en la herramienta, hereda el 422 del endpoint |
Marcado en bloque — POST .../cases/bulk-mark (y MCP bulk_mark_run_cases) | No — el esquema de la solicitud no lleva ningún campo de duración por caso | Exenta a nivel de esquema — no existe forma de construir una solicitud que lo viole |
Envío de resultados en bloque — POST .../cases/bulk-submit-result (y MCP bulk_submit_result) | No — pasa por un servicio distinto, nunca por la ruta de marcado individual | Exenta por diseño — el envío en bloque queda explícitamente fuera del alcance de este rechazo |
Enriquecimiento de notas de resultado — PATCH /api/v1/runs/{runUlid}/results/{resultUlid} | No — modifica una fila de resultado ya agregada (notes); nunca genera un cambio de estado | Exenta — fuera de alcance estructuralmente, no lleva status |
| Ruta automatizada de ingesta de resultados | N/D — esta API no tiene hoy una superficie de ingesta de resultados por CSV/webhook/CI | No aplica |
Precedencia en la creación de runs
Sección titulada «Precedencia en la creación de runs»defaultAssigneeUserId solo decide con qué empieza un run recién creado — cambiar la
configuración del proyecto nunca reescribe el responsable ya almacenado de un run existente.
POST /api/v1/projects/{projectId}/runs resuelve el responsable predeterminado del run en este
orden:
defaultAssigneeUlidpresente en el cuerpo de la solicitud de creación del run (incluido unnullexplícito, que significa “deliberadamente ninguno”) — siempre gana.- Si no, la configuración
defaultAssigneeUserIddel proyecto, cuando está definida. - Si no,
null— el comportamiento de hoy, sin cambios.
Relacionados
Sección titulada «Relacionados»- Casos de ejecución — los endpoints de marcado que gobiernan
estas configuraciones, incluidos los comportamientos
403 run_case_assignee_lockedy422 elapsed_ms_required - Adjuntos de resultado de ejecución — comportamiento de escritura en runs cerrados para adjuntos de paso y notas de resultado
- Descripción general de la referencia de la API — paginación, errores, autenticación
- Referencia interactiva v1 — esquemas completos