Organisation/User Configuration

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 :

  

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

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

name

dataType 

description

orgName

string

name of the organisation







Pros

Cons

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

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

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

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

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

Field

Type

Required

name

string

true

phone

string

conditional (phone or email)

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 

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

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.

      

getUserProfile
"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.