Componentes
Flujo de una entrega
1
Publicar (dentro de la petición)
Toda ruta que pasa por el wrapper compartido
handler()/ok() invoca
publishApiTransactionEvent tras un 2xx. El publisher deriva el
internal del catálogo a partir del método y la ruta, y comprueba el
conjunto en memoria de internals que hoy tienen al menos un suscriptor
activo. Si nadie escucha, no se encola nada — las tablas de cola
quedan vacías para las miles de mutaciones a las que nadie se suscribió.
Los fallos aquí se registran y nunca llegan al cliente de la API.2
Route (webhook-out-route)
El consumidor carga la fila del catálogo, resuelve la cuenta propietaria
del recurso mutado (ver abajo) y selecciona los webhooks coincidentes:
los globales siempre coinciden; los de cuenta solo cuando la cuenta
resuelta es igual a su
account. Se inserta una fila webhook_dispatch
por coincidencia con status = pending y se envía un mensaje
webhook-out-deliver por fila.3
Deliver (webhook-out-deliver)
El consumidor construye el cuerpo fino, lo firma con el secreto del
suscriptor, hace el
POST con timeout de 10 s y redirect: "error", y
registra el resultado (success, error con next_retry_at o
exhausted) en la fila del libro mayor. Los fallos reintentables se
reprograman con el backoff propio; ver
Reintentos y fallos.Resolución de la cuenta propietaria
Las suscripciones por cuenta necesitan saber a qué cuenta pertenece la fila mutada. El catálogo registra una de cuatro estrategias por evento:
El resolutor lee la fila una vez, en la etapa route; las entregas nunca
vuelven a tocar la tabla origen.
Lanes y planificación
Ambos topics corren en el lane dedicadowebhook-out (vercel.json →
app/api/queue/consumers/webhook-out/route.ts), de modo que una ráfaga de
entregas no puede dejar sin recursos a los jobs de negocio, ni un atasco de
negocio retrasar la notificación a un suscriptor. El topic deliver usa un
calendario de reintentos propio en lugar del predeterminado de la
plataforma: el backoff que ve el suscriptor forma parte del contrato público.
Feature flag
La publicación está condicionada porENABLE_API_EVENT_QUEUE. Mientras sea
false la API se comporta exactamente como antes: sin consulta al catálogo,
sin caché, sin tráfico de cola. Operaciones lo activa por entorno tras
sincronizar el catálogo y probar el primer suscriptor; ver
Operación.