> For the complete documentation index, see [llms.txt](https://lern.sunbird.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lern.sunbird.org/use/developer-guide/user-and-org-service/caching-and-denormalising-user-metadata/usercacheupdaterflinkjob.md).

# UserCacheUpdaterFlinkJob

The three exhaust reports depend on the user metadata information which is generated from the user-cache-updater flink job by fetching information from different core Cassandra tables and are stored in the Redis cache. From Release-3.7.0 the design for the flink job has been changed and now the information will be fetched from the User Read API.

JIRA Link: <https://project-sunbird.atlassian.net/browse/SB-21691>

Reference Wiki Links:

1. User Table Changes: <https://project-sunbird.atlassian.net/wiki/spaces/UM/pages/2110881881>
2. Org Table Changes: <https://project-sunbird.atlassian.net/wiki/spaces/UM/pages/2260074547>

**Implementation Design:**

<figure><img src="/files/3UtexFgj61psBk8u2vAH" alt="usercacheupdaterflinkdesign" width="452"><figcaption></figcaption></figure>

![](blob:https://project-sunbird.atlassian.net/4576cfc6-d4bf-4cad-b0a5-b217e77358ed#media-blob-url=true\&id=2da0751c-f2f3-4ec6-9a84-917fce115f47\&collection=contentId-1520074753\&contextId=1520074753\&height=551\&width=501\&alt=)Design for the fields to be fetched:

<table><thead><tr><th width="158">Field Name</th><th width="87">Type</th><th width="206">Logic to fetch</th><th>Description</th></tr></thead><tbody><tr><td><strong>User-ID</strong></td><td>String</td><td>userId</td><td>It indicates user unique Identifier</td></tr><tr><td><strong>Mobile Number</strong></td><td>String</td><td>encPhone</td><td>User phone number in an encrypted format</td></tr><tr><td><strong>Email ID</strong></td><td>String</td><td>encEmail</td><td>User mail id in an encrypted format</td></tr><tr><td>First Name</td><td>String</td><td>firstName</td><td>User first name</td></tr><tr><td>Last Name</td><td>String</td><td>lastName</td><td>User Last Name</td></tr><tr><td>Rootorgid</td><td>String</td><td>rootOrgId</td><td>User root org id (can be used to differentiate between custodian and state user)</td></tr><tr><td>Board</td><td>String</td><td>framework.board</td><td>User’s board<br>Assumption: It is single valued</td></tr><tr><td>Medium</td><td>List[String]</td><td>framework.medium</td><td>User medium</td></tr><tr><td>Subject</td><td>List[String]</td><td>framework.subject</td><td>User subjects</td></tr><tr><td>Language</td><td>List[String]</td><td>language</td><td>User Language</td></tr><tr><td>Grade</td><td>List[String]</td><td>framework.gradeLevel</td><td>User grades</td></tr><tr><td>framework</td><td>String</td><td>framework.id</td><td>User’s framework id<br>Assumption: It is single valued</td></tr><tr><td><strong>UserType</strong></td><td>String</td><td>profileUserType.type</td><td>User Type</td></tr><tr><td><strong>UserSubType</strong></td><td>String</td><td>profileUserType.subType</td><td>User’s Sub Type</td></tr><tr><td><strong>Orgname</strong></td><td>String</td><td>rootOrg.orgName</td><td>User’s Org Name<br>It is fetched from rootOrg Map.</td></tr><tr><td><strong>School Name</strong></td><td>String</td><td>Fetch {name} where userLocation[*].type = 'school'</td><td>User’s School Name.<br>It is fetched from the userLocation Map</td></tr><tr><td><strong>School UDISE Code</strong></td><td>String</td><td>Fetch {code} where userLocation[*].type = 'school'</td><td>User’s School UDISE Code.<br>It is fetched from the userLocation Map</td></tr><tr><td><strong>State Name</strong></td><td>String</td><td>Fetch {name} where userLocation[*].type = 'state'</td><td>User’s State Name.<br>It is fetched from the userLocation Map</td></tr><tr><td><strong>District Name</strong></td><td>String</td><td>Fetch {name} where userLocation[*].type = 'district'</td><td>User’s District Name.<br>It is fetched from the userLocation Map</td></tr><tr><td><strong>Block Name</strong></td><td>String</td><td>Fetch {name} where userLocation[*].type = 'block'</td><td>User’s Block Name.<br>It is fetched from the userLocation Map</td></tr><tr><td><strong>Cluster Name</strong></td><td>String</td><td>Fetch {name} where userLocation[*].type = 'cluster'</td><td>User’s Cluster Name.<br>It is fetched from the userLocation Map</td></tr></tbody></table>

**User Read API Request**\
\
curl --location --request GET 'http\://{Private LB}/learner/private/user/v1/read/:uuid?fields=locations'\
\
**User Read API Response**

```
{
  "id": ".private.user.v1.read.123456",
  "ver": "private",
  "ts": "2021-03-09 11:33:42:061+0530",
  "params": {
    "resmsgid": null,
    "msgid": "06ff91d6-043e-4714-b002-6f8b90a04723",
    "err": null,
    "status": "success",
    "errmsg": null
  },
  "responseCode": "OK",
  "result": {
    "response": {
      "webPages": [],
      "maskedPhone": null,
      "subject": [],
      "channel": "root2",
      "language": [],
      "updatedDate": null,
      "password": null,
      "managedBy": null,
      "flagsValue": 2,
      "id": "a962a4ff-b5b5-46ad-a9fa-f54edf1bcccb",
      "recoveryEmail": "",
      "identifier": "a962a4ff-b5b5-46ad-a9fa-f54edf1bcccb",
      "thumbnail": null,
      "updatedBy": null,
      "accesscode": null,
      "locationIds": [
        "8db3345c-1bfc-4276-aef1-7ea0f3183211",
        "d087424e-18cb-49b0-865c-98f265c73ed3",
        "13087424e-18cb-49b0-865c-98f265c73ed3",
        "43087424e-18cb-49b0-865c-98f265c73ed3"
      ],
      "externalIds": [
        {
          "idType": "root2",
          "provider": "root2",
          "id": "123456"
        }
      ],
      "registryId": null,
      "rootOrgId": "0127738024883077121",
      "prevUsedEmail": "",
      "firstName": "Creator",
      "tncAcceptedOn": null,
      "allTncAccepted": {},
      "phone": "",
      "dob": null,
      "grade": [],
      "currentLoginTime": null,
      "userType": null,
      "status": 1,
      "lastName": "test",
      "tncLatestVersion": "v1",
      "gender": null,
      "roles": [
        "PUBLIC"
      ],
      "prevUsedPhone": "",
      "stateValidated": false,
      "isDeleted": false,
      "organisations": [
        {
          "organisationId": "0127738024883077121",
          "updatedBy": null,
          "addedByName": null,
          "addedBy": null,
          "roles": [
            "PUBLIC"
          ],
          "approvedBy": null,
          "updatedDate": null,
          "userId": "a962a4ff-b5b5-46ad-a9fa-f54edf1bcccb",
          "approvaldate": null,
          "isDeleted": false,
          "hashTagId": "0127738024883077121",
          "isRejected": null,
          "id": "0132322953313320960",
          "position": null,
          "isApproved": null,
          "orgjoindate": "2021-03-09 11:31:31:930+0530",
          "orgLeftDate": null
        }
      ],
      "profileUserType": {
        "usertype": "administrator",
        "usersubtype": "deo"
      },
      "userLocations": [
        {
          "code": "21",
          "name": "Odisha",
          "id": "8db3345c-1bfc-4276-aef1-7ea0f3183211",
          "type": "state",
          "parentId": null
        },
        {
          "code": "2112",
          "name": "CUTTACK",
          "id": "d087424e-18cb-49b0-865c-98f265c73ed3",
          "type": "district",
          "parentId": "8db3345c-1bfc-4276-aef1-7ea0f3183211"
        },
        {
          "code": "211",
          "name": "BLOCK1",
          "id": "13087424e-18cb-49b0-865c-98f265c73ed3",
          "type": "block",
          "parentId": "8db3345c-1bfc-4276-aef1-7ea0f3183211"
        },
        {
          "code": "211",
          "name": "CLUSTER1",
          "id": "43087424e-18cb-49b0-865c-98f265c73ed3",
          "type": "cluster",
          "parentId": "8db3345c-1bfc-4276-aef1-7ea0f3183211"
        },
        {
          "name": "DPS, MATHURA",
          "id": "63087424e-18cb-49b0-865c-98f265c73ed3",
          "type": "school",
          "externalid": "3183211"
        }
      ],
      "countryCode": null,
      "tncLatestVersionUrl": "https://dev-sunbird-temp.azureedge.net/portal/terms-and-conditions-v1.html",
      "maskedEmail": "am******@yopmail.com",
      "tempPassword": null,
      "email": "am******@yopmail.com",
      "rootOrg": {
        "dateTime": null,
        "preferredLanguage": "English",
        "keys": {},
        "approvedBy": null,
        "channel": "root2",
        "description": "Root Org2",
        "updatedDate": null,
        "addressId": null,
        "orgType": null,
        "provider": null,
        "locationId": null,
        "orgCode": null,
        "theme": null,
        "id": "0127738024883077121",
        "communityId": null,
        "isApproved": null,
        "email": null,
        "slug": "root2",
        "isSSOEnabled": null,
        "thumbnail": null,
        "orgName": "Root Org2",
        "updatedBy": null,
        "locationIds": [],
        "externalId": null,
        "isRootOrg": true,
        "rootOrgId": "0127738024883077121",
        "approvedDate": null,
        "imgUrl": null,
        "homeUrl": null,
        "orgTypeId": null,
        "isDefault": null,
        "createdDate": "2019-05-31 16:41:29:485+0530",
        "createdBy": null,
        "parentOrgId": null,
        "hashTagId": "0127738024883077121",
        "noOfMembers": null,
        "status": 1
      },
      "phoneVerified": false,
      "profileSummary": null,
      "recoveryPhone": "",
      "avatar": null,
      "userName": "creatortest_72yz",
      "userId": "a962a4ff-b5b5-46ad-a9fa-f54edf1bcccb",
      "userSubType": null,
      "promptTnC": true,
      "emailVerified": true,
      "lastLoginTime": null,
      "createdDate": "2021-03-09 11:31:23:189+0530",
      "framework": {
        "board": [
          "IGOT-Health"
        ],
        "gradeLevel": [
          "Volunteers"
        ],
        "id": [
          "igot_health"
        ],
        "medium": [
          "English"
        ],
        "subject": [
          "IRCS"
        ]
      },
      "createdBy": null,
      "location": null,
      "tncAcceptedVersion": null
    }
  }
}
```

**Queries:**

1. Should we fetch extra information eg webpage, createdBy, createdFor, etc? Fetch only if required for denorm job
2. Should we fetch externalid from now or not? Fetch only if required for denorm job
3. Should we directly fetch username or have a logic of firstname+lastname? firstname+lastname should be the username for reports


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://lern.sunbird.org/use/developer-guide/user-and-org-service/caching-and-denormalising-user-metadata/usercacheupdaterflinkjob.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
