BE-07 Órdenes y máquina de estados
BE-07 — Órdenes y máquina de estados
Sección titulada «BE-07 — Órdenes y máquina de estados»- Depende de: BE-05, BE-06, US-06, US-08, DS-02.
- Módulo:
orders(hexagonal). - Relevo 2026-09-21: BE-06 está DONE. Mañana empezar aquí; no reimplementar webhooks.
Objetivo
Sección titulada «Objetivo»Implementar la orden como agregado con transiciones de estado válidas e inmutables en sus ítems.
Alcance
Sección titulada «Alcance»- Estados en spec: PENDING_PAYMENT, PAID, SHIPPED, CANCELLED. En código/BD el pendiente ya es
PENDING(ver relevo). - Al consumir
checkout.PaymentSucceeded(BE-06) la orden pasa a PAID y se emiteorders.OrderPaid. - Al consumir
checkout.PaymentFailedocancelMyOrderen pendiente: CANCELLED (el stock lo libera inventory / BE-06). - Puertos de cliente
listMyOrders,getMyOrder,cancelMyOrder. - Puertos admin
adminListOrders,adminUpdateOrderStatus.
Criterios de aceptación (DoD de esta tarea)
Sección titulada «Criterios de aceptación (DoD de esta tarea)»- Transición inválida = 409 ProblemDetail.
- Un cliente no accede a órdenes ajenas.
- Los ítems conservan precio snapshot.
OrderPaidse emite al pasar a PAID.
Fuera del DoD
Sección titulada «Fuera del DoD»- Validar la firma del webhook y persistir
webhook_events: BE-06 (DONE). - Relay outbox (
published_at, reintentos): BE-12. Los tests de esta tarea invocan el caso de uso de órdenes directo; el camino vivo webhook→PAID no cierra hasta BE-12. - UI de «Mis órdenes»: FE-07.
Evidencia para DONE
Sección titulada «Evidencia para DONE»Unitarias de la máquina de estados; integración de repositorio (incl. transiciones a PAID y 409).
Relevo para implementar (2026-09-21)
Sección titulada «Relevo para implementar (2026-09-21)»Arrancar con get_context(mode=task, taskId=BE-07).
Hecho ya (no rehacer):
- Checkout crea la orden en
PENDINGvíaCreatePendingOrderPort(ExposedOrderCreationAdapter). Enum real:PENDING,PAID,SHIPPED,DELIVERED,CANCELLED. Alinear el specPENDING_PAYMENTaPENDINGdel esquema; no duplicar estados en BD. order_items.unit_price_centsya es snapshot al crear la orden.- BE-06 ya confirma o libera la reserva en la misma transacción del webhook.
confirmReservationsolo toca filasPENDING(segundo call = no-op). Al pasar a PAID emitirorders.OrderPaid; no volver a decrementar stock. - Eventos a consumir (
outbox_events,aggregateType=checkout,published_atNULL):checkout.PaymentSucceeded→ JSONeventId,paymentId,orderId,amountCents,occurredAtcheckout.PaymentFailed→ JSONeventId,paymentId,orderId,reason,occurredAt
- No existe relay (BE-12).
OutboxEventPublishersolo inserta. El handler de órdenes se prueba sin relay; el E2E local (ngrok → webhook → orden PAID) queda bloqueado hasta despachar outbox. - OpenAPI (DS-02):
listMyOrders,getMyOrder,cancelMyOrder,adminListOrders,adminUpdateOrderStatus. - Runtime local: API :8081 perfil
local, Postgres :5433. Una orden de auditoría puede estarPENDINGcon pagoSUCCEEDED: ese hueco es esta tarea.