{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Data Source Approval Contract",
  "description": "Master contract for external data source approval, SLA, and lineage",
  "version": "1.0",
  "type": "object",
  "required": ["sources", "metadata"],
  "properties": {
    "metadata": {
      "type": "object",
      "required": ["version", "owner", "approved_date", "approval_status"],
      "properties": {
        "version": { "type": "string", "example": "1.0" },
        "owner": { "type": "string", "example": "Data Governance Team" },
        "approved_date": { "type": "string", "format": "date", "example": "2026-08-07" },
        "approval_status": { "type": "string", "enum": ["APPROVED", "PENDING", "REJECTED"], "example": "APPROVED" },
        "last_updated": { "type": "string", "format": "date-time" }
      }
    },
    "sources": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "required": ["id", "name", "type", "url", "frequency", "sla"],
        "properties": {
          "id": { "type": "string", "description": "Unique source ID", "example": "krx-openapi-001" },
          "name": { "type": "string", "example": "KRX OpenAPI" },
          "type": { "type": "string", "enum": ["external_rest", "external_soap", "internal_form", "internal_db", "computed"], "example": "external_rest" },
          "url": { "type": "string", "format": "uri", "example": "https://openapi.krx.co.kr" },
          "authentication": {
            "type": "object",
            "required": ["method", "credential_key"],
            "properties": {
              "method": { "type": "string", "enum": ["api_key", "oauth2", "jwt", "basic_auth", "none"], "example": "api_key" },
              "credential_key": { "type": "string", "description": "Secret manager key", "example": "KRX_OPENAPI_KEY" },
              "rate_limit": { "type": "string", "example": "1000 req/day" }
            }
          },
          "frequency": {
            "type": "object",
            "required": ["schedule", "unit"],
            "properties": {
              "schedule": { "type": "string", "enum": ["real_time", "hourly", "daily", "weekly", "monthly", "on_demand"], "example": "daily" },
              "unit": { "type": "string", "example": "T+0 EOD" },
              "import_delay_sla": { "type": "string", "description": "Max acceptable delay", "example": "<4 hours" }
            }
          },
          "sla": {
            "type": "object",
            "required": ["availability", "support_hours"],
            "properties": {
              "availability": { "type": "string", "example": "99.5%" },
              "support_hours": { "type": "string", "example": "Weekdays 9 AM-5 PM KST" },
              "incident_contact": { "type": "string", "example": "support@krx.co.kr" },
              "escalation": { "type": "string", "example": "Operations Manager" }
            }
          },
          "retention": {
            "type": "object",
            "required": ["hot_storage", "cold_storage", "archive"],
            "properties": {
              "hot_storage": { "type": "integer", "description": "Days in primary DB", "example": 365 },
              "cold_storage": { "type": "integer", "description": "Days before archival", "example": 730 },
              "archive": { "type": "integer", "description": "Total retention years", "example": 5 }
            }
          },
          "fallback_strategy": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "object",
              "required": ["priority", "source", "description"],
              "properties": {
                "priority": { "type": "integer", "minimum": 1, "example": 1 },
                "source": { "type": "string", "enum": ["live_api", "cache", "snapshot", "manual"], "example": "live_api" },
                "description": { "type": "string", "example": "Live API call to KRX endpoint" },
                "max_age": { "type": "string", "description": "Max acceptable data age", "example": "1 trading day" }
              }
            }
          },
          "data_quality_rules": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "rule_name": { "type": "string", "example": "no_null_prices" },
                "condition": { "type": "string", "example": "volume >= 0 AND high >= low" },
                "severity": { "type": "string", "enum": ["critical", "warning", "info"], "example": "critical" }
              }
            }
          },
          "consumers": {
            "type": "array",
            "items": { "type": "string", "example": "signal_engine" }
          },
          "owner": { "type": "string", "example": "KRX" },
          "approved_by": { "type": "string", "example": "Data Governance Lead" }
        }
      }
    },
    "error_classification": {
      "type": "object",
      "description": "Retry and fallback rules for different error types",
      "properties": {
        "transient": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "error_code": { "type": "string", "example": "429" },
              "description": { "type": "string", "example": "Rate limit exceeded" },
              "retry_delay_ms": { "type": "integer", "example": 60000 },
              "max_attempts": { "type": "integer", "example": 3 }
            }
          }
        },
        "permanent": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "error_code": { "type": "string", "example": "400" },
              "description": { "type": "string", "example": "Bad request" },
              "action": { "type": "string", "enum": ["alert", "quarantine", "manual_review"], "example": "alert" }
            }
          }
        }
      }
    }
  }
}
