Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Scenario

Write Request

Read Request(Condition)

1

User consuming individual content. [New]

Code Block
languagejs
{
    "userid": "<<userid>>",
    "courseid": "<<contentid>>",
    "batchid": "<<contentid>>",
    "contentid": "<<contentid>>"
}

WHERE userid='<<userid>>' and courseid ='<<contentid>>'

2

User consuming a content with in a collection. [Existing]

  • Don’t carry forward content consumption (The content consumed in other context not considered for marking as complete).

Code Block
languagejs
{
    "userid": "<<userid>>",
    "courseid": "<<courseid>>",
    "batchid": "<<batchid>>",
    "contentid": "<<contentid>>"
}

WHERE userid='<<userid>>' and courseid ='<<courseid>>' and batchid ='<<batchid>>' and contentid='<<contentid>>'

3

User consuming a content with in a collection. [New]

  • Carry forward content consumption

Code Block
languagejs
{
    "userid": "<<userid>>",
    "courseid": "<<courseid>>",
    "batchid": "<<batchid>>",
    "contentid": "<<contentid>>"
}

Note: When it is consumed with in this context.

WHERE userid='<<userid>>' and courseid ='<<contentid>>'
OR
WHERE userid='<<userid>>' and courseid ='<<courseid>>' and batchid ='<<batchid>>' and contentid='<<contentid>>'

Extending Viewer-Service Design to support Program Context:

  • When a user enrols for program,once successfully capturing the data, an program context event will be generated

  • Enrolment Updater Job will read these events and use viewer-service read/write apis to update the corresponding content status based on the predefined rules set for a context

...

...

Scenario

...

Write Request

...

Read Request(Condition)

...

User consuming a content with in a collection by enrolling to program. [Existing]

...

Code Block
languagejs
{
    "userid": "<<userid>>",
    "courseid": "<<courseid>>",
    "batchid": "<<programid>>",
    "contentid": "<<contentid>>"
}

...

WHERE userid='<<userid>>' and courseid ='<<courseid>>' and batchid ='<<programid>>' and contentid='<<contentid>>'

...

User consuming a content with in a collection by enrolling to program . [New]

...

Code Block
languagejs
{
    "userid": "<<userid>>",
    "courseid": "<<courseid>>",
    "batchid": "<<programid>>",
    "contentid": "<<contentid>>"
}

...

WHERE userid='<<userid>>' and courseid ='<<contentid>>'
OR
WHERE userid='<<userid>>' and courseid ='<<courseid>>' and batchid ='<<programid>>' and contentid='<<contentid>>'

Program Metadata Table Schema:

...

Field

...

DataType

...

Description

...

identifier

...

String

...

Unique id for program

...

name

...

String

...

Name of the program

...

children

...

List[String]

...

list of collections in the program

Ex: [collection1,collection2]

Content View Lifecycle:

When the user view the content in context of a collection and batch, for the first time its start, progress update and end triggers are processed. Revisit (2nd - nth view) of the content will be ignored to process and update the DB.

...

  • If, collectionId and batchId are part of the request, then, individual content progress and overall collection progress is captured and computed.

...

  • In case of only userId and contentId, the progress is captured only for that content

...

  • With normal collection types, the map values gets distributed to multiple sstables with append, which might lead to read latency issues

  • To the handle the scenario, will consider the frozen collection types, which will helpful in avoiding tombstone and multiple sstable reads

...

...

Current vs New (Viewer-Service) APIs:

We need to continue supporting the current APIs (v1) before deprecate and delete. So, it requires to work with both the APIs with backward compatibility.

Enhance

...

Current APIs to read summary from aggregate table.

Enhance the below APIs to read the progress and score metrics from user_activity_agg table.

...

Expand
titlePOST - /v1/view/start

Request:

Code Block
languagejson
{
    "request": {
        "userId": "{{userId}}",
        "collectionId" : "{{collectionId}}",
        "batchId": "{{batchId}}",
        "contentId": "{{contentId}}"
    }
}

Response:

Code Block
languagejson
{
    "id": "api.view.start",
    "ver": "v2v1",
    "ts": "2021-06-23 05:37:40:575+0000",
    "params": {
        "resmsgid": null,
        "msgid": "5e763bc2-b072-440d-916e-da787881b1b9",
        "err": null,
        "status": "success",
        "errmsg": null
    },
    "responseCode": "OK",
    "result": {
        "{{contentId}}": "Progress started"
    }
}

...

Expand
titlePOST - /v1/view/update

