{
  "schemaVersion": "1.0",
  "integrationVersion": "1.0.0",
  "principles": {
    "businessStateSeparatedFromIntegrationState": true,
    "atLeastOnceRequiresIdempotency": true,
    "transientRetryOnly": true,
    "hangfireOwnsLongRetry": true,
    "pollyOwnsShortTransientResilience": true,
    "signalRIsNotSourceOfTruth": true,
    "terminalFailuresCreateOperationsException": true,
    "userNeverNeedsToRepeatBusinessCommandForIntegrationFailure": true
  },
  "states": [
    "queued",
    "delivering",
    "retrying",
    "delivered",
    "failed",
    "suspended"
  ],
  "integrations": [
    {
      "id": "integration.oms.wms.dispatch",
      "title": "OMS → WMS 출고지시 전달",
      "ownerModule": "OMS",
      "direction": "outbound",
      "transport": "outbox-http",
      "criticality": "high",
      "sourceEvent": "OrderShipmentRequested",
      "target": "WMS",
      "delivery": "at-least-once",
      "ordering": "per-aggregate",
      "idempotency": "event-id",
      "timeoutMs": 3000,
      "shortRetry": {
        "maxRetryAttempts": 2,
        "baseDelayMs": 250,
        "backoff": "exponential"
      },
      "longRetry": {
        "scheduler": "hangfire",
        "maxAttempts": 8,
        "scheduleSeconds": [
          10,
          30,
          120,
          300,
          900,
          1800,
          3600,
          7200
        ]
      },
      "circuitBreaker": {
        "failureRatio": 0.5,
        "samplingSeconds": 30,
        "minimumThroughput": 10,
        "breakSeconds": 30
      },
      "retryable": [
        "network",
        "timeout",
        "http-408",
        "http-429",
        "http-5xx",
        "circuit-open"
      ],
      "permanent": [
        "contract-invalid",
        "http-400",
        "http-401",
        "http-403",
        "http-404",
        "domain-rejected"
      ],
      "terminalAction": "operations-exception",
      "userVisible": true
    },
    {
      "id": "integration.wms.oms.picking-result",
      "title": "WMS → OMS 피킹결과 전달",
      "ownerModule": "WMS",
      "direction": "outbound",
      "transport": "outbox-http",
      "criticality": "high",
      "sourceEvent": "PickingCompleted",
      "target": "OMS",
      "delivery": "at-least-once",
      "ordering": "per-aggregate",
      "idempotency": "event-id",
      "timeoutMs": 3000,
      "shortRetry": {
        "maxRetryAttempts": 2,
        "baseDelayMs": 250,
        "backoff": "exponential"
      },
      "longRetry": {
        "scheduler": "hangfire",
        "maxAttempts": 8,
        "scheduleSeconds": [
          10,
          30,
          120,
          300,
          900,
          1800,
          3600,
          7200
        ]
      },
      "circuitBreaker": {
        "failureRatio": 0.5,
        "samplingSeconds": 30,
        "minimumThroughput": 10,
        "breakSeconds": 30
      },
      "retryable": [
        "network",
        "timeout",
        "http-408",
        "http-429",
        "http-5xx",
        "circuit-open"
      ],
      "permanent": [
        "contract-invalid",
        "http-400",
        "http-401",
        "http-403",
        "http-404",
        "domain-rejected"
      ],
      "terminalAction": "operations-exception",
      "userVisible": true
    },
    {
      "id": "integration.carrier.tracking",
      "title": "배송사 송장/배송상태 연계",
      "ownerModule": "OMS",
      "direction": "outbound",
      "transport": "outbox-http",
      "criticality": "medium",
      "sourceEvent": "TrackingSubmissionRequested",
      "target": "CarrierGateway",
      "delivery": "at-least-once",
      "ordering": "none",
      "idempotency": "business-key",
      "timeoutMs": 5000,
      "shortRetry": {
        "maxRetryAttempts": 2,
        "baseDelayMs": 500,
        "backoff": "exponential"
      },
      "longRetry": {
        "scheduler": "hangfire",
        "maxAttempts": 6,
        "scheduleSeconds": [
          30,
          120,
          600,
          1800,
          3600,
          7200
        ]
      },
      "circuitBreaker": {
        "failureRatio": 0.5,
        "samplingSeconds": 60,
        "minimumThroughput": 10,
        "breakSeconds": 60
      },
      "retryable": [
        "network",
        "timeout",
        "http-408",
        "http-429",
        "http-5xx",
        "circuit-open"
      ],
      "permanent": [
        "contract-invalid",
        "http-400",
        "http-401",
        "http-403",
        "http-404",
        "domain-rejected"
      ],
      "terminalAction": "operations-exception",
      "userVisible": true
    }
  ]
}
