{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://www.lastminuteslevy.cz/travel-feed.schema.json",
  "title": "LastMinuteSlevy.cz Travel Offer Feed",
  "description": "Minimální interoperabilní schéma konkrétních nabídek, termínů a mediálních dat zájezdů.",
  "type": "object",
  "required": ["generatedAt", "currencyDefault", "offers"],
  "properties": {
    "generatedAt": { "type": "string", "format": "date-time" },
    "fullSnapshot": { "type": "boolean", "default": true },
    "currencyDefault": { "type": "string", "pattern": "^[A-Z]{3}$" },
    "provider": {
      "type": "object",
      "required": ["id", "name"],
      "properties": {
        "id": { "type": "string", "minLength": 2, "maxLength": 100 },
        "name": { "type": "string", "minLength": 2, "maxLength": 200 },
        "website": { "type": "string", "format": "uri" },
        "market": { "type": "string", "pattern": "^[A-Z]{2}$" }
      },
      "additionalProperties": true
    },
    "offers": {
      "type": "array",
      "items": { "$ref": "#/$defs/offer" }
    }
  },
  "$defs": {
    "money": {
      "type": "object",
      "required": ["amount", "currency"],
      "properties": {
        "amount": { "type": "number", "exclusiveMinimum": 0 },
        "currency": { "type": "string", "pattern": "^[A-Z]{3}$" }
      },
      "additionalProperties": false
    },
    "media": {
      "type": "object",
      "required": ["url", "type"],
      "properties": {
        "url": { "type": "string", "format": "uri", "pattern": "^https?://" },
        "type": { "enum": ["image", "video", "map"] },
        "role": { "enum": ["cover", "gallery", "thumbnail", "map", "logo", "placeholder"] },
        "subject": {
          "enum": [
            "hotel", "room", "pool", "beach", "restaurant", "destination",
            "sport-event", "stadium", "map", "logo", "placeholder", "unknown"
          ]
        },
        "width": { "type": "integer", "minimum": 1, "maximum": 50000 },
        "height": { "type": "integer", "minimum": 1, "maximum": 50000 },
        "mimeType": { "type": "string", "maxLength": 100 },
        "alt": { "type": "string", "maxLength": 240 },
        "caption": { "type": "string", "maxLength": 500 },
        "sourceKind": {
          "type": "string",
          "minLength": 2,
          "maxLength": 100,
          "pattern": "^[a-z0-9][a-z0-9._-]*$",
          "description": "Strojově čitelný druh původu média. Hodnota je rozšiřitelná pro konkrétní partnerské feedy.",
          "examples": [
            "partner-feed", "radynacestu-feed", "hoska-tour-stovka-feed", "legacy-image",
            "detail-page-og", "detail-page-twitter", "detail-page-link", "detail-page-jsonld",
            "detail-page-img", "shared-media-catalog", "live-catalog-image", "manual", "legacy"
          ]
        },
        "sourceName": { "type": "string", "maxLength": 200 },
        "sourceUrl": { "type": "string", "format": "uri" },
        "rightsStatus": { "enum": ["unknown", "partner-provided", "licensed", "restricted"] },
        "rightsText": { "type": "string", "maxLength": 500 },
        "usage": { "enum": ["unknown", "catalog-only", "social-allowed", "restricted"] },
        "checkedAt": { "type": "string", "format": "date-time" },
        "qualityScore": { "type": "integer", "minimum": -100, "maximum": 100 },
        "usableAsCover": { "type": "boolean" }
      },
      "additionalProperties": true
    },
    "offer": {
      "type": "object",
      "required": ["id", "title", "country", "startDate", "nights", "price", "detailUrl", "availability"],
      "properties": {
        "id": { "type": "string", "minLength": 1, "maxLength": 200 },
        "tourId": { "type": "string", "maxLength": 200 },
        "termId": { "type": "string", "maxLength": 200 },
        "hotelId": { "type": "string", "maxLength": 200 },
        "title": { "type": "string", "minLength": 2, "maxLength": 300 },
        "hotelName": { "type": "string", "maxLength": 300 },
        "country": { "type": "string", "minLength": 2, "maxLength": 120 },
        "region": { "type": "string", "maxLength": 180 },
        "resort": { "type": "string", "maxLength": 180 },
        "latitude": { "type": "number", "minimum": -90, "maximum": 90 },
        "longitude": { "type": "number", "minimum": -180, "maximum": 180 },
        "startDate": { "type": "string", "format": "date" },
        "endDate": { "type": "string", "format": "date" },
        "nights": { "type": "integer", "minimum": 1, "maximum": 365 },
        "transport": { "enum": ["flight", "bus", "own", "train", "other"] },
        "departureCity": { "type": "string", "maxLength": 180 },
        "departureCode": { "type": "string", "maxLength": 10 },
        "board": { "type": "string", "maxLength": 180 },
        "roomType": { "type": "string", "maxLength": 240 },
        "adults": { "type": "integer", "minimum": 1, "maximum": 20 },
        "childrenAges": {
          "type": "array",
          "items": { "type": "integer", "minimum": 0, "maximum": 17 },
          "maxItems": 10
        },
        "price": { "$ref": "#/$defs/money" },
        "originalPrice": { "$ref": "#/$defs/money" },
        "priceType": { "enum": ["per-person", "total", "from"] },
        "availability": { "enum": ["available", "on-request", "limited", "sold-out", "unavailable", "cancelled"] },
        "availableUnits": { "type": "integer", "minimum": 0 },
        "priceCheckedAt": { "type": "string", "format": "date-time" },
        "updatedAt": { "type": "string", "format": "date-time" },
        "detailUrl": { "type": "string", "format": "uri", "pattern": "^https://" },
        "imageUrl": { "type": "string", "format": "uri" },
        "imageRights": { "type": "string", "maxLength": 300 },
        "mediaKey": { "type": "string", "minLength": 8, "maxLength": 120 },
        "media": {
          "type": "array",
          "items": { "$ref": "#/$defs/media" },
          "maxItems": 24
        },
        "includedServices": { "type": "array", "items": { "type": "string", "maxLength": 200 } },
        "baggage": { "type": "string", "maxLength": 300 },
        "transferIncluded": { "type": "boolean" },
        "cancellationUrl": { "type": "string", "format": "uri" },
        "termsUrl": { "type": "string", "format": "uri" },
        "organizerName": { "type": "string", "maxLength": 200 },
        "sellerName": { "type": "string", "maxLength": 200 }
      },
      "additionalProperties": true
    }
  },
  "additionalProperties": true
}
