Organisation/User Configuration
Problem statement: As of now organisation upload sample file is static file , so changes for any attributes required changes in portal as well. We need to make sample file generation as dynamic. The reason behind making file generation dynamic is , different adopters need different fields to be passed during org bulk upload.
Proposed Solution 1:
Sunbird will define all attribute for org creation as org master attribute and consumer can use some of this value to define upload file structure. Attribute will be define per installation.
Based on adopters defined value sunbird will do request validation as well. There will be a default settings for organisation create attribute , adopters can override it.
Organisation Attribute :
{ "org":{ "attributes":[ { "name":"orgName", "optional":false } , { "name":"locationCode", "optional":false } , { "name":"orgId", "optional":true } , { "name":"externalId", "optional":true }, { "name":"status", "optional":false }, { "name":"description", "optional":false } ] } }
Pros | Cons |
---|---|
user can select any attribute from supported attribute list | Extra configuration required for org attribute settings . |
Org creation sample csv can be generated at runtime | Extra configuration/api required for all supported organisation attribute. |
As data is store inside database , so value can be updated any time |
Usages :
This setting will be stored inside system settings table with column name "orgAttributeSettings" and column value as above setting in Json format.
There is a getSystemsetting api that need be called by consumer to get settings for particular key.
Define All supported attribute for an organisation:
There are two approach to define all supported attribute of an organisation:
Approach 1:
Define all the supported attribute in sunbird doc as follow.
name | dataType | description |
---|---|---|
orgName | string | name of the organisation |
Pros | Cons |
---|---|
less development effort | maintenance cost is more , any changes in attributes required doc updates. |
Approach 2:
Define a new api that will provide all attributes of organisations at runtime. it will reduce maintenance cost.
Proposed Solution 2:
Sunbird will take only list of mandatory attributes from adopters and it will have master list for org creation. Master list will define which field is option/mandatory , field data type and other details.
Adopters can see all supported fields from master list and then they can create mandatory list for org creation.
{
"orgMandatoryAttributes":"orgName","orgCodes","status"
}
Pros | Cons |
---|---|
Setting is simplified for adopters, they need to select mandatory attributes only | Extra configuration required , increase development time |
Need more logic from consumer to create dynamic csv sample. Because for optional they don't know field should be in csv. |
Proposed Solution 3:
Sunbird will take two list from adopters.
- Mandatory list : This will contains all mandatory parameter required for org creation.
- Optional list : This will contains optional parameter for org creation . Both mandatory and optional parameter will be part of master list (all the attribute supported for org creation
{ "orgMandatoryAttributes":["orgName","orgCodes","status"], "orgOptionalAttributes": ["orgId","externalId","description"] }
Pros | Cons |
---|---|
Mandatory and optional are define separately , so it will have clear picture of all fields | adopters need to set both mandatory and optional lsit |
Easy for consumer to generate sample csv based on both attribute |
Proposed Solution 4:
We can used config service to put org creation configuration. In that case same configuration will moved from sunbird to config service.
Pros | Cons |
---|---|
All configuration will be moved to config service | Since config service is optional ,so we need to have fallback as well. Or some time config service is down. |
Adding one more dependency , will increase development time | |
Still we have to support config service and local config both |
How setting can be done by adopters:
Adopter need to make system settings api call to update/insert settings
URI : /data/v1/system/setting/set Method: POST request body: { "request": { "id": "orgAttributeSettings", //fix value "field": "orgAttributeSettings", // fix value "value": "it can be json" } }
After Discussion we arrive to a point that no need to do dynamic generation of org and user sample file.
How Consumer will used it:
Consumer will make below api call to get org attribute settings.
Consumer will read settings data and they can provide option to org admin to generates files only with mandatory field or mandatory plus optional both.This can be ask during download time or can be a env variable that will decide business logic for file generation.
URI: /data/v1/system/setting/read/orgAttributeSettings
Method: GET
or they can make api call to get all settings.
/data/v1/system/settings/list
Method: GET
Proposed fields for user and org :
Organisation Fields:
Field | Type | Required |
---|---|---|
orgName | string | true |
locationCodes | array of string | true |
status | int | true |
organisationId | string | false |
description | string | false |
externalId | string | false |
Doubts:
1. In Bulk upload are we always going to create suborg only, because for rootOrg creation "channel" is mandatory.
2. Will only externalId be unique across system or externalId and channel combination should be unique
Resp: The external ID field will be used by states to assign the state ID for the school (if available) - this could be different formats for different states. This will not be a mandatory field in Diksha.
3. WorkFlow for status changes : if org status is inactive (0) then will all user of this org should be inactive, similarly if it's rootOrg and status is inactive then all suborg and there user need to be inactive.
Resp : The active/ inactive flag cannot be accessed via the api as confirmed by +vinayab@ilimi.in . We'll take up these workflows in V2.
4. Old org will have several other fields as well , so that field need to be retain as it is or need to be dropped. if need to be dropped then is it only applicable for DIKSHA or all adopters.
User Fields:
Field | Type | Required |
---|---|---|
name | string | true |
phone | string | conditional (phone or email) |
string | conditional (phone or email) | |
organisationId | string | conditional (if userType=teacher then it's required) |
userType | string | required (possible values : teacher and others) |
roles | list | conditional (required if userType is teacher) |
userFramework | Map<string,List<string>> | false |
or Framework related data we can directly save as well:
* Board , class, subject, medium
Doubts:
1. Email and phone are unique for a user , so during bulk upload what should be the flow. Means if phone/email exist then do we need to override it or throw an error.
2. Old user is having lot's more different fields as well , so how are we going to handle old field.
3. As some of the mandatory field we are going to change (firstName and userName) , so now how old app will behave?
User search based on locations:
Background:
As of now user search is not possible based on geo location, but now we need to provide capabilities to do user search based on Geo loaction (state,district, block etc).
Proposed Solution 1:
Sunbird will store locationIds inside user object . When ever a user is added to an organisation , it will store all hierarchical locations ids. If any user is removed from an organisation then it's locationIds need to be recalculated based on all other associated organisations.
Pros | Cons |
---|---|
User can be search based on any location hierarchy. | In each user org association and disassociation locationIds need to be calculated, System load will increase |
During org update , aging system need to do user location ids recalculations for all associated userIds. |
Proposed Solution 2:
In every user search api call, sunbird will check filters value, if filters having Geo location then it will first search all those organisation ids that belongs to provided geo location codes then it update user search filter with collected organisation ids.
"request": { "filters":{ "state":"stateId", "district":"districtId", "block":"blockId" } }
Pros | Cons |
---|---|
There is no changes in user org association and disassociation | User search will be little slower, because of making one extra search call |
During org update we don't need to do any user location updates | |
No need to directly store one more key locationIds inside user |
After discussion Solution 2 is accepted.
Changes in user profile read api:
Background:
As of now user profile read api is providing user basic details , and some extra details based on passed fields (completeness,missingFields,topic,organisations) , User is having organisation association and geolocation data as well. So Profile consumer need to make two extra call to get those values . one call for collecting organisation details and another for collecting geolocation.
Proposed Solution :
In get user api call system will take one extra field as organisations, if field will be available then system will make internal call and provide all values in same api.
"organisations":[ { "organisationId":"0123653943740170242", "updatedBy":null, "addedByName":null, "addedBy":null, "roles":[ "PUBLIC", "CONTENT_REVIEWER", "BOOK_REVIEWER", "COURSE_MENTOR", "ORG_ADMIN" ], "approvedBy":null, "updatedDate":null, "userId":"97255811-5486-4f01-bad1-36138d0f5b8a", "approvaldate":null, "isDeleted":false, "hashTagId":null, "isRejected":null, "id":"01236539303387955231", "position":"ASD", "isApproved":null, "orgjoindate":"2017-10-31 10:47:05:805+0000", "orgLeftDate": // Adding new field in organisation "orgName: "name of organisation", "description": "description of org", "channel":"org channel", "hashTagId":"org hashTag", "locationIds":[], "locations":[ { "code": "Mug-99", "name": "Munger-99", "id": "9587fd13-e742-4899-97e0-819b6771ac38", "type": "state", "parentId": null } ] } ]
User Search:
Problem statement :
As of now in user search response only public fields are visible. But now email and phone also need to be visible in user search, and it should always be mask. And this should come is caller is org admin or course mentor role. As per current implementation all user private fields are stored in a separate index as "profileVisiblity" , so during search search private fields won't come because search is happen on user index.
Proposed Solution 1:
User email and phone will be always stored in user index inside ES as mask data. During search system will check caller role if caller role is either org admin or course mentor then it will include email and phone as well in search. if caller is not having above role then email and phone won't come.
Proposed Solution 2:
User Private data will still be inside "profileVisiblity" index , so when ever search will happen based on caller role , system will fetch mask phone and email from another index and merge with existing response.
Accepted design is Solution 2:
Note: What ever solution will be accepted for org creation , same can be applied for user creation as well.