{
  "schema_version": 1,
  "diagram_type": "dataflow",
  "meta": {
    "title": "Topología de eventos de pedidos",
    "output": "examples/event-stream.html",
    "viewBox": [
      1080,
      780
    ],
    "animation": "trace",
    "visual_preset": "signal-flow",
    "quality_profile": "showcase",
    "views": [
      {
        "id": "order-transit",
        "label": "Recorrido del evento de pedido",
        "focus": [
          "checkout",
          "orders",
          "validate",
          "state",
          "fulfillment"
        ],
        "note": "Sigue un pedido desde su productor hasta el procesamiento ordenado y la entrega."
      },
      {
        "id": "payment-transit",
        "label": "Recorrido del evento de pago",
        "focus": [
          "billing",
          "payments",
          "enrich",
          "state",
          "analytics"
        ],
        "note": "Sigue los datos de pago hasta el estado materializado y la analítica."
      },
      {
        "id": "failure-and-replay",
        "label": "Errores y reprocesamiento",
        "focus": [
          "validate",
          "enrich",
          "dlq",
          "replay",
          "ops"
        ],
        "note": "Explora los mensajes fallidos, la revisión del operador y el reprocesamiento controlado."
      }
    ],
    "locale": "es"
  },
  "stages": [
    {
      "label": "Productores"
    },
    {
      "label": "Tránsito"
    },
    {
      "label": "Procesadores"
    },
    {
      "label": "Estado y recuperación"
    },
    {
      "label": "Consumidores"
    }
  ],
  "nodes": [
    {
      "id": "checkout",
      "type": "frontend",
      "label": "API de compras",
      "sublabel": "productor de pedidos",
      "stage": 0,
      "row": 0,
      "tag": "equipo comercial"
    },
    {
      "id": "billing",
      "type": "backend",
      "label": "API de cobros",
      "sublabel": "productor de pagos",
      "stage": 0,
      "row": 2,
      "tag": "equipo de pagos"
    },
    {
      "id": "orders",
      "type": "messagebus",
      "label": "orders.v1",
      "sublabel": "12 particiones",
      "stage": 1,
      "row": 0,
      "tag": "clave: order_id"
    },
    {
      "id": "payments",
      "type": "messagebus",
      "label": "payments.v2",
      "sublabel": "8 particiones",
      "stage": 1,
      "row": 2,
      "tag": "clave: order_id"
    },
    {
      "id": "validate",
      "type": "backend",
      "label": "Validar pedido",
      "sublabel": "grupo de entregas",
      "stage": 2,
      "row": 0,
      "tag": "ordenado"
    },
    {
      "id": "enrich",
      "type": "backend",
      "label": "Enriquecer pago",
      "sublabel": "grupo de analítica",
      "stage": 2,
      "row": 2,
      "tag": "al menos una vez"
    },
    {
      "id": "state",
      "type": "database",
      "label": "Estado de pedidos",
      "sublabel": "vista materializada",
      "stage": 3,
      "row": 1,
      "tag": "idempotente"
    },
    {
      "id": "dlq",
      "type": "messagebus",
      "label": "events.dlq",
      "sublabel": "eventos dañados",
      "stage": 3,
      "row": 4,
      "tag": "retención: 7 días"
    },
    {
      "id": "fulfillment",
      "type": "backend",
      "label": "Entrega",
      "sublabel": "flujo de envío",
      "stage": 4,
      "row": 0,
      "tag": "consumidor"
    },
    {
      "id": "analytics",
      "type": "database",
      "label": "Analítica",
      "sublabel": "datos en tiempo real",
      "stage": 4,
      "row": 2,
      "tag": "consumidor"
    },
    {
      "id": "replay",
      "type": "security",
      "label": "Reprocesar",
      "sublabel": "lote aprobado",
      "stage": 4,
      "row": 4,
      "tag": "control del operador"
    },
    {
      "id": "ops",
      "type": "external",
      "label": "De guardia",
      "sublabel": "responsable de DLQ",
      "stage": 4,
      "row": 3,
      "yOffset": -18,
      "tag": "SRE"
    }
  ],
  "flows": [
    {
      "from": "checkout",
      "to": "orders",
      "label": "OrderPlaced",
      "classification": "esquema v1",
      "variant": "emphasis",
      "route": "straight"
    },
    {
      "from": "billing",
      "to": "payments",
      "label": "PaymentCaptured",
      "classification": "esquema v2",
      "variant": "emphasis",
      "route": "straight"
    },
    {
      "from": "orders",
      "to": "validate",
      "label": "pedidos ordenados",
      "classification": "grupo consumidor",
      "variant": "emphasis",
      "route": "straight"
    },
    {
      "from": "payments",
      "to": "enrich",
      "label": "datos de pago",
      "classification": "al menos una vez",
      "variant": "emphasis",
      "route": "straight"
    },
    {
      "from": "validate",
      "to": "state",
      "label": "pedido válido",
      "classification": "idempotente",
      "variant": "emphasis",
      "route": "vertical-channel"
    },
    {
      "from": "enrich",
      "to": "state",
      "label": "pago enriquecido",
      "classification": "idempotente",
      "variant": "default",
      "route": "vertical-channel"
    },
    {
      "from": "state",
      "to": "fulfillment",
      "label": "pedidos listos",
      "classification": "modelo de lectura",
      "variant": "emphasis",
      "route": "vertical-channel"
    },
    {
      "from": "state",
      "to": "analytics",
      "label": "datos del pedido",
      "classification": "sin datos personales",
      "variant": "default",
      "route": "vertical-channel"
    },
    {
      "from": "validate",
      "to": "dlq",
      "label": "evento inválido",
      "classification": "mensaje fallido",
      "variant": "security",
      "fromSide": "top",
      "toSide": "top",
      "via": [
        [
          530,
          80
        ],
        [
          20,
          80
        ],
        [
          20,
          550
        ],
        [
          745,
          550
        ]
      ],
      "labelAt": [
        300,
        550
      ]
    },
    {
      "from": "enrich",
      "to": "dlq",
      "label": "evento dañado",
      "classification": "mensaje fallido",
      "variant": "security",
      "route": "bottom-channel",
      "labelDy": 30
    },
    {
      "from": "dlq",
      "to": "ops",
      "label": "muestra del error",
      "classification": "restringido",
      "variant": "security",
      "route": "vertical-channel"
    },
    {
      "from": "dlq",
      "to": "replay",
      "label": "reproceso aprobado",
      "classification": "lote auditado",
      "variant": "dashed",
      "route": "straight",
      "labelDy": 30
    }
  ],
  "cards": [
    {
      "dot": "amber",
      "title": "Reglas de tránsito",
      "items": [
        "Cada evento y tema tiene un nombre",
        "Las claves de partición conservan el orden de cada pedido",
        "Los grupos consumidores indican quién procesa los eventos"
      ]
    },
    {
      "dot": "emerald",
      "title": "Estado y entrega",
      "items": [
        "Los procesadores escriben en una vista materializada idempotente",
        "Las entregas y la analítica consumen datos distintos",
        "La entrega al menos una vez no debe duplicar efectos del negocio"
      ]
    },
    {
      "dot": "rose",
      "title": "Responsables de los errores",
      "items": [
        "Los eventos dañados se conservan en un tema de mensajes fallidos",
        "La persona de guardia revisa las muestras antes de reprocesar",
        "El reprocesamiento es autorizado, por lotes y auditable"
      ]
    }
  ]
}
