{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://curbi.io/developers/policy.v1.schema.json",
  "title": "Curbi Check policy v1",
  "description": "What a business has approved. Interface to the Check API implementation; the API is the authority and this schema mirrors its validation.",
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "name": {
      "type": "string"
    },
    "description": {
      "type": "string"
    },
    "prices": {
      "type": "array",
      "maxItems": 50,
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "item"
        ],
        "properties": {
          "item": {
            "$ref": "#/$defs/phrase"
          },
          "amount": {
            "$ref": "#/$defs/amount"
          },
          "amounts": {
            "type": "array",
            "minItems": 1,
            "maxItems": 8,
            "items": {
              "$ref": "#/$defs/amount"
            }
          },
          "aliases": {
            "type": "array",
            "maxItems": 8,
            "items": {
              "$ref": "#/$defs/phrase"
            }
          }
        },
        "oneOf": [
          {
            "required": [
              "amount"
            ],
            "not": {
              "required": [
                "amounts"
              ]
            }
          },
          {
            "required": [
              "amounts"
            ],
            "not": {
              "required": [
                "amount"
              ]
            }
          }
        ]
      }
    },
    "forbid": {
      "type": "array",
      "maxItems": 50,
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "phrases"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[a-z0-9-]{1,40}$"
          },
          "phrases": {
            "type": "array",
            "minItems": 1,
            "maxItems": 20,
            "items": {
              "$ref": "#/$defs/phrase"
            },
            "description": "Literal text, never a regular expression. Matched whole-word, case-insensitive, after Unicode normalization; simple inflections (s, es, d, ed, ing) also match."
          },
          "why": {
            "type": "string",
            "maxLength": 200
          },
          "negatable": {
            "type": "boolean",
            "default": true
          },
          "match": {
            "type": "string",
            "enum": [
              "word",
              "prefix"
            ],
            "default": "word"
          }
        }
      }
    },
    "actions": {
      "type": "object",
      "maxProperties": 40,
      "propertyNames": {
        "pattern": "^[a-z]{2,20}$"
      },
      "additionalProperties": {
        "type": "string",
        "minLength": 1,
        "maxLength": 60
      },
      "description": "Past-tense verb -> operation, e.g. {\"booked\": \"calendar.book\"}."
    },
    "discounts": {
      "type": "array",
      "maxItems": 20,
      "description": "Approved discounts. A claimed \"N% off\" (or half price, buy one get one) passes only when listed; the discounted price then counts as approved. Without items, the discount applies to every priced item.",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "percent"
        ],
        "properties": {
          "percent": {
            "type": "number",
            "exclusiveMinimum": 0,
            "maximum": 100
          },
          "items": {
            "type": "array",
            "minItems": 1,
            "maxItems": 50,
            "items": {
              "type": "string",
              "minLength": 1
            },
            "description": "Names from policy.prices[].item."
          }
        }
      }
    },
    "unknownAmounts": {
      "enum": [
        "flag",
        "allow"
      ],
      "default": "flag"
    }
  },
  "$defs": {
    "phrase": {
      "type": "string",
      "minLength": 1,
      "maxLength": 80,
      "pattern": "[^\\s\\u00ad\\u034f\\u061c\\u115f\\u1160\\u17b4\\u17b5\\u180b-\\u180f\\u200b-\\u200f\\u202a-\\u202e\\u2060-\\u206f\\u3164\\ufe00-\\ufe0f\\ufeff\\uffa0]"
    },
    "amount": {
      "type": "number",
      "minimum": 0
    }
  }
}
