I have a questionnaire which is being modelled using JSON-schema. Each Schema is validated using AJV. My "questionnaire" object looks like the following. 'Sections' contains a schema for individually rendered questions, "routes" is used to decided what page to route to next, and "answers" is an object that get's populated when a user posts an answer to a question.
"type": "apply-for-stuff",
"version": "0.0.1",
"sections": {
"when-was-it-ordered": {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
"q-when-was-it-ordered"
],
"additionalProperties": false,
"properties": {
"q-when-was-it-ordered": {
"type": "string",
"format": "date-time",
"title": "When was it ordered?",
"description": "For example, 31 3 2018. You can enter an approximate date.",
"errorMessage": {
"format": "The date it was ordered must be in the past"
}
}
},
"errorMessage": {
"required": {
"q-when-was-it-ordered": "Enter the date it was ordered"
}
}
},
"when-did-it-arrive": {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
"q-applicant-when-did-it-arrive"
],
"additionalProperties": false,
"properties": {
"q-when-did-it-arrive": {
"type": "string",
"format": "date-time",
"title": "When did it arrive?",
"description": "For example, 31 3 2018. You can enter an approximate date.",
"errorMessage": {
"format": "The date it arrived must be in the past"
}
}
},
"errorMessage": {
"required": {
"q-when-did-it-arrive": "Enter the date the it arrived"
}
}
},
"date-of-birth": {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
"q-when-did-it-start"
],
"additionalProperties": false,
"properties": {
"q-when-did-it-start": {
"type": "string",
"format": "date-time",
"title": "When did it start?",
"description": "For example, 03 2018. You can enter an approximate date.",
"errorMessage": {
"format": "Enter the date it started"
}
}
},
"errorMessage": {
"required": {
"q-when-did-it-start": "Enter the date it started"
}
}
}
},
"routes": {
"states": {
"when-was-it-ordered": {
"on": {
"ANSWER": [
{
"target": "another-question"
}
]
}
},
"applicant-when-did-it-arrive": {
"on": {
"ANSWER": [
{
"target": "another-question"
}
]
}
},
"date-of-birth": {
"on": {
"ANSWER": [
{
"target": "another-question"
}
]
}
}
}
},
"answers": {
"when-was-it-ordered": {
"q-when-was-it-ordered": "2019-01-01T14:48:00.000Z"
},
"when-did-it-arrive": {
"q-when-did-it-arrive": "2019-01-03T14:48:00.000Z"
},
"date-of-birth": {
"q-date-of-birth": "2000-01-01T14:48:00.000Z"
}
}
This information is contained within a service which sends each question individually to another service, which renders the output and displays it to the user.
In the above sample, I have included 3 'date' type questions. I am looking for an elegant way to compare these dates, and enforce validations rules. For example, I would like the value entered for 'when-did-it-arrive' to be after 'when-was-it-ordered', otherwise AJV fails the validation and errors.
I found a question previously answered which almost solves my problem here. However, this solution doesn't appear to be immediately suitable to my problem because each of the 'sections' is validated in isolation - If the user tries to navigate to 'when-did-it-arrive', the validator has no knowledge of anything else in the questionnaire, other than the schema for 'when-did-it-arrive':
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
"q-applicant-when-did-it-arrive"
],
"additionalProperties": false,
"properties": {
"q-when-did-it-arrive": {
"type": "string",
"format": "date-time",
"title": "When did it arrive?",
"description": "For example, 31 3 2018. You can enter an approximate date.",
"errorMessage": {
"format": "The date it arrived must be in the past"
}
}
},
"errorMessage": {
"required": {
"q-when-did-it-arrive": "Enter the date the it arrived"
}
}
}
And the answer posted by the user:
"when-did-it-arrive": {
"q-when-did-it-arrive": "2019-01-03T14:48:00.000Z"
}
Any advice on how to approach this type of validation would be appreciated.
UPDATE
In the absence of a way of doing this using the schema, I have elected to add some javascript post AJV which performs this function. So the schema is validated in AJV, and given a valid schema, my custom function (Which I'm not including as it's some trivial JS) performs the validation decribed above. If the schema fails validation here, the output is in the same style as an AJV error.