{
  "description": "This is the interface description of @EntityRelationship.",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://sap.github.io/csn-interop-specification/spec-v1/entity-relationship.schema.json#",
  "title": "EntityRelationship Document",
  "type": "object",
  "definitions": {
    "@EntityRelationship.entityType": {
      "type": "string",
      "description": "Defines which [Entity Type](#entity-type) the current data object represents.\n\nThere could be several data objects that are assigned to the same Entity Type.\nOne data object can only have one Entity Type assigned, which corresponds to the applications own Entity Type definition.",
      "pattern": "^([a-z0-9-]+(?:[.][a-z0-9-]+)*):([a-zA-Z0-9._\\-]+)(:v[1-9][0-9]*)?$",
      "examples": [
        "sap.vdm.sont:BillOfMaterial"
      ],
      "x-extension-targets": [
        "Entity"
      ],
      "title": "@EntityRelationship.entityType"
    },
    "@EntityRelationship.propertyType": {
      "type": "string",
      "description": "Defines the logical [Property Type](#property-type) of a property.\nThe reason is to have an ID to relate to the property, especially to state that it can be used as an ID or is part of a composite ID.",
      "pattern": "^([a-z0-9-]+(?:[.][a-z0-9-]+)*):([a-zA-Z0-9._\\-]+)(:v[1-9][0-9]*)?$",
      "examples": [
        "sap.vdm.gfn:BillOfMaterialUUID"
      ],
      "x-extension-targets": [
        "Type"
      ],
      "title": "@EntityRelationship.propertyType"
    },
    "@EntityRelationship.entityIds": {
      "type": "array",
      "description": "Defines a list of IDs, which are available to look up the Entity Type or create a reference to it.\nAn Entity Type can have multiple IDs:\n* There can be **alternative IDs** that can also be used to create a reference to the Entity Type\n* Some ID properties form a **composite ID** together and need to be combined to function as a unique ID for references\n* This is indicated by a [`propertyTypes`](#property-type) array with more than one Property Type ID entry.",
      "items": {
        "$ref": "#/definitions/@EntityRelationship.EntityId"
      },
      "x-extension-targets": [
        "Entity"
      ],
      "title": "@EntityRelationship.entityIds"
    },
    "@EntityRelationship.reference": {
      "type": "array",
      "description": "Defines references to other Entity Types based on a single ID.",
      "items": {
        "$ref": "#/definitions/@EntityRelationship.ReferenceTarget"
      },
      "x-extension-targets": [
        "Type"
      ],
      "title": "@EntityRelationship.reference"
    },
    "@EntityRelationship.compositeReferences": {
      "type": "array",
      "description": "Defines one or many references to other Entity Types based on a composite IDs.",
      "items": {
        "$ref": "#/definitions/@EntityRelationship.CompositeReference"
      },
      "x-extension-targets": [
        "Entity"
      ],
      "title": "@EntityRelationship.compositeReferences"
    },
    "@EntityRelationship.temporalIds": {
      "type": "array",
      "description": "Defines a list of temporal IDs",
      "items": {
        "$ref": "#/definitions/@EntityRelationship.TemporalId"
      },
      "x-extension-targets": [
        "Entity"
      ],
      "title": "@EntityRelationship.temporalIds"
    },
    "@EntityRelationship.temporalReferences": {
      "type": "array",
      "description": "Defines a list of temporal references",
      "items": {
        "$ref": "#/definitions/@EntityRelationship.TemporalReference"
      },
      "x-extension-targets": [
        "Entity"
      ],
      "title": "@EntityRelationship.temporalReferences"
    },
    "@EntityRelationship.referencesWithConstantIds": {
      "type": "array",
      "description": "Defines one or many references to other Entity Types based on a composite IDs where some properties of the references are constant values.",
      "items": {
        "$ref": "#/definitions/@EntityRelationship.ReferenceTargetWithConstantId"
      },
      "x-extension-targets": [
        "Entity"
      ],
      "title": "@EntityRelationship.referencesWithConstantIds"
    },
    "@EntityRelationship.ReferenceTarget": {
      "title": "Reference Target",
      "type": "object",
      "description": "Defines a reference to another Entity Type based on a single ID.",
      "properties": {
        "name": {
          "type": "string",
          "description": "Optional name to describe the semantics of the reference."
        },
        "referencedEntityType": {
          "$ref": "#/definitions/@EntityRelationship.EntityTypeID"
        },
        "referencedPropertyType": {
          "$ref": "#/definitions/@EntityRelationship.PropertyTypeID"
        }
      },
      "required": [
        "referencedEntityType",
        "referencedPropertyType"
      ]
    },
    "@EntityRelationship.EntityId": {
      "title": "Entity ID",
      "type": "object",
      "description": "Defines an ID that can be used to look up the Entity Type or create a reference to it.",
      "properties": {
        "name": {
          "type": "string",
          "description": "Optional name to describe the semantics of the ID."
        },
        "description": {
          "type": "string",
          "description": "Optional description to describe the semantics of the ID."
        },
        "propertyTypes": {
          "type": "array",
          "description": "List of [Property Type](#property-type) IDs.",
          "items": {
            "$ref": "#/definitions/@EntityRelationship.PropertyTypeID"
          }
        }
      },
      "required": [
        "propertyTypes"
      ]
    },
    "@EntityRelationship.CompositeReference": {
      "title": "Composite Reference",
      "type": "object",
      "description": "Defines single a reference to another Entity Type based on a composite ID.",
      "properties": {
        "name": {
          "type": "string",
          "description": "Optional name to describe the semantics of the reference."
        },
        "referencedEntityType": {
          "$ref": "#/definitions/@EntityRelationship.EntityTypeID"
        },
        "referencedPropertyTypes": {
          "type": "array",
          "description": "List of properties, the composite ID consists of.",
          "items": {
            "$ref": "#/definitions/@EntityRelationship.ReferenceTargetPropertyType"
          }
        }
      },
      "required": [
        "referencedEntityType",
        "referencedPropertyTypes"
      ]
    },
    "@EntityRelationship.ReferenceTargetPropertyType": {
      "title": "Referenced Property Type",
      "type": "object",
      "description": "Grouping of the ID in the referenced entity, by its property type ID and the local name in this entity.",
      "properties": {
        "referencedPropertyType": {
          "$ref": "#/definitions/@EntityRelationship.PropertyTypeID"
        },
        "localPropertyName": {
          "$ref": "#/definitions/@EntityRelationship.LocalPropertyName"
        }
      },
      "required": [
        "referencedPropertyType",
        "localPropertyName"
      ]
    },
    "@EntityRelationship.TemporalId": {
      "title": "Temporal ID",
      "type": "object",
      "description": "Defines an ID that includes a temporal interval.",
      "properties": {
        "name": {
          "type": "string",
          "description": "Optional name to describe the semantics of the ID."
        },
        "description": {
          "type": "string",
          "description": "Optional description to describe the semantics of the ID."
        },
        "propertyTypes": {
          "type": "array",
          "description": "List of [Property Type](#property-type) IDs that are non-temporal.",
          "items": {
            "$ref": "#/definitions/@EntityRelationship.PropertyTypeID"
          }
        },
        "temporalIntervalType": {
          "$ref": "#/definitions/@EntityRelationship.TemporalIntervalType"
        },
        "temporalType": {
          "$ref": "#/definitions/@EntityRelationship.TemporalType"
        },
        "temporalIntervalStartProperty": {
          "$ref": "#/definitions/@EntityRelationship.LocalPropertyName",
          "description": "Property in the local entity that is used to define the start of the interval."
        },
        "temporalIntervalEndProperty": {
          "$ref": "#/definitions/@EntityRelationship.LocalPropertyName",
          "description": "Property in the local entity that is used to define the end of the interval."
        }
      },
      "required": [
        "propertyTypes",
        "temporalIntervalType",
        "temporalType",
        "temporalIntervalStartProperty",
        "temporalIntervalEndProperty"
      ]
    },
    "@EntityRelationship.TemporalReference": {
      "title": "Temporal Reference",
      "type": "object",
      "description": "Defines single temporal reference to another Entity Type.",
      "properties": {
        "name": {
          "type": "string",
          "description": "Optional name to describe the semantics of the reference."
        },
        "referencedEntityType": {
          "$ref": "#/definitions/@EntityRelationship.EntityTypeID"
        },
        "referencedPropertyTypes": {
          "type": "array",
          "description": "List of non-temporal properties the composite temporal ID consists of.",
          "items": {
            "$ref": "#/definitions/@EntityRelationship.ReferenceTargetPropertyType"
          }
        },
        "category": {
          "$ref": "#/definitions/@EntityRelationship.Category"
        },
        "selectionDateProperty": {
          "$ref": "#/definitions/@EntityRelationship.LocalPropertyName",
          "description": "Property in the local entity that is used to select the right date interval.\nIf omitted, the consumer determines the selection date/time based on context.\nCommon examples include the current date/time, the start of a fiscal quarter,\nor another use-case-specific point in time."
        }
      },
      "required": [
        "referencedEntityType",
        "referencedPropertyTypes",
        "category"
      ]
    },
    "@EntityRelationship.ReferenceTargetWithConstantId": {
      "title": "Reference with Constant ID",
      "type": "object",
      "description": "Defines single a reference to another Entity Type based on a composite ID.",
      "properties": {
        "name": {
          "type": "string",
          "description": "Optional name to describe the semantics of the reference."
        },
        "description": {
          "type": "string",
          "description": "Optional description to describe the semantics of the reference."
        },
        "referencedEntityType": {
          "$ref": "#/definitions/@EntityRelationship.EntityTypeID"
        },
        "referencedPropertyTypes": {
          "type": "array",
          "description": "List of properties, the composite ID consists of.",
          "items": {
            "$ref": "#/definitions/@EntityRelationship.ReferenceTargetPropertyTypeWithConstantId"
          }
        }
      },
      "required": [
        "referencedEntityType",
        "referencedPropertyTypes"
      ]
    },
    "@EntityRelationship.ReferenceTargetPropertyTypeWithConstantId": {
      "title": "Referenced Property Type with Constant ID",
      "type": "object",
      "description": "Grouping  of the ID in the referenced entity, by its property type ID and either the local name in this entity or a constant value.",
      "properties": {
        "referencedPropertyType": {
          "$ref": "#/definitions/@EntityRelationship.PropertyTypeID"
        },
        "localPropertyName": {
          "$ref": "#/definitions/@EntityRelationship.LocalPropertyName"
        },
        "constantValue": {
          "type": "string",
          "description": "String serialization of the constant value of the property in the referenced entity."
        }
      },
      "required": [
        "referencedPropertyType"
      ]
    },
    "@EntityRelationship.PropertyTypeID": {
      "title": "Property Type ID",
      "type": "string",
      "pattern": "^([a-z0-9-]+(?:[.][a-z0-9-]+)*):([a-zA-Z0-9._\\-]+)(:v[1-9][0-9]*)?$",
      "description": "ID of the [Property Type](#property-type). The reason is to have an ID to relate to the property, especially to state that it can be used as an ID or is part of a composite ID.",
      "examples": [
        "sap.vdm.gfn:BillOfMaterialUUID"
      ]
    },
    "@EntityRelationship.EntityTypeID": {
      "title": "Entity Type ID",
      "type": "string",
      "description": "ID of the [Entity Type](#entity-type).",
      "pattern": "^([a-z0-9-]+(?:[.][a-z0-9-]+)*):([a-zA-Z0-9._\\-]+)(:v[1-9][0-9]*)?$",
      "examples": [
        "sap.vdm.sont:BillOfMaterial"
      ]
    },
    "@EntityRelationship.LocalPropertyName": {
      "title": "Local Property Name",
      "type": "string",
      "description": "Name of the property in the local Entity Type"
    },
    "@EntityRelationship.TemporalIntervalType": {
      "title": "Temporal Interval Type",
      "type": "object",
      "description": "Interval which includes the boundaries.",
      "properties": {
        "#": {
          "type": "string",
          "description": "Provide the value in `{ \"#\": \"<value>\" }` enum notation.",
          "enum": [
            "CLOSED_CLOSED",
            "OPEN_OPEN",
            "OPEN_CLOSED",
            "CLOSED_OPEN"
          ]
        }
      },
      "additionalProperties": false,
      "required": [
        "#"
      ],
      "examples": [
        {
          "#": "CLOSED_CLOSED"
        }
      ]
    },
    "@EntityRelationship.TemporalType": {
      "title": "Temporal Type",
      "type": "object",
      "description": "Temporal type.",
      "properties": {
        "#": {
          "type": "string",
          "description": "Provide the value in `{ \"#\": \"<value>\" }` enum notation.",
          "enum": [
            "DATE",
            "DATETIME"
          ]
        }
      },
      "additionalProperties": false,
      "required": [
        "#"
      ],
      "examples": [
        {
          "#": "DATE"
        }
      ]
    },
    "@EntityRelationship.Category": {
      "title": "Category",
      "type": "object",
      "description": "Category of the temporal reference.",
      "properties": {
        "#": {
          "type": "string",
          "description": "Provide the value in `{ \"#\": \"<value>\" }` enum notation.",
          "enum": [
            "TEMPORAL_DATE"
          ]
        }
      },
      "additionalProperties": false,
      "required": [
        "#"
      ],
      "examples": [
        {
          "#": "TEMPORAL_DATE"
        }
      ]
    }
  },
  "examples": [
    {
      "csnInteropEffective": "1.2",
      "$version": "2.0",
      "definitions": {
        "BusinessPartner": {
          "kind": "entity",
          "@EntityRelationship.entityType": "sap.vdm.sont:BusinessPartner",
          "@EntityRelationship.entityIds": [
            {
              "name": "Semantic ID (composite ID)",
              "propertyTypes": [
                "sap.vdm.gfn:BusinessPartnerNumber",
                "sap.vdm.gfn:BusinessPartnerType"
              ]
            },
            {
              "name": "UUID (single property ID)",
              "propertyTypes": [
                "sap.vdm.gfn:BusinessPartnerUUID"
              ]
            }
          ],
          "elements": {
            "number": {
              "@EntityRelationship.propertyType": "sap.vdm.gfn:BusinessPartnerNumber",
              "key": true,
              "type": "cds.Integer"
            },
            "type": {
              "@EntityRelationship.propertyType": "sap.vdm.gfn:BusinessPartnerType",
              "key": true,
              "type": "cds.String"
            },
            "uuid": {
              "@EntityRelationship.propertyType": "sap.vdm.gfn:BusinessPartnerUUID",
              "type": "cds.UUID"
            }
          }
        }
      }
    },
    {
      "csnInteropEffective": "1.2",
      "$version": "2.0",
      "definitions": {
        "PurchaseOrder": {
          "kind": "entity",
          "@EntityRelationship.compositeReferences": [
            {
              "name": "Main Supplier",
              "referencedEntityType": "sap.vdm.sont:BusinessPartner",
              "referencedPropertyTypes": [
                {
                  "referencedPropertyType": "sap.vdm.gfn:BusinessPartnerNumber",
                  "localPropertyName": "mainSupplierNumber"
                },
                {
                  "referencedPropertyType": "sap.vdm.gfn:BusinessPartnerType",
                  "localPropertyName": "mainSupplierType"
                }
              ]
            }
          ],
          "elements": {
            "mainSupplierNumber": {
              "type": "cds.Integer"
            },
            "mainSupplierType": {
              "@EntityRelationship.propertyType": "sap.vdm.gfn:BusinessPartnerType",
              "type": "cds.String"
            },
            "alternativeSupplierUUID": {
              "@EntityRelationship.reference": [
                {
                  "referencedEntityType": "sap.vdm.sont:BusinessPartner",
                  "referencedPropertyType": "sap.vdm.gfn:BusinessPartnerUUID"
                }
              ],
              "type": "cds.UUID"
            }
          }
        }
      }
    }
  ]
}