{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Markets Open daily calendar projection",
  "type": "object",
  "additionalProperties": false,
  "required": ["version", "data_version", "year", "scopes", "rows"],
  "properties": {
    "version": { "const": 1 },
    "data_version": { "type": "string", "minLength": 1 },
    "year": { "type": "integer", "minimum": 2024, "maximum": 2028 },
    "scopes": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": ["market_id", "scope", "time_zone", "coverage_start", "coverage_end", "source_urls"],
        "properties": {
          "market_id": { "enum": ["SSE", "HKEX", "NB", "SB"] },
          "scope": { "type": "string", "minLength": 1 },
          "time_zone": { "enum": ["Asia/Shanghai", "Asia/Hong_Kong"] },
          "coverage_start": { "type": "string", "format": "date" },
          "coverage_end": { "type": "string", "format": "date" },
          "source_urls": {
            "type": "array",
            "uniqueItems": true,
            "items": { "type": "string", "format": "uri" }
          }
        }
      }
    },
    "rows": {
      "type": "array",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": ["date", "market_id", "status", "is_trading_day", "is_half_day", "source_ids"],
        "properties": {
          "date": { "type": "string", "format": "date" },
          "market_id": { "enum": ["SSE", "HKEX", "NB", "SB"] },
          "status": { "enum": ["open", "closed", "half_day", "irregular", "unknown"] },
          "is_trading_day": { "type": ["boolean", "null"] },
          "is_half_day": { "type": ["boolean", "null"] },
          "source_ids": {
            "type": "array",
            "uniqueItems": true,
            "items": { "type": "string", "minLength": 1 }
          }
        },
        "allOf": [
          {
            "if": { "properties": { "status": { "const": "open" } }, "required": ["status"] },
            "then": { "properties": { "is_trading_day": { "const": true }, "is_half_day": { "const": false } } }
          },
          {
            "if": { "properties": { "status": { "const": "closed" } }, "required": ["status"] },
            "then": { "properties": { "is_trading_day": { "const": false }, "is_half_day": { "const": false } } }
          },
          {
            "if": { "properties": { "status": { "const": "half_day" } }, "required": ["status"] },
            "then": { "properties": { "is_trading_day": { "const": true }, "is_half_day": { "const": true } } }
          },
          {
            "if": { "properties": { "status": { "const": "irregular" } }, "required": ["status"] },
            "then": { "properties": { "is_trading_day": { "const": null }, "is_half_day": { "const": null } } }
          },
          {
            "if": { "properties": { "status": { "const": "unknown" } }, "required": ["status"] },
            "then": { "properties": { "is_trading_day": { "const": null }, "is_half_day": { "const": null }, "source_ids": { "maxItems": 0 } } }
          }
        ]
      }
    }
  }
}
