{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://www.rucksackrebellen.de/schema/tour.json",
  "title": "Rucksackrebellen tours",
  "description": "All tours published on rucksackrebellen.de with their key facts. Facts are taken from the articles; missing values are omitted, never guessed.",
  "type": "object",
  "required": ["version", "source", "license", "count", "tours"],
  "properties": {
    "$schema": { "type": "string" },
    "version": { "const": 1 },
    "generated": { "type": "string", "format": "date" },
    "source": { "type": "string", "format": "uri" },
    "license": { "type": "string" },
    "count": { "type": "integer", "minimum": 0 },
    "tours": { "type": "array", "items": { "$ref": "#/$defs/tour" } }
  },
  "$defs": {
    "tour": {
      "type": "object",
      "required": ["title", "url", "markdown_url", "route", "region", "country", "published"],
      "properties": {
        "title": { "type": "string" },
        "url": { "type": "string", "format": "uri", "description": "Canonical article URL" },
        "markdown_url": { "type": "string", "format": "uri", "description": "Markdown version of the article" },
        "summary": { "type": "string" },
        "published": { "type": "string", "format": "date" },
        "updated": { "type": "string", "format": "date" },
        "route": { "enum": ["rundweg", "streckenwanderung", "hin-und-zurueck"], "description": "Loop, point-to-point or out-and-back" },
        "distance_km": { "type": "number", "exclusiveMinimum": 0 },
        "ascent_m": { "type": "number", "minimum": 0, "description": "Total ascent in metres" },
        "duration_h": { "type": "number", "exclusiveMinimum": 0, "description": "Walking time in hours" },
        "max_elevation_m": { "type": "number", "description": "Highest point in metres above sea level" },
        "difficulty": { "enum": ["leicht", "mittel", "schwer"], "description": "Easy, moderate, hard (authors' judgement)" },
        "region": { "type": "string" },
        "country": { "type": "string", "pattern": "^[A-Z]{2}$", "description": "ISO 3166-1 alpha-2" },
        "season": { "type": "array", "items": { "enum": ["frühling", "sommer", "herbst", "winter"] } },
        "finish": { "type": "string" },
        "start": {
          "type": "object",
          "required": ["name", "lat", "lon"],
          "properties": {
            "name": { "type": "string" },
            "lat": { "type": "number", "minimum": -90, "maximum": 90 },
            "lon": { "type": "number", "minimum": -180, "maximum": 180 },
            "approximate": { "type": "boolean", "description": "True when the coordinates are rounded to about 1 km" }
          }
        },
        "gpx": { "type": "string", "description": "File name of the GPX track" },
        "gpx_url": { "type": "string", "format": "uri" },
        "komoot": { "type": "string" },
        "komoot_url": { "type": "string", "format": "uri" },
        "route_image": { "type": "string", "format": "uri" }
      },
      "additionalProperties": false
    }
  }
}
