{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "/schemas/3.1.0-rc.4/core/catchment.json",
  "title": "Catchment",
  "description": "A catchment area definition for a store or location. Defines the geographic area from which a store draws customers. Three methods are supported: isochrone inputs (travel time + transport mode, platform resolves the shape), simple radius (distance from location), or pre-computed GeoJSON geometry (buyer provides the exact boundary). Provide exactly one method per catchment.",
  "type": "object",
  "properties": {
    "catchment_id": {
      "type": "string",
      "description": "Identifier for this catchment, used to reference specific catchment areas in targeting (e.g., 'walk', 'drive', 'primary')."
    },
    "label": {
      "type": "string",
      "description": "Human-readable label for this catchment (e.g., '15-min drive', '1km walking radius')."
    },
    "travel_time": {
      "type": "object",
      "description": "Travel time limit for isochrone calculation. The platform resolves this to a geographic boundary based on actual transportation networks, accounting for road connectivity, transit schedules, and terrain.",
      "properties": {
        "value": {
          "type": "number",
          "minimum": 1,
          "description": "Travel time limit."
        },
        "unit": {
          "$ref": "/schemas/3.1.0-rc.4/enums/travel-time-unit.json"
        }
      },
      "required": ["value", "unit"],
      "additionalProperties": false
    },
    "transport_mode": {
      "$ref": "/schemas/3.1.0-rc.4/enums/transport-mode.json",
      "description": "Transportation mode for isochrone calculation. Required when travel_time is provided."
    },
    "radius": {
      "type": "object",
      "description": "Simple radius from the store location. The platform draws a circle of this distance around the store's coordinates.",
      "properties": {
        "value": {
          "type": "number",
          "exclusiveMinimum": 0,
          "description": "Radius distance."
        },
        "unit": {
          "$ref": "/schemas/3.1.0-rc.4/enums/distance-unit.json",
          "description": "Distance unit."
        }
      },
      "required": ["value", "unit"],
      "additionalProperties": false
    },
    "geometry": {
      "type": "object",
      "description": "Pre-computed GeoJSON geometry defining the catchment boundary. Use this when the buyer has already calculated isochrones (via TravelTime, Mapbox, etc.) or has custom trade area boundaries. Supports Polygon and MultiPolygon types.",
      "properties": {
        "type": {
          "type": "string",
          "enum": ["Polygon", "MultiPolygon"],
          "description": "GeoJSON geometry type."
        },
        "coordinates": {
          "type": "array",
          "description": "GeoJSON coordinates array. For Polygon: array of linear rings. For MultiPolygon: array of polygons."
        }
      },
      "required": ["type", "coordinates"],
      "additionalProperties": false
    },
    "ext": {
      "$ref": "/schemas/3.1.0-rc.4/core/ext.json"
    }
  },
  "required": ["catchment_id"],
  "oneOf": [
    {
      "required": ["travel_time", "transport_mode"],
      "not": {
        "anyOf": [
          { "required": ["radius"] },
          { "required": ["geometry"] }
        ]
      }
    },
    {
      "required": ["radius"],
      "not": {
        "anyOf": [
          { "required": ["travel_time"] },
          { "required": ["geometry"] }
        ]
      }
    },
    {
      "required": ["geometry"],
      "not": {
        "anyOf": [
          { "required": ["travel_time"] },
          { "required": ["radius"] }
        ]
      }
    }
  ],
  "additionalProperties": true,
  "examples": [
    {
      "description": "Isochrone: 15-minute drive",
      "data": {
        "catchment_id": "drive",
        "label": "15-min drive",
        "travel_time": { "value": 15, "unit": "min" },
        "transport_mode": "driving"
      }
    },
    {
      "description": "Isochrone: 10-minute walk",
      "data": {
        "catchment_id": "walk",
        "label": "10-min walk",
        "travel_time": { "value": 10, "unit": "min" },
        "transport_mode": "walking"
      }
    },
    {
      "description": "Simple 5km radius",
      "data": {
        "catchment_id": "local",
        "label": "5km radius",
        "radius": { "value": 5, "unit": "km" }
      }
    },
    {
      "description": "Pre-computed GeoJSON boundary",
      "data": {
        "catchment_id": "trade-area",
        "label": "Primary trade area",
        "geometry": {
          "type": "Polygon",
          "coordinates": [[[4.85, 52.35], [4.95, 52.35], [4.95, 52.40], [4.85, 52.40], [4.85, 52.35]]]
        }
      }
    }
  ]
}
