{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://reqview.com/schemas/2.22/document.json",
  "title": "ReqView Document File",

  "type": "object",
  "properties": {
    "id": {
      "description": "Human readable unique ID of the document chosen by user",
      "$ref": "common.json#/definitions/fileName"
    },
    "guid": {
      "description": "Globally unique ID of the document",
      "$ref": "common.json#/definitions/guid"
    },
    "name": {
      "description": "Document name string",
      "$ref": "common.json#/definitions/nonEmptyString"
    },
    "createdOn": {
      "description": "Date of creation in ISO format",
      "$ref": "common.json#/definitions/timeStamp"
    },
    "createdBy": {
      "description": "Initial author of the document",
      "$ref": "common.json#/definitions/user"
    },
    "lastChangedOn": {
      "description": "Date of last modification in ISO format",
      "$ref": "common.json#/definitions/timeStamp"
    },
    "lastChangedBy": {
      "description": "Author of the last modification",
      "$ref": "common.json#/definitions/user"
    },
    "lastId": {
      "description": "ID of the last created object in the document",
      "type": "number",
      "minimum": 0
    },
    "helpRef": {
      "description": "Name of the source document of the instructions text",
      "$ref": "common.json#/definitions/nonEmptyString"
    },
    "url": {
      "description": "URL of the instructions text",
      "type": "string",
      "format": "uri"
    },
    "copyright": {
      "description": "Copyright notice(s) of the instructions author",
      "type": "array",
      "uniqueItems": true,
      "items": { "$ref": "common.json#/definitions/nonEmptyString" }
    },
    "metadata": {
      "description": "Document file metadata storing information about the data format version",
      "type": "object",
      "properties": {
        "format": {
          "description": "Data format version string",
          "$ref": "common.json#/definitions/nonEmptyString"
        }
      }
    },
    "attributes": {
      "description": "Set of custom document attributes",
      "type": "object",
      "additionalProperties": {
        "type": "object",
        "properties": {
          "type": {
            "description": "Data type of document attribute values",
            "type": "string",
            "enum": ["int", "bool", "string", "date", "real", "enum", "xhtml"]
          },
          "name": {
            "description": "Optional long attribute name displayed in the column header",
            "$ref": "common.json#/definitions/nonEmptyString",
            "examples": ["Supplier Status"]
          },
          "readOnly": {
            "description": "Set to true the user should be prevented from changing the attribute value",
            "type": "boolean"
          },
          "help": {
            "description": "Set to true if the attribute value should be displayed as read-only instructions in a separate pane",
            "type": "boolean"
          },
          "values": {
            "description": "For enumeration attributes stores array of allowed values",
            "type": "array",
            "uniqueItems": true,
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "description": "Unique key of the enumeration value",
                  "$ref": "common.json#/definitions/nonEmptyString",
                  "examples": ["FEA", "FRQ", "CON"]
                },
                "label": {
                  "description": "Optional text label",
                  "$ref": "common.json#/definitions/nonEmptyString",
                  "examples": ["Feature", "Functional Requirement", "Constraint"]
                },
                "default": {
                  "description": "Set to true if the enumeration value should be used as the default value",
                  "type": "boolean"
                }
              },
              "required": ["key"]
            }
          },
          "multiValued": {
            "description": "Set to true for multivalued enumeration attributes",
            "type": "boolean"
          },
          "hint": {
            "description": "Optional suggestions for the attribute value displayed as a placeholder in the column editor or as a column head hint",
            "type": "string"
          }
        },
        "dependencies": {
          "help": {
            "properties": {
              "type": { "const": "xhtml" }
            }
          }
        },
        "required": ["type"]
      }
    },
    "data": {
      "description": "Array of top level document objects",
      "type": "array",
      "items": { "$ref": "#/definitions/docObj" }
    },
    "templateColumns": {
      "description": "Set of custom document template columns",
      "type": "object",
      "additionalProperties": {
        "type": "object",
        "properties": {
          "label": {
            "description": "Optional text label",
            "type": "string"
          },
          "template": {
            "description": "For template columns stores the template text",
            "type": "string"
          }
        },
        "required": ["label", "template"]
      }
    },
    "views": {
      "description": "Set of document views (table views)",
      "type": "object",
      "additionalProperties": {
        "type": "object",
        "properties": {
          "columns": {
            "type": "array",
            "uniqueItems": true,
            "items": {
              "type": "object",
              "properties": {
                "hidden": {
                  "description": "Set to true for columns which should not be displayed (deprecated)",
                  "type": "boolean"
                },
                "width": {
                  "description": "Column width in pixels",
                  "type": "number",
                  "exclusiveMinimum": 0
                },
                "columnId": {
                  "description": "For attribute columns stores the attribute ID",
                  "$ref": "common.json#/definitions/nonEmptyString"
                },
                "templateColumnId": {
                  "description": "For template columns stores the template column ID",
                  "$ref": "common.json#/definitions/nonEmptyString"
                }
              }
            }
          },
          "default": {
            "description": "Set to true if view will be used as a default view",
            "type": "boolean"
          },
          "filter": {
            "description": "Filter specification",
            "type": "array"
          },
          "sort": {
            "description": "Sort specification",
            "type": "object",
            "properties": {
              "columnId": {
                "description": "ID of the column used for sorting",
                "type": "string"
              },
              "descending": {
                "description": "Sorting order flag",
                "type": "boolean"
              }
            }
          },
          "numFrozenCols": {
            "description": "Number of frozen columns",
            "type": "number",
            "exclusiveMinimum": 0
          }
        }
      }
    },
    "properties": {
      "description": "Document properties entered by a user.",
      "type": "object"
    },
    "integrations": {
      "description": "3rd party integrations config",
      "type": "object",
      "$ref": "common.json#/definitions/integrationsBase",
      "properties": {
        "jira": {
          "description": "Jira integration config",
          "type": "object"
        },
        "reqif": {
          "description": "ReqIF integration config",
          "type": "object"
        }
      }
    },
    "rtl": {
      "description": "Use RTL as the default text direction",
      "type": "boolean"
    }
  },
  "required": ["id"],

  "definitions": {
    "docObj": {
      "title": "ReqView Document Object",
      "description": "Document object representing a document section, requirement, risk, test, ...",
      "type": "object",
      "properties": {
        "id": {
          "description": "Unique document object ID assigned automatically by the application",
          "$ref": "common.json#/definitions/numberString"
        },
        "guid": {
          "description": "Globally unique ID of the document object",
          "$ref": "common.json#/definitions/guid"
        },
        "heading": {
          "description": "For sections stores the heading of the section",
          "type": "string",
          "examples": ["Introduction", "User Stories"]
        },
        "text": {
          "description": "Text description of the related requirement, test, risk, etc.",
          "type": "string",
          "examples": ["User shall be able to save projects as JSON files"]
        },
        "deleted": {
          "description": "Set to true if the document object is marked as deleted",
          "type": "boolean"
        },
        "children": {
          "description": "Array of children document objects in the document tree hierarchy",
          "type": "array",
          "items": { "$ref": "#/definitions/docObj" }
        },
        "attachments": {
          "description": "Array of referenced attachment IDs",
          "type": "array",
          "uniqueItems": true,
          "items": { "$ref": "common.json#/definitions/nonEmptyString" }
        },
        "links": {
          "description": "Object storing links to other objects grouped by link type",
          "type": "object",
          "additionalProperties": {
            "type": "array",
            "uniqueItems": true,
            "items": {
              "oneOf": [
                { "$ref": "#/definitions/projDocObjId" },
                { "$ref": "#/definitions/suspectLink" }
              ]
            }
          }
        },
        "origin": { "$ref": "#/definitions/suspectLink" },
        "history": {
          "description": "Array of change records storing date, author and further information for each change of the document object",
          "type": "array",
          "uniqueItems": true,
          "items": {
            "type": "object",
            "properties": {
              "changedOn": {
                "description": "Date and time of the change",
                "$ref": "common.json#/definitions/timeStamp"
              },
              "changedBy": {
                "description": "Author of the change",
                "$ref": "common.json#/definitions/user"
              },
              "attributesChanged": {
                "description": "Set of changed attributes",
                "type": "object"
              },
              "addedAttachment": {
                "description": "ID of the added attachment",
                "$ref": "common.json#/definitions/nonEmptyString"
              },
              "updatedAttachment": {
                "description": "ID of the updated attachment",
                "type": "object",
                "properties": {
                  "newAttachmentId": { "$ref": "common.json#/definitions/nonEmptyString" },
                  "oldAttachmentId": { "$ref": "common.json#/definitions/nonEmptyString" }
                },
                "required": ["newAttachmentId", "oldAttachmentId"]
              },
              "removedAttachment": { "$ref": "common.json#/definitions/nonEmptyString" },
              "commentGuid": {
                "description": "Globally unique ID of the edited comment",
                "$ref": "common.json#/definitions/guid"
              },
              "commentIndex": {
                "description": "Index of the edited or deleted comment (deprecated)",
                "type": "number"
              },
              "commentAuthor": {
                "description": "Author of the deleted comment (deprecated for added and edited comment change)",
                "$ref": "common.json#/definitions/user"
              },
              "commentDate": {
                "description": "Date and time of the deleted comment (deprecated for added and edited comment change)",
                "$ref": "common.json#/definitions/timeStamp"
              },
              "updatedComment": {
                "description": "Previous text of the edited comment or null for the added comment",
                "anyOf": [
                 {"$ref": "common.json#/definitions/nonEmptyString"},
                 {"type": "null"}
                ]
              },
              "removedComment": {
                "description": "Text of the deleted comment",
                "$ref": "common.json#/definitions/nonEmptyString"
              },
              "addedComment": {
                "description": "Text of the added comment (deprecated)",
                "$ref": "common.json#/definitions/nonEmptyString"
              },
              "editLastComment": {
                "description": "Previous text of the edited comment (deprecated)",
                "$ref": "common.json#/definitions/nonEmptyString"
              },
              "deleteLastComment": {
                "description": "Text of the deleted comment (deprecated)",
                "$ref": "common.json#/definitions/nonEmptyString"
              },
              "resolvedComment": {
                "description": "The comment has been resolved or reopened",
                "type": "boolean"
              },
              "addedLink": {
                "description": "Type and target of the added traceability link",
                "$ref": "#/definitions/historyLink"
              },
              "removedLink": {
                "description": "Type and target of the removed traceability link",
                "$ref": "#/definitions/historyLink"
              },
              "changedLink": {
                "description": "Type and targets of the changed traceability link",
                "type": "object",
                "properties": {
                  "oldType": {
                    "description": "Old link type",
                    "$ref": "common.json#/definitions/nonEmptyString"
                  },
                  "oldTargets": {
                    "description": "Old link targets",
                    "$ref": "#/definitions/linkTargets"
                  },
                  "newType": {
                    "description": "New link type",
                    "$ref": "common.json#/definitions/nonEmptyString"
                  },
                  "newTargets": {
                    "description": "New link targets. Items - links match those in oldTargets.",
                    "$ref": "#/definitions/linkTargets"
                  }
                },
                "required": ["oldType", "oldTargets"]
              },
              "clearedLinkSuspect": {
                "description": "Type and target of the link with cleared suspect link flag",
                "$ref": "#/definitions/historyLink"
              },
              "structureAction": {
                "description": "Type of structural operation",
                "type": "string",
                "enum": ["Create", "Copy", "Cut", "Promote", "Demote", "SwapUp", "SwapDown"]
              },
              "affectedNodeId": {
                "description": "Reference document object ID for moving the document object",
                "oneOf": [
                  { "$ref": "common.json#/definitions/numberString" },
                  { "const": "#" }
                ]
              },
              "docId": {
                "description": "Reference document ID for moving the document object",
                "$ref": "common.json#/definitions/fileName"
              }
            }
          }
        },
        "discussion": {
          "description": "Array of comments storing date, author and comment text",
          "type": "array",
          "uniqueItems": true,
          "items": {
            "type": "object",
            "properties": {
              "guid": {
                "description": "Globally unique ID of the comment",
                "$ref": "common.json#/definitions/guid"
              },
              "comment": {
                "description": "Comment text",
                "$ref": "common.json#/definitions/nonEmptyString"
              },
              "resolved": {
                "description": "Comment has been resolved",
                "type": "boolean"
              },
              "date": {
                "description": "Date and time of the comment",
                "$ref": "common.json#/definitions/timeStamp"
              },
              "author": {
                "description": "Author of the comment",
                "$ref": "common.json#/definitions/user"
              },
              "updatedOn": {
                "description": "Date and time of the last comment update",
                "$ref": "common.json#/definitions/timeStamp"
              }
            },
            "required": ["comment", "date", "author"]
          }
        },
        "helpRef": {
          "description": "If the document was created from a predefined template then it may store optional reference to the template help",
          "type": "string"
        }
      }
    },
    "historyLink": {
      "description": "Information about a changed traceability links in the document object history",
      "type": "object",
      "properties": {
        "type": {
          "description": "Link type of the added, updated or deleted traceability links",
          "$ref": "common.json#/definitions/nonEmptyString"
        },
        "target": {
          "$ref": "#/definitions/linkTargets"
        }
      },
      "required": ["type", "target"]
    },
    "suspectLink": {
      "description": "Structure describing an outgoing traceability link with suspect flag",
      "type": "object",
      "properties": {
        "target": {
          "description": "Target document object ID for the traceability link",
          "$ref": "#/definitions/projDocObjId"
        },
        "suspectClearedOn": {
          "description": "Date and time when the suspect flag of the traceability link was cleared last time",
          "$ref": "common.json#/definitions/timeStamp"
        },
        "targetGuid": {
          "description": "Globally unique ID of the target document object",
          "$ref": "common.json#/definitions/guid"
        }
      },
      "required": ["target", "suspectClearedOn"]
    },
    "linkTargets": {
      "description": "Array storing the target link ProjDocIds",
      "type": "array",
      "uniqueItems": true,
      "items": { "$ref": "#/definitions/projDocObjId" }
    },
    "projDocObjId": {
      "description": "Document object ID with document ID prefix and optional project ID prefix",
      "type": "string",
      "pattern": "^([^<>:\"/\\\\|?*]+/)?[^<>:\"/\\\\|?*]+-\\d+$",
      "examples": ["SRS-123", "Project2/NEEDS-45"]
    }
  }
}
