{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "definitions": {
        "types": {
            "enum": [
                "Float",
                "Boolean",
                "Date",
                "DateTime",
                "Integer",
                "Short",
                "Counter",
                "Duration",
                "Number",
                "Text",
                "Time",
                "URL",
                "Language",
                "Model",
                "Guid",
                "Object",
                "NegativeInteger",
                "NegativeNumber",
                "NonNegativeInteger",
                "NonNegativeNumber",
                "NonPositiveInteger",
                "NonPositiveNumber",
                "PositiveInteger",
                "PositiveNumber",
                "Email",
                "AbsoluteURI",
                "RelativeURI"
            ]
        },
        "unknownTypes": {
            "not": {
                "$ref": "#/definitions/types"
            }
        }
    },
    "id": "https://themost-framework.github.io/themost/models/2018/2/schema.json",
    "properties": {
        "@id": {
            "description": "A string which represents a literal unique identifier for this model e.g. https://example.com/models/User",
            "type": "string"
        },
        "abstract": {
            "default": false,
            "description": "A boolean which indicates whether this model is an abstract model or not. The default value is false.",
            "type": "boolean"
        },
        "caching": {
            "default": "none",
            "description": "A boolean which indicates whether model data will be cached or not. The default value is none -no caching-. A conditional caching allows developers to control caching mechanism while fetching data.",
            "enum": [
                "none",
                "always",
                "conditional"
            ],
            "type": "string"
        },
        "classPath": {
            "description": "A string which represents a module path that exports a class which maps this database model e.g. './models/some-model'",
            "type": "string"
        },
        "constraints": {
            "items": {
                "properties": {
                    "description": {
                        "description": "A short description for this constraint e.g. Unique identifier field must be unique across different records.",
                        "type": "string"
                    },
                    "fields": {
                        "items": {
                            "type": "string"
                        },
                        "type": "array"
                    },
                    "type": {
                        "description": "A string which represents the type of this constraint e.g. unique",
                        "enum": [
                            "unique"
                        ],
                        "type": "string"
                    }
                },
                "required": [
                    "type"
                ],
                "type": "object"
            },
            "type": "array"
        },
        "eventListeners": {
            "items": {
                "properties": {
                    "name": {
                        "description": "A string which the name of this event listener e.g. update person user listener",
                        "type": "string"
                    },
                    "type": {
                        "description": "A string which represents the path of the module that exports this listener. This path may be a relative to execution folder path of a module exists in package modules e.g. ./listeners/add-user-listener or my-module/send-mail-listener",
                        "type": "string"
                    }
                },
                "required": [
                    "type"
                ],
                "type": "object"
            },
            "type": "array"
        },
        "fields": {
            "items": {
                "properties": {
                    "@id": {
                        "description": "A string which represents a literal unique identifier for this attribute e.g. https://example.com/models/attributes/name",
                        "type": "string"
                    },
                    "calculation": {
                        "description": "An expression which represents the calculated value for this attribute.",
                        "type": "string"
                    },
                    "description": {
                        "description": "A string which represents a short description of this attribute",
                        "type": "string"
                    },
                    "editable": {
                        "default": false,
                        "description": "A boolean which indicates whether this attribute is editable or not.",
                        "type": "boolean"
                    },
                    "expandable": {
                        "default": false,
                        "description": "A boolean value which indicates whether the associated object(s) will be automatically expanded or not.",
                        "type": "boolean"
                    },
                    "indexed": {
                        "default": false,
                        "description": "A boolean which indicates whether this attribute is an indexed column or not.",
                        "type": "boolean"
                    },
                    "many": {
                        "description": "A boolean value which indicates whether this attribute represents an one-to-many or many-to-many association between two models.",
                        "type": "boolean"
                    },
                    "mapping": {
                        "properties": {
                            "associationAdapter": {
                                "type": "string"
                            },
                            "associationObjectField": {
                                "type": "string"
                            },
                            "associationType": {
                                "enum": [
                                    "association",
                                    "junction"
                                ],
                                "type": "string"
                            },
                            "associationValueField": {
                                "type": "string"
                            },
                            "cascade": {
                                "enum": [
                                    "delete",
                                    "none"
                                ],
                                "type": "string"
                            },
                            "childField": {
                                "type": "string"
                            },
                            "childModel": {
                                "type": "string"
                            },
                            "options": {
                                "properties": {
                                    "$expand": {
                                        "description": "The set of expanded entities can be further refined through the application of expand options, expressed as a semicolon-separated list of system query options.",
                                        "type": "string"
                                    },
                                    "$levels": {
                                        "description": "The value of the $levels system query option is a positive integer to specify the number of levels to expand e.g. $levels=2",
                                        "type": "string"
                                    },
                                    "$orderby": {
                                        "description": "The $orderby system query option specifies the order in which items are returned from the service. e.g. $orderby=dateCreated desc",
                                        "type": "string"
                                    },
                                    "$select": {
                                        "description": "The $select system query option requests that the service return only the properties, dynamic properties requested by the client e.g. $select=id,name,dateCreated",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            },
                            "parentField": {
                                "type": "string"
                            },
                            "parentModel": {
                                "type": "string"
                            },
                            "privileges": {
                                "items": {
                                    "properties": {
                                        "account": {
                                            "description": "A string which represents the name of the security group where this privilege will be applied e.g. Administrators, Sales etc.",
                                            "type": "string"
                                        },
                                        "filter": {
                                            "description": "A string which represents a filter expression for this privilege. This attribute is used for self privileges which are commonly derived from user's attributes e.g. 'owner eq me()' or 'orderStatus eq 1 and customer eq me()' etc.",
                                            "type": "string"
                                        },
                                        "mask": {
                                            "default": 1,
                                            "description": "A number which represents permission mask (1=Read, 2=Create, 4=Update, 8=Delete, 16=Execute)",
                                            "maximum": 31,
                                            "minimum": 0,
                                            "type": "number"
                                        },
                                        "type": {
                                            "description": "A string which represents the permission scope.",
                                            "enum": [
                                                "self",
                                                "global",
                                                "parent",
                                                "item"
                                            ],
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "mask",
                                        "type"
                                    ],
                                    "type": "object"
                                },
                                "type": "array"
                            }
                        },
                        "type": "object"
                    },
                    "name": {
                        "description": "A string which represents the name of this attribute e.g. title, description, dateCreated etc",
                        "type": "string"
                    },
                    "nested": {
                        "default": false,
                        "description": "A boolean which indicates whether this attribute defines an association between two models where child objects are always treated as a part of the parent object.",
                        "type": "boolean"
                    },
                    "nullable": {
                        "default": true,
                        "description": "A boolean which indicates whether this attribute is nullable or not.",
                        "type": "boolean"
                    },
                    "primary": {
                        "description": "A boolean which indicates whether this attribute is a key column or not.",
                        "type": "boolean"
                    },
                    "property": {
                        "description": "A string which optionally represents the name of this attribute in object mapping. This name may defer from the name of the database field.",
                        "type": "string"
                    },
                    "readonly": {
                        "default": false,
                        "description": "A boolean which indicates whether this attribute is readonly or not. A readonly value must have a default value or a calculated value.",
                        "type": "boolean"
                    },
                    "size": {
                        "description": "A number which represents the maximum size for this attribute e.g. the size of a text field etc",
                        "type": "number"
                    },
                    "title": {
                        "description": "A string which represents a title for this attribute e.g. Date Created etc",
                        "type": "string"
                    },
                    "type": {
                        "description": "A string which represents the type of this attribute e.g. Counter, Integer, Number, Text etc",
                        "oneOf": [
                            {
                                "$ref": "#/definitions/types"
                            },
                            {
                                "$ref": "#/definitions/unknownTypes"
                            }
                        ],
                        "type": "string"
                    },
                    "validation": {
                        "description": "Defines a data validator for this attribute",
                        "properties": {
                            "maxLength": {
                                "description": "Sets a value which represents the max allowed length.",
                                "type": "integer"
                            },
                            "maxValue": {
                                "description": "Sets a value which represents the max value."
                            },
                            "message": {
                                "description": "A string which represents a message that is going to be used when validation fails.",
                                "type": "string"
                            },
                            "minLength": {
                                "description": "Sets a value which represents the min length.",
                                "type": "integer"
                            },
                            "minValue": {
                                "description": "Sets a value which represents the min value."
                            },
                            "pattern": {
                                "description": "A string which represents a regular expression that validates values of this attribute.",
                                "type": "string"
                            },
                            "patternMessage": {
                                "description": "A string which represents a message that is going to be used when pattern validation fails.",
                                "type": "string"
                            },
                            "type": {
                                "description": "Defines a validation against a pre-defined data type e.g. PositiveInteger, URL etc",
                                "oneOf": [
                                    {
                                        "$ref": "#/definitions/types"
                                    },
                                    {
                                        "$ref": "#/definitions/unknownTypes"
                                    }
                                ],
                                "type": "string"
                            },
                            "validator": {
                                "description": "A string which represetns the module path that exports a custom validator e.g. ./validators/custom-validator.js",
                                "type": "string"
                            }
                        },
                        "type": "object"
                    },
                    "value": {
                        "description": "An expression which represents the default value for this attribute.",
                        "type": "string"
                    }
                },
                "required": [
                    "name"
                ],
                "type": "object"
            },
            "type": "array"
        },
        "hidden": {
            "default": false,
            "description": "A boolean which indicates whether this model is hidden or not. The default value is false.",
            "type": "boolean"
        },
        "id": {
            "description": "An optional numeric identifier for this model e.g. 9587891",
            "type": "number"
        },
        "implements": {
            "description": "A string which represents the model which is implemented by this model e.g. ActionStatusType model implements Enumeration model etc",
            "type": "string"
        },
        "inherits": {
            "description": "A string which represents the model which is inherited by this model e.g. User inherits Account, Person inherits Party etc",
            "type": "string"
        },
        "name": {
            "description": "A string which represents the name of this model e.g. Order, Customer, Person etc",
            "type": "string"
        },
        "privileges": {
            "items": {
                "properties": {
                    "account": {
                        "description": "A string which represents the name of the security group where this privilege will be applied e.g. Administrators, Sales etc.",
                        "type": "string"
                    },
                    "filter": {
                        "description": "A string which represents a filter expression for this privilege. This attribute is used for self privileges which are commonly derived from user's attributes e.g. 'owner eq me()' or 'orderStatus eq 1 and customer eq me()' etc.",
                        "type": "string"
                    },
                    "mask": {
                        "default": 1,
                        "description": "A number which represents permission mask (1=Read, 2=Create, 4=Update, 8=Delete, 16=Execute)",
                        "maximum": 31,
                        "minimum": 0,
                        "type": "number"
                    },
                    "type": {
                        "description": "A string which represents the permission scope.",
                        "enum": [
                            "self",
                            "global",
                            "parent",
                            "item"
                        ],
                        "type": "string"
                    }
                },
                "required": [
                    "mask",
                    "type"
                ],
                "type": "object"
            },
            "type": "array"
        },
        "sealed": {
            "default": false,
            "description": "A boolean which indicates whether this model is being upgraded automatically or not. The default value is false.",
            "type": "boolean"
        },
        "seed": {
            "items": {
                "type": "object"
            },
            "type": "array"
        },
        "source": {
            "description": "A string which holds the database object of this model. If this property is missing the database object's name is the concatenation of the model's name and the keyword 'Base' e.g. UserBase, PersonBase etc",
            "type": "string"
        },
        "title": {
            "description": "A string which represents the title of this e.g. Supplier Orders, Person Followers etc",
            "type": "string"
        },
        "version": {
            "default": "1.0",
            "description": "A string which represents the version of the model's schema. This version is going to be used in model upgrade operations e.g. 1.0, 0.1.2 etc",
            "pattern": "^[0-9]+\\.[0-9]+(\\.[0-9]+)?$",
            "type": "string"
        },
        "view": {
            "description": "A string which holds the database object that is going to be used for fetching data. If this property is missing this database object's name is the concatenation of the model's name and the keyword 'Data' e.g. UserData, PersonData etc",
            "type": "string"
        },
        "views": {
            "items": {
                "properties": {
                    "fields": {
                        "items": {
                            "properties": {
                                "description": {
                                    "description": "A string which represents a short description of this attribute",
                                    "type": "string"
                                },
                                "editable": {
                                    "default": false,
                                    "description": "A boolean which indicates whether this attribute is editable or not.",
                                    "type": "boolean"
                                },
                                "expandable": {
                                    "default": false,
                                    "description": "A boolean value which indicates whether the associated object(s) will be automatically expanded or not.",
                                    "type": "boolean"
                                },
                                "mapping": {
                                    "properties": {
                                        "options": {
                                            "properties": {
                                                "$expand": {
                                                    "description": "string\n(query)\t\nThe set of expanded entities can be further refined through the application of expand options, expressed as a semicolon-separated list of system query options.",
                                                    "type": "string"
                                                },
                                                "$levels": {
                                                    "description": "The value of the $levels option is a positive integer to specify the number of levels to expand e.g. $levels=2",
                                                    "type": "string"
                                                },
                                                "$orderby": {
                                                    "description": "The $orderby system Query option specifies the order in which items are returned from the service. e.g. $orderby=dateCreated desc",
                                                    "type": "string"
                                                },
                                                "$select": {
                                                    "description": "The $select system query option requests that the service return only the properties, dynamic properties requested by the client e.g. $select=id,name,dateCreated",
                                                    "type": "string"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    },
                                    "type": "object"
                                },
                                "name": {
                                    "description": "A string which represents the name of this attribute e.g. title, description, dateCreated etc",
                                    "type": "string"
                                },
                                "property": {
                                    "description": "A string which optionally represents the name of this attribute in object mapping. This name may defer from the name of the database field.",
                                    "type": "string"
                                },
                                "title": {
                                    "description": "A string which represents a title for this attribute e.g. Date Created etc",
                                    "type": "string"
                                }
                            },
                            "required": [
                                "name"
                            ],
                            "type": "object"
                        },
                        "type": "array"
                    },
                    "filter": {
                        "description": "A string which represents a $filter system query option which is going to be used by default for this data view",
                        "type": "string"
                    },
                    "group": {
                        "description": "A string which represents a $groupby system query option which is going to be used for this data view",
                        "type": "string"
                    },
                    "levels": {
                        "description": "A positive number which represents a $levels system query option which is going to be used for this data view",
                        "type": "number"
                    },
                    "name": {
                        "description": "A string which represents the name of this data view e.g. MyCustomView",
                        "type": "string"
                    },
                    "order": {
                        "description": "A string which represents a $orderby system query option which is going to be used for this data view",
                        "type": "string"
                    },
                    "public": {
                        "description": "A boolean which indicates whether this data view is public or not. The default value is true.",
                        "type": "boolean"
                    },
                    "select": {
                        "description": "A string which represents a $select system query option which is going to be used for this data view",
                        "type": "string"
                    },
                    "title": {
                        "description": "A string which represents the title of this data view e.g. MyCustomView",
                        "type": "string"
                    }
                },
                "required": [
                    "name"
                ],
                "type": "object"
            },
            "type": "array"
        }
    },
    "required": [
        "name",
        "title",
        "version"
    ],
    "type": "object"
}