Request:

Code Block
languagejson
{
    "request": {
        "userId": "{{userId}}",
        "collectionId" : "{{collectionId}}",
        "batchId": "{{batchId}}",
        "contentId": "{{contentId}}",
        "progress": 34
    }
}

Response:

Code Block
languagejson
200 OK:
{
    "id": "api.view.update",
    "ver": "v2v1",
    "ts": "2021-06-23 05:37:40:575+0000",
    "params": {
        "resmsgid": null,
        "msgid": "5e763bc2-b072-440d-916e-da787881b1b9",
        "err": null,
        "status": "success",
        "errmsg": null
    },
    "responseCode": "OK",
    "result": {
        "{{contentId}}": "SUCCESS"
    }
}

4XX or 5XX Error:
{
    "id": "api.view.update",
    "ver": "v2v1",
    "ts": "2021-06-23 05:37:40:575+0000",
    "params": {
        "resmsgid": null,
        "msgid": "5e763bc2-b072-440d-916e-da787881b1b9",
        "err": ERR_Error_Code,
        "status": "failed",
        "errmsg": ERR_error_msg
    },
    "responseCode": "BAD_REQUEST"/"SERVER_ERROR",
    "result": {
    }
}

...

Expand
titlePOST - /v1/assessment/submit

Request:

Code Block
languagejson
{
    "request": {
        "userId": "{{userId}}",
        "collectionId" : "{{collectionId}}",
        "batchId": "{{batchId}}",
        "contentId": "{{contentId}}",
        "assessments": [{
            {{assess_event}} //Mandatory for self-assess contents
        }]
    }
}

Response:

Code Block
{
    "id": "api.view.assess",
    "ver": "v2v1",
    "ts": "2021-06-23 05:37:40:575+0000",
    "params": {
        "resmsgid": null,
        "msgid": "5e763bc2-b072-440d-916e-da787881b1b9",
        "err": null,
        "status": "success",
        "errmsg": null
    },
    "responseCode": "OK",
    "result": {
        "{{contentId}}": "SUCCESS"
    }
}

...

Expand
titlePOST - /v1/view/end

Request:

Code Block
languagejson
{
    "request": {
        "userId": "{{userId}}",
        "collectionId" : "{{collectionId}}",
        "batchId": "{{batchId}}",
        "contentId": "{{contentId}}"
    }
}

Response:

Code Block
languagejson
{
    "id": "api.view.end",
    "ver": "v2v1",
    "ts": "2021-06-23 05:37:40:575+0000",
    "params": {
        "resmsgid": null,
        "msgid": "5e763bc2-b072-440d-916e-da787881b1b9",
        "err": null,
        "status": "success",
        "errmsg": null
    },
    "responseCode": "OK",
    "result": {
        "{{contentId}}": "Progress ended"
    }
}

...

Expand
titlePOST - /v1/view/read

Request:

Code Block
languagejson
{
    "request": {
        "userId": "{{userId}}",
        "contentId": ["do_123", "do_1234"],
        "collectionId" : "{{collectionId}}", //optional
        "batchId": "{{batchId}}"   // optional
  
    }
}

Response:

Code Block
languagejson
{
    "id": "api.view.read",
    "ver": "v2v1",
    "ts": "2021-06-23 05:37:40:575+0000",
    "params": {
        "resmsgid": null,
        "msgid": "5e763bc2-b072-440d-916e-da787881b1b9",
        "err": null,
        "status": "success",
        "errmsg": null
    },
    "responseCode": "OK",
    "result": {
    	"userId": "{{userId}}",
    	"collectionId": "{{collectionId}}",
    	"batchId": "{{batchId}}",
        "contents": [{
          "identifier": "{contentId}",
          "progress": 45,
    	  "score": {{best_score}},
    	  "max_score": {{max_score}}
        }]
    }
}

...

Expand
titleGET - /v1/summary/list/:userId

Response:

