ADR-025: cómo recibe el OMS la dirección de entrega sin sacar datos personales a Kafka
Aceptado el 15/11/2026 por Andrés con la opción A (propuesto el 11/11/2026 por el agente; toca la regla 2 de `CLAUDE.md` y ADR-010). Complementa ADR-010 (gRPC pasa de un punto a dos). Sin implementar al 15/11/2026; hasta entonces el registro en el OMS sale sin dirección.
Contexto
El OMS legado necesita la dirección de entrega y el contacto para despachar. Esos datos viven solo en order-service, cifrados por campo (docs/to-be/02-dominios-y-servicios.md, 08-seguridad.md). La regla 5 prohíbe datos personales en eventos, y el comando CreateOmsOrder viaja por Kafka. El contrato ya da la dirección de la respuesta, en la descripción de OrderEvent: "Quien necesite la dirección la pide a order-service con el orderId". Pero no dice por qué vía, y ninguna operación la ofrece. Hoy (carril f4-oms-webhooks) la orden se registra en el OMS sin dirección.
Las opciones chocan con alguna regla: la 1 (solo los adaptadores hablan con el legado), la 2 (la única llamada síncrona interna es de order-service a inventory-service) o la 5 (ningún dato personal en eventos).
Opciones
| Opción | A favor | En contra |
|---|---|---|
A. Ticket de reclamo (claim check): el comando lleva solo orderId; oms-adapter pide la dirección a order-service por gRPC (GetFulfillmentDetails), autorizado solo para su identidad de carga |
Los datos personales nunca tocan Kafka; un solo dueño; con mTLS y AuthorizationPolicy, solo oms-adapter llega; patrón conocido (Claim Check, de Enterprise Integration Patterns) |
Una segunda llamada síncrona interna, que pide ampliar ADR-010; el registro en el OMS depende de que order-service responda (se reintenta como cualquier fallo) |
B. La dirección va en el comando, cifrada con una llave que solo oms-adapter puede descifrar |
Sigue asíncrono, sin llamada nueva | Datos personales, aunque cifrados, en un tópico con retención de días y en sus reintentos y DLQ; rompe la letra de la regla 5; borrar un dato exige rotar o destruir la llave |
C. order-service registra la orden en el OMS directamente |
Sin piezas nuevas | Rompe la regla 1: un servicio de dominio habla con el legado |
D. El OMS toma la dirección del CRM por customerId |
Sin datos personales en la capa | Una compra sin cuenta no tiene cliente en el CRM, y la dirección de una orden no es la del perfil |
Decisión propuesta
Opción A.
order-serviceexpone el servicio gRPC internoandesretail.orders.v1.FulfillmentDetails/GetFulfillmentDetails(orderId), que devuelve el destinatario, la dirección y el contacto de la orden, descifrados en memoria y nunca escritos en el log.- Acceso: solo la identidad de carga de
oms-adapterllega a esa operación, por la AuthorizationPolicy de la malla (platform/mesh/) y por una segunda comprobación en el servicio. - El adaptador la llama al procesar
CreateOmsOrder, entrega la dirección al OMS y no la guarda. Siorder-serviceno responde, el comando sigue la política de reintento y DLQ del contrato. - Registro: cada lectura queda en
andes.audit.v1, con quién, qué orden y cuándo, sin los datos. - ADR-010: gRPC pasa de "un solo punto" a dos: order-service hacia inventory-service, y oms-adapter hacia order-service para este dato.
Qué se sacrifica
- Una dependencia síncrona más: el registro en el OMS espera a
order-service. Como el registro ya es asíncrono y tolera horas (ADR-004, OMS caído), el efecto es un reintento más, no una orden perdida. - Un contrato gRPC nuevo que mantener.
- La regla 2 queda con una excepción explícita, además de la de inventory.
Si Andrés no la aprueba
Mientras no haya decisión, el registro en el OMS sale sin dirección, y eso es un hueco del demo que el entregable debe decir. La alternativa de menor costo es B, que exige reescribir la regla 5 como "ningún dato personal en claro".