- v1 · current
- v0 · deprecated
Estás viendo el contrato actual (v1) de
store.business_day_closed — un payload thin: identidad del cierre, timing, closedBy y una store mínima. Ya no arrastra las métricas agregadas del día, los breakdowns ni el detalle de anomalías — eso lo consultás por businessDayId cuando lo necesites.store.business_day_closed dispara cuando el pipeline automático de cierre de día de Fire termina de construir el snapshot inmutable del día operativo de una tienda. El payload es thin: lleva la identidad del cierre (businessDayId), el timing, quién lo cerró y una ref mínima de tienda — lo suficiente para reaccionar a “el día cerró” y matchearlo de tu lado. Los agregados pesados (ventas, métricas, breakdowns por canal/pago, detalle de force-closed y cancelaciones) viven en el snapshot y se obtienen por businessDayId — no vienen embebidos en el evento.
A diferencia de los eventos a nivel orden, este es un evento a nivel tienda: uno por tienda cerrada, no uno por orden.
Condición de disparo
Fire emitestore.business_day_closed una vez por snapshot (storeId, businessDayDate), la primera vez que todo lo siguiente es verdadero:
- La tienda tenía un día de negocio abierto (
isBusinessDayOpen === true) para la fecha que se cierra - El pipeline de cierre (
CloseBusinessDayService.execute()) completó todos los pasos sin error (force-close, cálculo de métricas, persistencia del snapshot) - No existe ya un snapshot para ese par
(storeId, businessDayDate)(guard de idempotencia)
| Cobertura | Universal — todos los países. Sin gating por país. |
| Llave de idempotencia | event.id (también trigger.data.businessDayId) |
| Dispara más de una vez | No, salvo reintento. Un snapshot por (storeId, fecha). |
| Origen | Pipeline cron (v1). El cierre manual aún no emite. |
| Latencia vs cierre real | Síncrono — el evento se encola apenas saveSnapshot() retorna. |
Qué hay en trigger.data
Un payload thin: identidad (businessDayId, businessDayDate, timezone, status), timing (openedAt, closedAt), el closedBy resuelto, y una ref mínima de store (uid, code, externalId, countryCode, timezone, currencyCode). Sin métricas, breakdowns ni arrays de anomalías — consultá el snapshot por businessDayId si necesitás el detalle.
Ejemplo — payload real (sanitizado)
Referencia de data.*
Identidad y temporal
UUID del snapshot de día de negocio persistido en la base de Fire. También aparece como
_meta.triggerEntityId. Usalo como llave de idempotencia de tu lado — los reenvíos del mismo cierre comparten el mismo businessDayId — y como llave de lookup para traer los agregados del día desde la API de snapshots de Fire cuando los necesites.Fecha calendario que representa el cierre, en la timezone de la tienda (ej.
"2026-03-31"). No la fecha UTC en que disparó el evento.Timezone IANA de la tienda (ej.
"America/Sao_Paulo"). Usala para interpretar businessDayDate.Siempre
"CLOSED" para este evento. No hay otro valor posible.Timestamp ISO 8601 UTC de apertura del día. Puede ser
null para tiendas que nunca abrieron explícitamente (data legacy); para tiendas cerradas por cron v1 siempre está presente.Timestamp ISO 8601 UTC en que el pipeline persistió el snapshot. Usalo para medir SLI/SLO en vez de
event.createdAt (que es el momento del dispatch de la cola).closedBy — identidad del operador
Identidad del operador ya resuelta. Sin lookups en runtime downstream.
store — ref mínima de tienda
Una referencia mínima de tienda — identidad más país/timezone/moneda. El bloque store canónico completo (name, address, vendor, account, fiscal config) no viene acá; si lo necesitás, tomalo de los eventos
order.completed de la misma tienda.Ejemplo de handler
Errores comunes
- Las métricas del día NO están en este evento.
sales,metrics,byChannel,byPaymentMethod,forceClosedOrders,closureStats,cancelledOrdersymetadataya no viajan inline. Si dependías de ellos, traé el snapshot porbusinessDayId. snapshotIdse renombró abusinessDayId. Si parseabasdata.snapshotId, cambiá adata.businessDayId(mismo valor — el id de la fila del snapshot).closedBy.uidpuede ser el nil UUID"00000000-0000-0000-0000-000000000000"— en cierres system donde la cuenta no configuró un system user. Detectá cierres system conclosedBy.type === "system", no parseando eluid.businessDayDatees la fecha calendario de la tienda, no UTC. Interpretala contimezone.- Los campos
store.*pueden sernullante configuración de tienda incompleta. No asumas non-null.
Eventos relacionados
order.completed
Dispara por cada orden al completarse. El bloque store completo vive acá.
order.cancelled
Evento por cancelación. Usalo para el detalle de cancelaciones en vez del payload de cierre.

