{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://reqview.com/schemas/2.7/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 in instructions 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"
          }
        },
        "dependencies": {
          "help": {
            "properties": {
              "type": { "const": "xhtml" }
            }
          }
        },
        "required": ["type"]
      }
    },
    "data": {
      "description": "Array of top level document objects",
      "type": "array",
      "uniqueItems": true,
      "items": { "$ref": "#/definitions/docObj" }
    },
    "view": {
      "description": "The default document view",
      "type": "object",
      "properties": {
        "columns": {
          "type": "array",
          "uniqueItems": true,
          "items": {
            "type": "object",
            "properties": {
              "guid": {
                "description": "Globally unique ID of the column",
                "$ref": "common.json#/definitions/guid"
              },
              "hidden": {
                "description": "Set to true for columns which should not be displayed",
                "type": "boolean"
              },
              "width": {
                "description": "Column width in pixels",
                "type": "number",
                "exclusiveMinimum": 0
              },
              "label": {
                "description": "The displayed label of the column",
                "type": "string"
              },
              "columnId": {
                "description": "For attribute columns stores the attribute ID or 'description' for the main column (deprecated)",
                "$ref": "common.json#/definitions/nonEmptyString"
              },
              "attribute": {
                "description": "For attribute columns stores the attribute ID or 'description' for the main column",
                "$ref": "common.json#/definitions/nonEmptyString"
              },
              "template": {
                "description": "For template columns stores the template text",
                "type": "string"
              }
            }
          }
        }
      }
    }
  },
  "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/docObjId" },
                { "$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" },
              "commentIndex": {
                "description": "Index of the edited comment",
                "type": "number"
              },
              "commentAuthor": {
                "description": "Author of the comment",
                "$ref": "common.json#/definitions/user"
              },
              "commentDate": {
                "description": "Date and time of the comment",
                "$ref": "common.json#/definitions/timeStamp"
              },
              "addedComment": {
                "description": "Text of the added comment",
                "$ref": "common.json#/definitions/nonEmptyString"
              },
              "editLastComment": {
                "description": "Previous text of the edited comment",
                "$ref": "common.json#/definitions/nonEmptyString"
              },
              "deleteLastComment": {
                "description": "Text of the deleted comment",
                "$ref": "common.json#/definitions/nonEmptyString"
              },
              "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"
              },
              "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": {
              "comment": {
                "description": "Comment text",
                "$ref": "common.json#/definitions/nonEmptyString"
              },
              "date": {
                "description": "Date and time of the comment",
                "$ref": "common.json#/definitions/timeStamp"
              },
              "author": {
                "description": "Author of the comment",
                "$ref": "common.json#/definitions/user"
              }
            },
            "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": {
        "target": {
          "description": "Array storing the target document object for each added, updated or deleted traceability link",
          "type": "array",
          "uniqueItems": true,
          "items": { "$ref": "#/definitions/docObjId" }
        },
        "type": {
          "description": "Link type of the added, updated or deleted traceability links",
          "$ref": "common.json#/definitions/nonEmptyString"
        }
      },
      "required": ["target", "type"]
    },
    "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/docObjId"
        },
        "suspectClearedOn": {
          "description": "Date and time when the suspect flag of the traceability link was cleared last time",
          "$ref": "common.json#/definitions/timeStamp"
        }
      },
      "required": ["target", "suspectClearedOn"]
    },
    "docObjId": {
      "description": "Document object ID with optional document ID prefix",
      "type": "string",
      "pattern": "^[^\\<\\>\\:\\\"\\/\\\\\\|\\?\\*]+-\\d+$",
      "examples": ["123", "SRS-123"]
    }
  }
}