Code Block
languagejson
{
  "id": "api.summary.list",
  "ver": "v2v1",
  "ts": "2021-06-23 05:59:54:984+0000",
  "params": {
    "resmsgid": null,
    "msgid": "95e4942d-cbe8-477d-aebd-ad8e6de4bfc8",
    "err": null,
    "status": "success",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "summary": [
      {
        "userId": "{{userId}}",
        "collectionId": "{{collectionId}}",
        "batchId": "{{batchId}}",
        "enrolledDate": 1624275377301,
        "active": true,
        "contentStatus": {
          "{{contentId}}": {{status}}
        },
        "assessmentStatus": {
          "assessmentId": {
            "score": {{best_score}},
            "max_score": {{max_score}}
          }
        },
        "collection": {
          "identifier": "{{collectionId}}",
          "name": "{{collectionName}}",
          "logo": "{{logo Url}}",
          "leafNodesCount": {{leafNodeCount}},
          "description": "{{description}}"
        },
        "issuedCertificates": [{
          "name": "{{certName}}",
          "id": "certificateId",
          "token": "{{certToken}}",
          "lastIssuedOn": "{{lastIssuedOn}}"
        }],
        "completedOn": {{completion_date}},
        "progress": {{progress}},
        "status": {{status}}
      }
    ]
  }
}

...

Expand
titlePOST - /v1/summary/read

Request:

Code Block
{
    "request": {
        "userId": "{{userId}}",
        "collectionId" : "{{collectionId}}",
        "batchId": "{{batchId}}"
    }
}

Response:

Code Block
languagejson
{
  "id": "api.summary.read",
  "ver": "v2v1",
  "ts": "2021-06-23 05:59:54:984+0000",
  "params": {
    "resmsgid": null,
    "msgid": "95e4942d-cbe8-477d-aebd-ad8e6de4bfc8",
    "err": null,
    "status": "success",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
        "userId": "{{userId}}",
        "collectionId": "{{collectionId}}",
        "batchId": "{{batchId}}",
        "enrolledDate": 1624275377301,
        "active": true,
        "contentStatus": {
          "{{contentId}}": {{status}}
        },
        "assessmentStatus": {
          "assessmentId": {
            "score": {{best_score}},
            "max_score": {{max_score}}
          }
        },
        "collection": {
          "identifier": "{{collectionId}}",
          "name": "{{collectionName}}",
          "logo": "{{logo Url}}",
          "leafNodesCount": {{leafNodeCount}},
          "description": "{{description}}"
        },
        "issuedCertificates": [{
          "name": "{{certName}}",
          "id": "certificateId",
          "token": "{{certToken}}",
          "lastIssuedOn": "{{lastIssuedOn}}"
        }],
        "completedOn": {{completion_date}},
        "progress": {{progress}},
        "status": {{status}}
  }
}

...

Expand
titleDELETE - /v1/summary/delete/:userId?all - To Delete all enrolments

Response:

Code Block
languagejson
Response: 
{
    "id": "api.summary.delete",
    "ver": "v2v1",
    "ts": "2021-06-23 05:37:40:575+0000",
    "params": {
        "resmsgid": null,
        "msgid": "5e763bc2-b072-440d-916e-da787881b1b9",
        "err": null,
        "status": "success",
        "errmsg": null
    },
    "responseCode": "OK",
    "result": {}
}
Expand
titleDELETE - /v1/summary/delete/:userId - To Delete specific enrolments

Request:

Code Block
{
    "request": {
        "userId": "{{userId}}",
        "collectionId" : "{{collectionId}}",
        "batchId": "{{batchId}}"
    }
}

Response:

Code Block
languagejson
Response: 
{
    "id": "api.summary.delete",
    "ver": "v2v1",
    "ts": "2021-06-23 05:37:40:575+0000",
    "params": {
        "resmsgid": null,
        "msgid": "5e763bc2-b072-440d-916e-da787881b1b9",
        "err": null,
        "status": "success",
        "errmsg": null
    },
    "responseCode": "OK",
    "result": {}
}

...

Expand
titleGET - /v1/summary/download/:userId?format=csv

Response:

Code Block
{
    "id": "api.summary.download",
    "ver": "v2v1",
    "ts": "2021-06-23 05:37:40:575+0000",
    "params": {
        "resmsgid": null,
        "msgid": "5e763bc2-b072-440d-916e-da787881b1b9",
        "err": null,
        "status": "success",
        "errmsg": null
    },
    "responseCode": "OK",
    "result": {
      "url": "{{userId}}_viewer_summary.csv"
    }
}
Expand
titleGET - /v1/summary/download/:userId

Response:

Code Block
{
    "id": "api.summary.download",
    "ver": "v2v1",
    "ts": "2021-06-23 05:37:40:575+0000",
    "params": {
        "resmsgid": null,
        "msgid": "5e763bc2-b072-440d-916e-da787881b1b9",
        "err": null,
        "status": "success",
        "errmsg": null
    },
    "responseCode": "OK",
    "result": {
      "url": "{{userId}}_viewer_summary.json"
    }
}

...