Problem Statement:
The creator should be able to add a sub-question against the options of a question.
Users should be able to see the relevant question based on the response of the previous question/s.
Rules/Behaviour:
...
The dependent Question feature should be enabled only for observation & survey.
...
A Question can have more than one dependent(child) question for its different option combinations
...
A question can't depend upon more than one question. It means multiple questions can't point to the same question as a dependent one.
...
Problem Statement:
The creator should be able to add a sub-question against the options of a question.
Users should be able to see the relevant question based on the response of the previous question/s.
Rules/Behaviour:
A Question can have more than one dependent(child) question for its different option combinations.
Questions with a pre-condition (i.e. pre-condition is not null or empty) will not be part of the primary sequence of the question set.
Source question and its targets should be members of the same question set.
Current Implementation:
The dependent Question feature should be enabled only for observation & survey.
A question can't depend upon more than one question. It means multiple questions can't point to the same question as a dependent one.
The dependent question will not have further dependent questions.
Example:
Q1, Q2, Q3
Q4 - pre-condition:
if Q1. response = x or Q1.response = y
if Q1.response = x and Q2.response = y
delete Q1: delete Q1 from hierarchy and branching logic. return “Q4 is dependent on Q1” in the response.
hierarchy: Q2, Q3, Q4
branchingLogic:
Q2 - target = Q4
Q4 - source = Q1, Q2 & pre-condition: {Q1.response = x and Q2.response = y}
if Q1.response = x or Q2.response = y
Solution: Dependent Question Behaviour will be achieved using metadata (branchingLogic) with Immediate Parent ( A Section or Observation/Survey) who has a dependent question
...
Code Block | ||
---|---|---|
| ||
{ "branchingLogic": { // Renamed from render config "questionId_do_1": { // Only parent or child questions will be stored here. "target": [ "questionId_do_2" ], "preCondition": {} }, "questionId_do_2": { "target": [], "source/parent": ["questionId_do_1"], "preCondition": { "and": [ // Use of JSON Logic library { "eq": [ // eq, ne, lt, gt, exists, not_exists, and, or { "var": "do_1.response1.value", "type": "responseDeclaration" }, "0" ] } ] ] } } } } |
target : all target question id's will be stored here.
preCondition: rule or set of rules for question response assertion
“branchingLogic” will have entries for only those objects which have a dependent question and a dependent one.
Dependent Question should be added only through update hierarchy api as we need to pass additional metadata branchingLogic as well. The metadata should be passed as part of nodesModified.
Question with visibility Parent/Default can be added as a dependent question.
ES Syncing will be disabled for the field “branchingLogic” through an existing config in search-indxer job.
Platform will always support the replace operation for “branchingLogic”. So any partial update shouldn’t happen.
compatibilityLevel for observation & survey categories will be set as current + 1 . i.e: 6. So that user will be forced to update the app, when observation/survey consumption will go live.
When The player starts playing a survey/observation, It should start rendering using hierarchy index as well as branchingLogic.
Question Index needs to be handled explicitly at player end as hierarchy index may be different for question which becomes visible first. the same will be applicable for dependent question as well.
Solution of Progress tracking/score computation for dependent question will be designed and taken up later before consumption start.
...
Code Block |
---|
{
"request": {
"data": {
"nodesModified": {
"section1": {
"isNew": false,
"root": false,
"metadata": {
"branchingLogic": {
"q1": {
"target": [
"q2"
],
"preCondition": {} // this will be empty
},
"q2": {
"target": [], // this will be empty
"preCondition": {} // this will have required rule.
}
}
}
},
"q2": {} // metadata for question q2
},
"hierarchy": {
"survey-1": {
"name": "survey 1",
"primaryCategory": "Survey",
"children": [
"section1"
],
"root": true
},
"section1": {
"name": "Section 1",
"primaryCategory": "Survey",
"children": [
"q1",
"q2"
],
"root": false
}
},
"lastUpdatedBy": "5a587cc1-e018-4859-a0a8-e842650b9d64"
}
}
}
|
deleteFromHierarchy:
...
}
|
deleteFromHierarchy:
deleting a dependent question:
delete from hierarchy
delete the entry from branching logic
<update all the targets> - using the source
deleting an independent question:
if the question has targets, throw an error…
the dependent questions should be deleted first and then the delete should be triggered again
if there are no targets, delete the node from hierarchy
If a node gets deleted from hierarchy through this api, platform will first check if its parent has branchingLogic meta, if yes, further check the node entry in branchingLogic, if entry found, there are two possible behaviour:
1st Behaviour:
if target of the requested node is not empty, delete all target ids from hierarchy as well as from branchingLogic first and then delete the requested node.
if target is empty, scan the identifier in other entries of branchingLogic and update the target, then delete the requested node from hierarchy and remove the entry from branchingLogic
2nd Behaviour:
If the target is not empty, throw client error with target ids because it has a dependent question. So in this case, the user should remove the dependent question first and update the branchingLogic of the parent question and then delete the parent one.
If the target is empty but preCondition is not empty, it will delete the node from the hierarchy and remove the entry from branchingLogic.
Note: Ideally platform should go with 1st behaviour because a child question can have only one parent.
...
addNodeToHierachy:
The api won’t be used for dependent question feature. All children added through this api will be treated as independent object. So no code change is required.
input:
identifier of the question
branching for this node
source & pre-condition: source must already exist within the question set
TODO: add support for atomic operations to add/remove dependent questions
questionset-publish flink job:
...