{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://rctp.dev/schemas/term-set.schema.json",
  "title": "Term set",
  "description": "The terms a category takes, their types, visibility and constraints (Draft 0.5 6.2; binding 4.1). Every term set includes floor and available_until. v0.2 accepts only the registered term names, so every term has a closed field in listing-terms.",
  "type": "object",
  "properties": {
    "id": {
      "$ref": "common.schema.json#/$defs/TermSetId"
    },
    "title": {
      "type": "string",
      "minLength": 1,
      "maxLength": 140
    },
    "terms": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/TermDefinition"
      },
      "minItems": 2,
      "allOf": [
        {
          "contains": {
            "type": "object",
            "properties": {
              "term": {
                "const": "floor"
              }
            },
            "required": [
              "term"
            ]
          }
        },
        {
          "contains": {
            "type": "object",
            "properties": {
              "term": {
                "const": "available_until"
              }
            },
            "required": [
              "term"
            ]
          }
        }
      ]
    }
  },
  "additionalProperties": false,
  "required": [
    "id",
    "terms"
  ],
  "$defs": {
    "TermName": {
      "type": "string",
      "enum": [
        "floor",
        "available_until",
        "fulfillment_options",
        "payment_terms",
        "release_condition",
        "deliver_within_days",
        "counterparty_requirements",
        "deposit_pct",
        "inspection_before_deposit",
        "required_observation"
      ],
      "description": "A registered term name (Draft 0.5 6.2)"
    },
    "TermType": {
      "type": "string",
      "enum": [
        "money",
        "date-time",
        "integer",
        "percent",
        "boolean",
        "fulfillment_options",
        "payment_terms",
        "release_condition",
        "counterparty_requirements",
        "required_observation"
      ]
    },
    "TermDefinition": {
      "type": "object",
      "properties": {
        "term": {
          "$ref": "#/$defs/TermName"
        },
        "type": {
          "$ref": "#/$defs/TermType"
        },
        "visibility": {
          "type": "string",
          "enum": [
            "private",
            "public"
          ],
          "description": "private terms never leave the platform (INV-1)"
        },
        "required": {
          "type": "boolean",
          "description": "Whether the term must have a value; the marketplace may fill a public term from its category defaults (Draft 0.5 6.2)"
        },
        "constraints": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/Constraint"
          },
          "minItems": 1
        }
      },
      "additionalProperties": false,
      "required": [
        "term",
        "type",
        "visibility",
        "required"
      ],
      "description": "One term. Its type and visibility are fixed by the Draft 0.5 6.2 table.",
      "allOf": [
        {
          "if": {
            "properties": {
              "term": {
                "const": "floor"
              }
            },
            "required": [
              "term"
            ]
          },
          "then": {
            "properties": {
              "type": {
                "const": "money"
              },
              "visibility": {
                "const": "private"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "term": {
                "const": "available_until"
              }
            },
            "required": [
              "term"
            ]
          },
          "then": {
            "properties": {
              "type": {
                "const": "date-time"
              },
              "visibility": {
                "const": "public"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "term": {
                "const": "fulfillment_options"
              }
            },
            "required": [
              "term"
            ]
          },
          "then": {
            "properties": {
              "type": {
                "const": "fulfillment_options"
              },
              "visibility": {
                "const": "public"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "term": {
                "const": "payment_terms"
              }
            },
            "required": [
              "term"
            ]
          },
          "then": {
            "properties": {
              "type": {
                "const": "payment_terms"
              },
              "visibility": {
                "const": "public"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "term": {
                "const": "release_condition"
              }
            },
            "required": [
              "term"
            ]
          },
          "then": {
            "properties": {
              "type": {
                "const": "release_condition"
              },
              "visibility": {
                "const": "public"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "term": {
                "const": "deliver_within_days"
              }
            },
            "required": [
              "term"
            ]
          },
          "then": {
            "properties": {
              "type": {
                "const": "integer"
              },
              "visibility": {
                "const": "public"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "term": {
                "const": "counterparty_requirements"
              }
            },
            "required": [
              "term"
            ]
          },
          "then": {
            "properties": {
              "type": {
                "const": "counterparty_requirements"
              },
              "visibility": {
                "const": "public"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "term": {
                "const": "deposit_pct"
              }
            },
            "required": [
              "term"
            ]
          },
          "then": {
            "properties": {
              "type": {
                "const": "percent"
              },
              "visibility": {
                "const": "public"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "term": {
                "const": "inspection_before_deposit"
              }
            },
            "required": [
              "term"
            ]
          },
          "then": {
            "properties": {
              "type": {
                "const": "boolean"
              },
              "visibility": {
                "const": "public"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "term": {
                "const": "required_observation"
              }
            },
            "required": [
              "term"
            ]
          },
          "then": {
            "properties": {
              "type": {
                "const": "required_observation"
              },
              "visibility": {
                "const": "public"
              }
            }
          }
        }
      ]
    },
    "Constraint": {
      "type": "object",
      "properties": {
        "op": {
          "type": "string",
          "enum": [
            "min",
            "max",
            "gt_term",
            "lt_term",
            "lte_list_price",
            "min_ratio_of_list_price"
          ],
          "description": "The closed constraint set of Draft 0.4 6.2"
        },
        "value": {
          "type": "number",
          "description": "For min and max, the bound; for min_ratio_of_list_price, a ratio in (0, 1]"
        },
        "term": {
          "$ref": "#/$defs/TermName"
        }
      },
      "additionalProperties": false,
      "required": [
        "op"
      ],
      "description": "Terms that break a constraint are refused terms_invalid before the seller can approve them. min, max and min_ratio_of_list_price take value; gt_term and lt_term take term; lte_list_price takes neither.",
      "allOf": [
        {
          "if": {
            "properties": {
              "op": {
                "enum": [
                  "min",
                  "max",
                  "min_ratio_of_list_price"
                ]
              }
            },
            "required": [
              "op"
            ]
          },
          "then": {
            "required": [
              "value"
            ],
            "not": {
              "required": [
                "term"
              ]
            }
          }
        },
        {
          "if": {
            "properties": {
              "op": {
                "enum": [
                  "gt_term",
                  "lt_term"
                ]
              }
            },
            "required": [
              "op"
            ]
          },
          "then": {
            "required": [
              "term"
            ],
            "not": {
              "required": [
                "value"
              ]
            }
          }
        },
        {
          "if": {
            "properties": {
              "op": {
                "const": "lte_list_price"
              }
            },
            "required": [
              "op"
            ]
          },
          "then": {
            "not": {
              "anyOf": [
                {
                  "required": [
                    "value"
                  ]
                },
                {
                  "required": [
                    "term"
                  ]
                }
              ]
            }
          }
        },
        {
          "if": {
            "properties": {
              "op": {
                "const": "min_ratio_of_list_price"
              }
            },
            "required": [
              "op"
            ]
          },
          "then": {
            "properties": {
              "value": {
                "type": "number",
                "exclusiveMinimum": 0,
                "maximum": 1
              }
            }
          }
        }
      ]
    }
  }
}
