Consolida el disparador, los huecos de datos y el protocolo de prueba para continuar el desarrollo con decisiones trazables.
33 KiB
Investigación de la API de Jira — qué probar exactamente
Fecha: 30-jul-2026 · Actualizado: 10-ago-2026 Propósito: lista cerrada de pruebas y preguntas para habilitar la integración Jira → cotización BIND (estimada en ~10 h, REGISTRO #51). Documento de trabajo interno; sirve también como briefing para el agente/chat especializado en la API de Jira.
Estado validado (30-jul):
- Sitio:
https://balam-jsm-temp.atlassian.net. El token regenerado de Pedro, usado con Basic auth ypedro.ayala@balamtalentoestrategico.com, respondió 200 aGET /rest/api/3/myself. - Facturación es el proyecto JSM
FAC(projectId: 10034,serviceDeskId: 35), de tiposervice_desky estiloclassic(company-managed). - La búsqueda de FAC devolvió 66 tickets. La API vigente es
GET /rest/api/3/search/jql, con paginación pornextPageToken; el endpoint clásico/rest/api/3/searchresponde 410 Gone. - Estatus confirmados:
Open,En proceso de facturación,En espera por colaborador,En validación nacional,En validación extranjera,FacturadoyCancelado. No se observó un estatus llamado “Resuelto”. - Límites de consumo ya aclarados por Pedro (sin tope mensual; 3 límites de velocidad; telemetría solo en headers
X-RateLimit-*).
⭐ Decisiones de negocio recibidas (correo del 7-ago) y su verificación por API (10-ago)
Balam contestó las tres preguntas del 30-jul. Arturo respondió el 4-ago (en verde sobre el correo de Noé), Noé lo reenvió el 7-ago. Fuente: RV_ Seguimiento_ medición de consumo API de Jira y accesos.eml.
| Decisión de Balam | Quién / cuándo | Verificación por API (10-ago) |
|---|---|---|
La cotización BIND se genera al entrar a En proceso de facturación |
Arturo, 4-ago | ✅ Estatus y transición Iniciar facturación ya inventariados (Bloque 3) |
| Todo se tramita como facturación normal; el caso recurrente espera a que se explore el módulo de Proyectos de BIND | Arturo, 4-ago | ⚠️ El campo Facturación recurrente sigue siendo obligatorio y se está llenando (FAC-100: Si, periodo 12) |
Se observan todos los request types de la bandeja de facturación, no solo Facturación adicional |
Arturo, 4-ago | 🔴 10 de 69 tickets no tienen request type alguno y ninguno trae campos de facturación (ver Bloque 1) |
| Monto y conceptos van como campos de Jira, no del adjunto; omitir el campo de recurrencia | Arturo, 4-ago | ⚠️ Monto sin IVA ya existe y funciona; conceptos no existe como campo en todo el sitio (ver Bloque 2) |
Las pruebas de escritura son prueba acompañada sobre un ticket, no proyecto FACTEST |
Noé, 7-ago | Se descarta el sandbox en la instancia de Balam → aplica el protocolo del Bloque 6 sin excepción |
Lo que sigue abierto tras estas respuestas: de dónde salen los conceptos/partidas de la cotización, qué hacer con los tickets sin campos estructurados, si nacional/extranjero cambia la cotización o solo el paquete de salida, PUE vs PPD, la fecha de la prueba acompañada y la migración a cuenta de servicio.
Bloque 0 — Acceso autenticado ✅
El 401 del 29-jul quedó explicado por la combinación de token previo y datos de conexión incompletos. Pedro confirmó el correo, regeneró el token y compartió el dominio del sitio.
Configuración que funcionó:
GET https://balam-jsm-temp.atlassian.net/rest/api/3/myself
Authorization: Basic base64(pedro.ayala@balamtalentoestrategico.com:<token>)
Accept: application/json
El resultado fue HTTP 200. Por tanto, para esta integración se usará la API directa del sitio con Basic auth; no hay evidencia de que se requiera una ruta api.atlassian.com/ex/jira/{cloudId}.
Prueba canónica de auth (la primera que debe correrse siempre):
GET /rest/api/3/myself
Interpretación de la respuesta:
- 200 → auth OK; además devuelve
accountId(identidad con la que la plataforma va a escribir — dato de gobierno, ver Bloque 7). - 401 → credencial inválida/inactiva o esquema mal armado.
- 403 → credencial VÁLIDA pero sin permiso → problema de permisos, no de token. Distinguir 401 de 403 es el diagnóstico más barato que existe.
⚠️ Registrar siempre los headers de la respuesta 401 completos. Ahí vive la pista (
WWW-Authenticate,X-Seraph-LoginReason,X-Failure-Category).
Bloque 1 — Topología: Jira Service Management confirmado ✅
FAC está confirmado como Jira Service Management (JSM). Por ello la integración requiere dos familias de API:
| API | Para qué | Cuándo usarla |
|---|---|---|
/rest/api/3/... |
Issues genéricos: JQL, campos, transiciones, adjuntos, changelog | Lectura/sync, transiciones, trazabilidad |
/rest/servicedeskapi/... |
Requests de portal: request types, campos del formulario, aprobaciones, SLA, comentarios públicos vs internos | Crear tickets como los crea un humano; leer aprobaciones y SLA |
Resultados:
GET /rest/api/3/project/FAC
→ projectTypeKey: service_desk, style: classic, id: 10034.
GET /rest/servicedeskapi/servicedesk
→ FAC corresponde a serviceDeskId: 35.
Request types publicados en el portal (GET /rest/servicedeskapi/servicedesk/35/requesttype, isLastPage: true):
| requestTypeId | Nombre | Campos obligatorios |
|---|---|---|
| 84 | Bajas | 7 |
| 83 | Facturación adicional | 10 |
| 389 | Automatización | 1 (solo summary) |
| 12 | Facturación | 1 (solo summary) |
Contratos verificados el 10-ago con /requesttype/{id}/field:
| Request type | Hallazgo |
|---|---|
Bajas (84) |
Empresa origen, Summary, adjunto de Cálculo/VoBo de Finiquito, Nombre del Cliente, Nombre del Colaborador, Fecha de la Baja y Motivo de la Baja. |
Facturación adicional (83) |
Empresa origen, MES / DESCRIPCIÓN / CLIENTE (es el summary), Cliente Nuevo, Nombre del Cliente, adjunto de cotización/CSF, Tipo de Moneda, Días de Crédito, Facturación recurrente, Periodo de recurrencia y Monto sin IVA. Es el contrato más completo. ⚠️ Cambió desde el 30-jul: se agregó Monto sin IVA y desapareció Periodo de Incidencias. |
Automatización (389) |
Solo exige Summary. |
Facturación (12) |
Solo exige Summary. |
🔴 “Todos los request types” incluye tickets sin request type
La bandeja de FAC muestra en el filtro de la UI 6 de 6 opciones: las 4 de arriba más Empty y Emailed request. Ninguna de esas dos aparece en servicedeskapi porque no están publicadas en el portal. El conteo real sobre los 69 tickets de FAC (10-ago):
| Request type | Tickets | c/Monto | c/Moneda | c/Cliente | c/Adjunto |
|---|---|---|---|---|---|
| 83 — Facturación adicional | 48 | 2 | 48 | 48 | 48 |
| (sin request type) | 10 | 0 | 0 | 0 | 3 |
| 84 — Bajas | 6 | 0 | 0 | 6 | 6 |
| 389 — Automatización | 4 | 0 | 0 | 0 | 4 |
| 12 — Facturación | 1 | 0 | 0 | 0 | 1 |
Los 10 tickets sin request type tienen creator y reporter = Automation for Jira: nacen de una regla de Automation desde otras bandejas (HH, SA, IN, RH), no del portal. Y no son ruido: FAC-91 es uno de ellos, está vivo en En validación nacional y su summary es [FACTURA COMPLETA - Staff Augmentation] Axians - Incident Manager — RH-36. Es decir, hay facturación real entrando por una vía que no tiene ni un solo campo estructurado — los datos viajan codificados en el summary y en la description (ADF), más 2 adjuntos.
Emailed request hoy tiene 0 tickets, pero existe en la configuración: cualquier correo a la bandeja aterriza ahí, también sin campos.
Implicación: el acuerdo literal “todos los request types” significa que ~14% de los tickets no puede generar una cotización automática con el diseño de campos estructurados. Hay dos salidas y conviene que Balam elija explícitamente: (a) acotar la automatización a los request types que sí traen campos y dejar los demás en tratamiento manual, o (b) que Automation for Jira propague los campos al crear el ticket en FAC. La opción (b) es trabajo del lado de Balam, no de la plataforma.
Bloque 2 — Modelo de datos del ticket FAC (el mapeo) 🔴
Esto es lo que decide si la integración es de 10 h o de 25. La pregunta de fondo: ¿los datos de facturación vienen en campos estructurados o en texto libre? Si vienen en texto libre, hay que negociar campos nuevos con Pedro o meter parsing frágil.
Lo que la plataforma necesita de cada ticket para armar una cotización en BIND:
| Dato requerido | Por qué | Qué verificar |
|---|---|---|
| Cliente | Match contra Clients de BIND (por RFC o nombre normalizado) |
¿Campo custom? ¿Lista desplegable? ¿Texto libre? ¿Trae RFC? |
| Monto y moneda | Cotización BIND; la cartera jamás mezcla monedas | ¿Campo numérico? ¿Viene la moneda separada o embebida en el texto? |
| Nacional vs internacional | Determina PDF+XML (nacional) vs solo PDF (extranjero) | ¿Se deduce del cliente o hay campo/etiqueta? |
| Concepto / descripción | Línea de la cotización | Ver formato (ver ⚠️ ADF abajo) |
| Tipo de solicitud | adicional / recurrente / baja / headhunting / staff augmentation | ¿Request type, issue type, o campo? |
Folio FAC-nnn |
Trazabilidad ticket ↔ cotización ↔ factura (persistir en el modelo) | Confirmar formato y estabilidad (ver Bloque 5, ⚠️ moves) |
| Solicitante / área | Auditoría | reporter vs requester de JSM (no son lo mismo) |
| Adjuntos | Constancia fiscal, Excel de horas (CEMEX), estado de cuenta | Cómo se descargan y con qué auth |
Resultados de lectura:
GET /rest/api/3/issue/FAC-98?expand=names,renderedFields
→ caso real de tipo Bajas: cliente Axians, colaborador, fecha y motivo de baja en campos estructurados; una evidencia adjunta; sin descripción. Los valores de texto enriquecido regresan como ADF.
Mapeo de campos confirmado (10-ago)
| Campo de Jira | fieldId |
Tipo | Valores | → BIND |
|---|---|---|---|---|
| Empresa origen | customfield_11423 |
option | Balam, RegioTurk, Helmstone |
Emisor (multi-empresa) |
| MES / DESCRIPCIÓN / CLIENTE | summary |
string | texto libre | Referencia / parseo de respaldo |
| Cliente Nuevo | customfield_10052 |
option | Si, No |
Decide si hay que dar de alta el cliente |
| Nombre del Cliente | customfield_10202 |
ADF (textarea) | texto enriquecido | Match contra Clients de BIND |
| Tipo de Moneda | customfield_10053 |
option | MXN, USD, OTRO |
Moneda de la cotización |
| Días de Crédito | customfield_10054 |
option | 30, 45, NA |
Condiciones de pago |
| Facturación recurrente | customfield_10552 |
option | Si, No |
Fuera de alcance por ahora (Arturo, 4-ago) |
| Periodo de recurrencia | customfield_10553 |
string | texto | Fuera de alcance por ahora |
| Monto sin IVA | customfield_11556 |
number/float | — | Total de la cotización |
| Approvers | customfield_10003 |
array/user | — | Gobierno (ver Bloque 3) |
⚠️ Nombre del Cliente es ADF, no string. El match contra BIND tiene que extraer texto plano de un documento estructurado, no leer un campo de texto. Nada garantiza que el nombre escrito a mano coincida con la razón social en BIND; el campo no trae RFC, que sería la llave confiable.
🔴 Dos huecos que el acuerdo del 4-ago no cierra
-
Monto sin IVAexiste pero está prácticamente vacío. Solo 2 de 69 tickets lo tienen:FAC-100yFAC-101, ambos creados el 4-ago — el mismo día en que Arturo contestó el correo. El campo se agregó en ese momento; los 67 tickets anteriores lo tienen ennull. Es buena noticia (el acuerdo ya se implementó) con dos consecuencias: no hay histórico para validar el mapeo contra facturas reales, y la obligatoriedad solo aplica al crear por portal — un ticket nacido de Automation entra connulligual. -
conceptos/ partidas no existe como campo en NINGUNA parte del sitio.GET /rest/api/3/fieldfiltrado por monto/concepto/partida/importe/precio/cantidad/RFC devuelve únicamente:customfield_11556—Monto sin IVA(en uso)customfield_11522—Monto con IVA(existe, no está en el formulario 83)customfield_10031—Total forms(de JSM, no es de facturación)
Con un solo monto agregado no se pueden armar partidas: la cotización BIND queda de una sola línea con la descripción del
summary. Eso puede ser aceptable como decisión, pero hay que tomarla explícitamente, y no cubre el caso ACUNTIA. Que existaMonto con IVAsin usar además abre la pregunta de si el IVA lo calcula BIND o viene dado.
El caso ACUNTIA ya tiene evidencia: FAC-100 es exactamente eso — summary Julio/CONSULTORIA Y SERVICIOS (Eduardo Fiallo CEMEXUSA)/ACUNTIA, Helmstone, USD, 45 días, Monto sin IVA = 7594.00, con 2 adjuntos. Un solo monto para un ticket que históricamente representa 40–48 facturas (REGISTRO #55 punto 6). El supuesto “un ticket → una cotización” necesita confirmarse contra este caso antes de codificar.
⚠️ ADF (Atlassian Document Format). En Jira Cloud v3,
descriptiony los comentarios no son texto plano ni wiki markup: son JSON estructurado. Hay que decidir ya si se parsea ADF o se pideexpand=renderedFields(HTML). Y al escribir comentarios/descripciones hay que construir ADF válido, no mandar un string. Es la trampa que más tiempo cuesta si se descubre tarde.
⚠️ Adjuntos: confirmar si
content(URL de descarga) requiere el mismo Basic auth y si redirige. Y aplica la misma regla que con BIND: los adjuntos traen datos reales de clientes (constancias, estados de cuenta) — no van a disco del repo ni a documentos.
Bloque 3 — Workflow, estatus y transiciones (el disparador) ✅🟡
Disparador confirmado por Arturo el 4-ago: la cotización BIND se crea al entrar a En proceso de facturación. El inventario técnico ya estaba levantado, así que la regla de negocio queda cerrada.
Inventario confirmado:
GET /rest/api/3/project/FAC/statuses → estatus por tipo de issue, con id y statusCategory
| Estatus | ID | Categoría |
|---|---|---|
| Open | 1 | To Do |
| En proceso de facturación | 10305 | In Progress |
| Facturado | 10306 | Done |
| En espera por colaborador | 10339 | In Progress |
| Cancelado | 10372 | Done |
| En validación nacional | 10635 | In Progress |
| En validación extranjera | 10669 | In Progress |
Transiciones de lectura confirmadas (son contextuales al estatus actual):
| Ticket / estatus actual | transitionId | Destino |
|---|---|---|
| FAC-98 / En proceso de facturación | 6 | En espera por colaborador |
| FAC-98 / En proceso de facturación | 8 | En validación nacional |
| FAC-98 / En proceso de facturación | 9 | En validación extranjera |
| FAC-98 / En proceso de facturación | 2 | Cancelado |
| FAC-91 / En validación nacional | 2 | Cancelado |
| FAC-89 / Cancelado | 12 | Open |
FAC-97 ya está Facturado y no expone transiciones. Las respuestas consultadas no devolvieron campos obligatorios para las transiciones anteriores. Aun así, no se ejecutará ninguna transición sin la sesión acompañada.
Diagrama de workflow compartido por Balam: confirma la ruta completa y los nombres de transición:
Open --[Iniciar facturación]--> En proceso de facturación
En proceso de facturación --[Pausar actividad]--> En espera por colaborador
En espera por colaborador --[Retomar actividad]--> En proceso de facturación
En proceso de facturación --[Validar documentación nacional]--> En validación nacional
En proceso de facturación --[Validar documentación extranjera]--> En validación extranjera
En validación nacional o extranjera --[Facturación completa]--> Facturado
En validación nacional o extranjera --[Rechazar actividad]--> En proceso de facturación
El diagrama también contempla cancelación desde los estados de trabajo y reapertura; la API confirmó al menos Cancelado --[Reabrir Ticket]--> Open en FAC-89. No existe un estado “Resuelto” en el workflow. Con la respuesta del 4-ago, la regla queda: Iniciar facturación (Open → En proceso de facturación) dispara la cotización; Facturado confirma que la factura se emitió.
🔴 Hallazgo crítico: el estatus disparador dura minutos, no horas
Recorrido real de FAC-100 (4–5 ago), desde su changelog:
| Hora | Transición | Autor |
|---|---|---|
| 05-ago 11:51:25 | Open → En proceso de facturación |
Arturo Rosas |
| 05-ago 11:54:09 | → En validación extranjera |
Arturo Rosas |
| 05-ago 12:16:37 | → Facturado |
Araceli Sánchez |
El ticket estuvo 2 minutos 44 segundos en el estatus disparador, y 25 minutos de punta a punta. Hoy solo 1 de los 69 tickets está parado en En proceso de facturación (65 ya están Facturado).
Consecuencia de diseño, no negociable: un poller de 15 min que pregunte “¿qué tickets están hoy en En proceso de facturación?” se pierde la mayoría de los disparos. La detección tiene que leer el changelog y buscar el cruce de estado dentro de la ventana, exactamente como se resolvió la detección de pagos en BIND (ADR-004). Esto confirma y vuelve obligatorio lo que antes era una preferencia de arquitectura, y refuerza el caso de los webhooks (Bloque 4) para reducir la latencia.
⭐ Hallazgo nuevo: el workflow tiene aprobaciones de JSM
Ni FAC-98 ni el diagrama lo mostraban. Tanto FAC-100 como FAC-91 traen:
customfield_10003Approvers =Araceli Sánchezcustomfield_10025Approvals = el estatus donde vive la aprobación (En validación extranjera/En validación nacional)
Es decir, el paso a Facturado pasa por una aprobación formal de Araceli, no por una transición simple. Implicaciones: (1) la plataforma no debe intentar aprobar — eso es decisión humana; (2) si algún día tuviera que transicionar a Facturado, la vía correcta es /rest/servicedeskapi/request/{id}/approval, no /transitions; (3) la aprobación es un buen punto de trazabilidad para saber quién autorizó cada factura.
⚠️ Trampas:
Resuelto (10-ago): enFacturadocomo estatus ≠ camporesolution.FAC-100,status = Facturadoyresolution = Doneyresolutiondatepoblada, todo consistente. Ambas señales sirven; se usará el cruce de estatus en el changelog por coherencia con el resto del diseño.- Las transiciones son contextuales:
/transitionssolo devuelve las salidas del estado actual, y pueden tener pantallas con campos obligatorios. Probar conexpand=transitions.fieldspara saber si transicionar por API exige llenar algo. issuetypede FAC esadmon, no “Service Request”. Cualquier JQL o creación por API debe usar ese nombre.
Changelog = la fuente de la detección. expand=changelog da cada cambio de estatus con timestamp y autor. Verificado en FAC-100 (total: 6) y FAC-91 (total: 8): vienen completos y sin paginar en tickets de este tamaño. Para tickets con mucho historial hay que usar /rest/api/3/issue/{key}/changelog, que sí pagina.
Bloque 4 — Estrategia de sincronización: polling vs webhooks 🟡
El scheduler de la plataforma ya existe (BackgroundService + PeriodicTimer a 15 min). La pregunta es qué le pega a Jira.
a) Búsqueda por JQL — validado.
El endpoint clásico GET /rest/api/3/search respondió 410 Gone. La integración debe usar GET /rest/api/3/search/jql, con nextPageToken. La lectura de FAC recuperó 66 tickets con ese mecanismo.
JQL de delta a validar:
project = FAC AND updated >= "-20m" ORDER BY updated ASC
⚠️ updated en JQL tiene granularidad de minuto, no de segundo → el checkpoint necesita ventana de solape (igual que el re-barrido de facturas abiertas de BIND) o se pierden tickets en el borde.
Validar también: fields= para pedir solo lo necesario (menos payload, menos puntos), y el tope real de maxResults.
b) Webhooks. Tres caminos, con dueños distintos:
| Opción | Quién la configura | Nota |
|---|---|---|
| Webhook de sitio (admin) | Pedro (requiere admin de Jira) | El más limpio; exige endpoint público |
| Regla de Jira Automation con "Send web request" | Pedro, sin escribir código | La más realista a corto plazo; se puede acotar a FAC y a un estatus |
| Webhook dinámico vía OAuth app | Desarrollo | Expiran a los 30 días, hay que refrescarlos |
Recomendación: arrancar con polling y dejar el webhook para después. Ningún webhook sirve hasta que exista un endpoint público, y Azure sigue pendiente del lado de Balam. El polling además es reversible y no depende de que Pedro toque su instancia.
c) Rate limits — headers verificados ✅ (10-ago). La respuesta de /rest/api/3/search/jql sí los emite:
X-RateLimit-Limit: 350
X-RateLimit-Remaining: 348
RateLimit-Policy: "jira-burst-based";q=100;w=1
RateLimit: "jira-burst-based";r=348;t=1
Tres notas: (1) la telemetría existe y el autorregulado por headers es viable, como se le dijo a Erika el 29-jul; (2) el límite observado es 350, no los 100/s que mencionó Pedro — hay que leer el header y no hardcodear el número; (3) aparecen también los headers estándar RateLimit-* (RFC) además de los X-RateLimit-*, así que el cliente debe tolerar ambos. X-RateLimit-NearLimit no apareció porque no se llegó al 20% del umbral. No se provocó un 429 deliberadamente contra producción.
Bloque 5 — La bandeja padre: de dónde nacen realmente los tickets 🟡
Pedro dijo que procesos que se cierran en RH o Administración General caen en Facturación. Técnicamente eso puede ser cuatro cosas distintas, y cada una se sincroniza diferente:
| Mecanismo | Cómo detectarlo | Implicación |
|---|---|---|
| Issue link (RH-45 relacionado con FAC-89) | issuelinks en el issue |
Escuchar FAC basta; el link da contexto |
| Clon / creación por Automation | changelog + campo creator (usuario de automation) |
Escuchar FAC basta |
| Subtarea / hijo | parent / subtasks |
Relevante para ACUNTIA (1 ticket ↔ 40 facturas) |
| Move entre proyectos | changelog con cambio del campo project |
🔴 La llave del ticket CAMBIA (RH-45 → FAC-89). Cualquier folio persistido se rompe |
Resultado de la prueba (10-ago): es creación por Automation, no move. ✅
Los 10 tickets sin request type tienen creator = reporter = Automation for Jira, y sus changelogs (revisados en FAC-91) no muestran cambios de project ni de key. El patrón es: la regla de Automation crea un ticket nuevo en FAC y lo liga al original con issuelinks. Ejemplos de summary, que llevan el origen embebido:
FAC-91 [FACTURA COMPLETA - Staff Augmentation] Axians - Incident Manager — RH-36
FAC-1 Seguimiento del Ticket Cerrado: HH-1 - Prueba #1
FAC-28 Seguimiento del Ticket con pago anticipado: HH-8 - TLE
Se ven tres bandejas de origen: HH (headhunting), SA (staff augmentation), IN, y RH. Dos patrones de regla: Seguimiento del Ticket Cerrado: y Seguimiento del Ticket con pago anticipado: — el segundo probablemente implique PUE y toca la pregunta pendiente de PUE/PPD.
Conclusiones para el modelo de datos:
- Escuchar FAC basta para detectar el disparo; el origen se obtiene de
issuelinkssin salir del proyecto. - No hay evidencia de moves, así que la llave
FAC-nnnparece estable. Aun así conviene persistir elissue.idnumérico (FAC-100 =17308, FAC-91 =14348): es inmutable por diseño y el costo de guardarlo es cero. - ⚠️ Estos tickets son la vía sin campos estructurados del Bloque 1. Si la automatización debe cubrirlos, la regla de Automation de Balam tendría que propagar los campos al crear el ticket en FAC.
Bloque 6 — Escritura (CRUD): qué probar, cómo aprobarlo y dónde 🔴
Confirmado por Noé el 7-ago: prueba acompañada sobre un ticket acordado. No habrá proyecto FACTEST. Eso cierra la pregunta pero deja el riesgo intacto: se escribirá en producción, y el token tiene permisos para crear, editar, transicionar, comentar, adjuntar e incluso borrar tickets en FAC. El protocolo de abajo pasa de recomendación a requisito, y el sandbox propio (ver recuadro al final del bloque) pasa de opcional a necesario para desarrollar sin tocar Balam.
Protocolo obligatorio para cualquier prueba de escritura:
- Preparar un script idempotente y de una sola operación; sin bucles, sin búsquedas masivas y sin credenciales embebidas.
- Compartir el script y el payload de ejemplo con Pedro/Arturo antes de la sesión; documentar endpoint, ticket destino, efecto esperado y reversión.
- Acordar el ticket de prueba y una ventana de ejecución. Preferir un proyecto sandbox (
FACTEST) o un ticket creado expresamente para la prueba. - Ejecutarlo acompañado, registrar el
HTTP status, elissue.id/keyy verificar el resultado por API. - No probar
DELETE; no es una capacidad necesaria para la plataforma y no es reversible en producción.
Operaciones a validar, en este orden (de menos a más invasivo):
- Comentar —
POST /rest/api/3/issue/{key}/comment(cuerpo en ADF). ⚠️ En JSM hay comentarios públicos (los ve el cliente) vs internos:POST /rest/servicedeskapi/request/{id}/commentconpublic: true|false. La plataforma debe escribir SIEMPRE internos. Publicar por error un comentario visible al cliente es el error más caro y menos reversible de este bloque. - Adjuntar —
POST /rest/api/3/issue/{key}/attachments. ⚠️ Exige el headerX-Atlassian-Token: no-checkymultipart/form-data. Sin ese header falla con un error que no explica nada. Es la vía para dejar el PDF/XML como evidencia en el ticket. - Transicionar —
POST /rest/api/3/issue/{key}/transitionscon eltransition.iddel Bloque 3. - Crear — decisión real de diseño:
POST /rest/api/3/issue(crudo, se salta el request type y el ticket queda "raro" en el portal) vsPOST /rest/servicedeskapi/request(respeta request type y se ve como uno normal). Si es JSM, la segunda es la correcta. - Editar —
PUT /rest/api/3/issue/{key}. - Borrar —
DELETE /rest/api/3/issue/{key}. Requiere permiso de admin de proyecto. Probablemente ni se tenga ni convenga tenerlo; en producción el borrado no debe ser una capacidad de la plataforma.
🔴 Dónde probar.
Pedir a Pedro un proyecto de pruebas→ descartado por Noé el 7-ago: será prueba acompañada sobre un ticket. Queda entonces una sola vía de mitigación:FACTESTCrear un sitio propio y gratuito de Jira Cloud (plan Free, hasta 10 usuarios) con un proyecto JSM que replique el workflow de FAC. Sirve para desarrollar el cliente, el parser de ADF, la paginación, las aprobaciones y las transiciones sin tocar nada de Balam ni depender de que respondan. Es el sandbox que BIND nunca tuvo. Contra producción solo se corre lectura y, al final, la única prueba acompañada.
Con el
FACTESTdescartado, esto ya no es una alternativa: es el único lugar donde se puede equivocar sin costo.
Bloque 7 — Gobierno y seguridad 🟡
- ✅
→ Resuelto: ignorado enpropuesta/token-jira.txtNO está en.gitignore.gitignore:9. Sigue pendiente mover el token a user-secrets / Key Vault y borrarlo de disco. Mismo pendiente que arrastrabind_token_api.txt. - Cuenta de servicio vs cuenta personal de Pedro (ya planteado en el borrador de correo del 29-jul): hoy todo lo que la plataforma escriba en Jira queda firmado con el nombre de Pedro, y una rotación suya deja la integración muerta. Verificar con
GET /rest/api/3/myselfcon qué identidad se está actuando. Sin respuesta al 10-ago. - 🔴 Alcance de permisos: validado con
GET /rest/api/3/mypermissionspara FAC. El token puede navegar, crear, editar, transicionar, comentar, adjuntar y borrar tickets. Es un alcance excesivo para producción; la integración no debe implementar borrado y conviene migrar a una cuenta de servicio con permisos mínimos. - Vigencia 27-jul-2027 → dejar registrado el vencimiento y el plan de rotación desde ahora.
- Datos de clientes en adjuntos y descripciones — misma regla que BIND: nunca a disco del repo ni a documentos compartidos.
Bloque 8 — Preguntas para Pedro / Balam (no se resuelven con la API)
Cerradas con el correo del 7-ago:
¿Puede crear un proyecto de pruebas→ No. Prueba acompañada sobre un ticket (Noé, 7-ago).FACTEST?¿Debe observarse→ Todos los request types de la bandeja (Arturo, 4-ago). ⚠️ Con la salvedad del Bloque 1: 10 tickets no tienen request type ni campos.Facturación adicional(83),Facturación(12) u otro?¿Cuál estatus dispara la cotización?→En proceso de facturación(Arturo, 4-ago).¿Monto del adjunto o como campo?→ Campo de Jira. Ya implementado (customfield_11556), omitiendo recurrencia (Arturo, 4-ago).
Abiertas:
- 🔴 ¿De dónde salen los CONCEPTOS/partidas? El acuerdo resolvió el monto pero no los conceptos, y no existe campo para ellos en el sitio. ¿Cotización de una sola línea con el
summarycomo descripción, o se agrega un campo? - 🔴 ¿Qué pasa con los tickets creados por Automation for Jira (10 de 69, sin ningún campo estructurado, incluido
FAC-91que está vivo)? ¿Se acota la automatización o la regla de Automation propaga los campos? - 🔴 ACUNTIA /
FAC-100: ¿un ticket conMonto sin IVAúnico debe generar una cotización, o sigue siendo el caso de 40–48 facturas? - ¿Nacional vs extranjero cambia la cotización o solo el paquete de salida (PDF+XML vs PDF)? Hay dos estatus de validación distintos y una aprobación por cada rama.
- ¿Quién puede crear webhooks o reglas de Automation apuntando a una URL nuestra, y bajo qué proceso? Gana urgencia: el estatus disparador dura minutos (Bloque 3).
- PUE vs PPD — la pregunta que no se ha alcanzado a hacer en cuatro sesiones (REGISTRO #52). Los tickets
Seguimiento del Ticket con pago anticipado:sugieren que sí hay casos PUE reales. - Cuenta de servicio en lugar de la cuenta personal de Pedro, y fecha para la prueba acompañada.
Orden de ataque sugerido
| # | Acción | Bloqueado por |
|---|---|---|
| 1 | ✅ Blindar el token (.gitignore) — falta secrets/Key Vault |
— |
| 2 | ✅ Mapeo de campos y contratos de request type verificados (10-ago) | — |
| 3 | Implementar lectura con /search/jql, cursor y ventana de solape |
— |
| 4 | Detección por changelog del cruce a En proceso de facturación |
— (ya desbloqueado por el acuerdo del 4-ago) |
| 5 | Parser de ADF para Nombre del Cliente + match contra Clients de BIND |
⚠️ Sin RFC; definir tolerancia del match |
| 6 | Armado de la cotización BIND | 🔴 Definición de conceptos/partidas (pregunta 5) |
| 7 | Levantar un sandbox Jira propio (plan Free) | — (ya no depende de Balam) |
| 8 | Preparar y compartir el script de escritura mínimo para revisión | — |
| 9 | Ejecutar una única prueba de escritura acompañada | Fecha de Balam + script revisado + ticket acordado |
Lo que puede avanzar ya: el cliente de lectura, manejo de ADF, paginación por cursor, mapeo de campos, detección incremental por changelog y el sandbox propio. Lo único que sigue bloqueado es el armado final de la cotización, por la definición de conceptos. La escritura queda fuera del flujo automático hasta la sesión acompañada.
Briefing corto para desarrollo / revisión técnica
Contexto validado: Jira Cloud JSM en
balam-jsm-temp.atlassian.net; proyecto FAC company-managed (projectId: 10034,serviceDeskId: 35). La autenticación directa con Basicemail:tokenfunciona. El token tiene permisos de escritura amplios, pero no se debe ejecutar ningún POST, PUT o DELETE fuera de una prueba acompañada y aprobada.Para la capa de lectura, usar
GET /rest/api/3/search/jql, paginar pornextPageTokeny aplicar una ventana de solape al checkpoint deupdated. No usar/rest/api/3/search: responde 410.Para JSM, usar
/rest/servicedeskapial consultar request types y su contrato de campos. FAC publica 4 request types: Bajas (84), Facturación adicional (83), Automatización (389) y Facturación (12); los cuatro contratos están verificados. Facturación adicional (83) es el único con datos de facturación e incluyeMonto sin IVA(customfield_11556, number). No existe campo de conceptos/partidas en el sitio.El disparador acordado es el cruce a
En proceso de facturación, y dura minutos (FAC-100: 2m44s). La detección debe leer el changelog y buscar el cruce dentro de la ventana; consultar el estatus actual no sirve. Elissuetypeesadmon. El workflow tiene aprobaciones de JSM con Araceli como aprobadora en las ramas de validación nacional/extranjera: la plataforma nunca aprueba.10 de 69 tickets nacen de
Automation for Jiradesde HH/SA/IN/RH, sin request type y sin ningún campo estructurado; los datos van en elsummaryy ladescription(ADF), con el origen enissuelinks. Persistir elissue.idnumérico además de la llave.Pendientes técnicos: parser de ADF para
Nombre del Cliente(no trae RFC), armado de la cotización cuando se defina el tema de conceptos, y diseñar un script de escritura de una sola operación para revisión previa. El script debe ser idempotente, no incluir credenciales y ejecutarse únicamente en el sandbox propio o acompañado en el ticket de prueba acordado. No habráFACTEST.