Skip to content

Commit

Permalink
Merge pull request #89 from shikshalokam/master
Browse files Browse the repository at this point in the history
ED-94 Block Level Filters
  • Loading branch information
aks30 authored Apr 27, 2023
2 parents 2b32e92 + 4476e27 commit b546a44
Show file tree
Hide file tree
Showing 10 changed files with 382 additions and 5 deletions.
4 changes: 4 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ OBSERVATION_DATASOURCE_NAME = "OBSERVATION_DATASOURCE_NAME" // Obs
OBSERVATION_EVIDENCE_DATASOURCE_NAME = "EVIDENCE_DATASOURCE_NAME" // Observation evidences data source name
SURVEY_DATASOURCE_NAME = "SURVEY_DATASOURCE_NAME" // Survey data source name
SURVEY_EVIDENCE_DATASOURCE_NAME = "SURVEY_EVIDENCE_DATASOURCE_NAME" // Survey evidence data source name
PROJECT_RESOURCE_DATASOURCE_NAME = "PROJECT_RESOURCE_DATASOURCE_NAME" // Project resource data source name
OBSERVATION_RESOURCE_DATASOURCE_NAME = "OBSERVATION_RESOURCE_DATASOURCE_NAME" // Observation resource data source name
SURVEY_RESOURCE_DATASOURCE_NAME = "SURVEY_RESOURCE_DATASOURCE_NAME" // Survey resource data source name
PROGRAM_RESOURCE_DATASOURCE_NAME = "PROGRAM_RESOURCE_DATASOURCE_NAME" // Program resource data source name
CONTENT_REPORT_THRESHOLD = 5 // Restrict number of records to be shown for container reports
ENTITY_SCORE_REPORT_THRESHOLD = 5 // Restrict number of submission for entity score report
OBSERVATION_SCORE_REPORT_THRESHOLD = 2 // Restrict number of submission per entity in observation report
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,5 @@ typings/
config/config.json
tmp/*
package-lock.json
keycloak-public-keys/
.vscode/
34 changes: 34 additions & 0 deletions common/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* name : constants.js
* author : Ankit Shahu
* created-date : 10-April-2023
* Description : This is to keep all the hard code value in form of variable.
*/


/**
* Description : projection passed by frontend
*/
exports.ResourceTypeProjection = {
DISTRICT:"district",
BLOCK:"block",
ORGANISATION:"organisation"

}

/**
* Description : resource type passed by frontend
*/
exports.ResourceType = {
PROGRAM:"program",
SOLUTION:"solution"
}

/**
* Description : solution type passed by frontend
*/
exports.SolutionType = {
PROJECT : "improvementProject",
OBSERVATION: "observation",
SURVEY :"survey"
}
14 changes: 13 additions & 1 deletion common/druid_queries.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,17 @@

"observations_by_entity" : {"queryType":"groupBy","dataSource":"ml_observation_dev","granularity":"all","dimensions":["entityId","entityName","observationName","observationSubmissionId","createdAt"],"filter":{"type":"or","fields":[]},"aggregations":[],"postAggregations":[],"intervals":["1901-01-01T00:00:00+00:00/2101-01-01T00:00:00+00:00"]},

"question_response_query" : {"queryType":"scan","dataSource":"sl-observation","resultFormat": "list","columns":[ "solutionName", "criteriaName", "domainName", "questionName", "programName", "questionResponseLabel", "observationSubmissionId", "questionResponseType", "questionId", "questionSequenceByEcm","solution_type"],"filter": {"type":"and","fields": [ { "type": "or", "fields": [ { "type": "selector", "dimension": "questionResponseType", "value": "radio" }, { "type": "selector", "dimension": "questionResponseType", "value": "multiselect" }, { "type": "selector", "dimension": "questionResponseType", "value": "slider" } ] } ] },"intervals":"1901-01-01T00:00:00+00:00/2101-01-01T00:00:00+00:00"}
"question_response_query" : {"queryType":"scan","dataSource":"sl-observation","resultFormat": "list","columns":[ "solutionName", "criteriaName", "domainName", "questionName", "programName", "questionResponseLabel", "observationSubmissionId", "questionResponseType", "questionId", "questionSequenceByEcm","solution_type"],"filter": {"type":"and","fields": [ { "type": "or", "fields": [ { "type": "selector", "dimension": "questionResponseType", "value": "radio" }, { "type": "selector", "dimension": "questionResponseType", "value": "multiselect" }, { "type": "selector", "dimension": "questionResponseType", "value": "slider" } ] } ] },"intervals":"1901-01-01T00:00:00+00:00/2101-01-01T00:00:00+00:00"},

"solution_distric_level_query": {"queryType": "groupBy","dataSource": "","dimensions": ["district_name", "district_externalId"],"granularity": "all","intervals": "1901-01-01T00:00:00+00:00/2101-01-01T00:00:00+00:00","filter": {"type": "and","fields": []}},

"solution_organisations_level_query": {"queryType": "groupBy","dataSource": "","dimensions": ["organisation_id", "organisation_name"],"granularity": "all","intervals": "1901-01-01T00:00:00+00:00/2101-01-01T00:00:00+00:00","filter": {"type": "and","fields": []}},

"solution_block_level_query": {"queryType": "groupBy","dataSource": "","dimensions": ["block_externalId", "block_name"],"granularity": "all","intervals": "1901-01-01T00:00:00+00:00/2101-01-01T00:00:00+00:00","filter": {"type": "and","fields": []}},

"program_distric_level_query": {"queryType": "groupBy","dataSource": "","dimensions": ["district_name", "district_id"],"granularity": "all","intervals": "1901-01-01T00:00:00+00:00/2101-01-01T00:00:00+00:00","filter": {"type": "and","fields": []}},

"program_organisations_level_query": {"queryType": "groupBy","dataSource": "","dimensions": ["organisation_id", "organisation_name"],"granularity": "all","intervals": "1901-01-01T00:00:00+00:00/2101-01-01T00:00:00+00:00","filter": {"type": "and","fields": []}},

"program_block_level_query": {"queryType": "groupBy","dataSource": "","dimensions": ["block_id", "block_name"],"granularity": "all","intervals": "1901-01-01T00:00:00+00:00/2101-01-01T00:00:00+00:00","filter": {"type": "and","fields": []}}
}
3 changes: 2 additions & 1 deletion common/endpoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ module.exports = {
AZURE_GET_DOWNLOADABLE_URL : "/v1/cloud-services/azure/getDownloadableUrl",
AWS_GET_DOWNLOADABLE_URL : "/v1/cloud-services/aws/getDownloadableUrl",
GET_PRESIGNED_URL : "/v1/cloud-services/files/preSignedUrls",
GET_DOWNLOADABLE_URL: "/v1/cloud-services/files/getDownloadableUrl"
GET_DOWNLOADABLE_URL: "/v1/cloud-services/files/getDownloadableUrl",
GET_USER_EXTENSION : "/v1/user-extension/read"
}
43 changes: 41 additions & 2 deletions common/utils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const druidQueries = require('./druid_queries.json');

const { ResourceType, SolutionType } = require("./constants");
/**
* Return druid query for the given query name
* @function
Expand Down Expand Up @@ -80,10 +80,49 @@ function getDruidIntervalDate( data ) {
return isoSring;
}

/**
* Returns Druid Data source Name
* @function
* @name getDataSourceName
* @returns {String} returns druid data source name.
*/
function getDataSourceName (query, body){
let dataSource
if(query.resourceType === ResourceType.PROGRAM){
dataSource = process.env.PROGRAM_RESOURCE_DATASOURCE_NAME
}else {
switch (body.solutionType) {
case SolutionType.PROJECT : dataSource = process.env.PROJECT_RESOURCE_DATASOURCE_NAME
break;
case SolutionType.OBSERVATION : dataSource = process.env.OBSERVATION_RESOURCE_DATASOURCE_NAME
break;
case SolutionType.SURVEY : dataSource = process.env.SURVEY_RESOURCE_DATASOURCE_NAME
break;
}
}
return dataSource
}

/**
* Returns Druid Query Filter
* @function
* @name getResourceFilter
* @returns {String} returns druid query filter
*/
function getResourceFilter (query) {
const resourceFilter = {
type: "selector",
dimension: query.resourceType == ResourceType.SOLUTION ? "solution_id" : "program_id",
value: query.resourceId
}
return resourceFilter
}

module.exports = {
getDruidQuery: getDruidQuery,
getDruidConnection: getDruidConnection,
getGotenbergConnection: getGotenbergConnection,
getDruidIntervalDate: getDruidIntervalDate
getDruidIntervalDate: getDruidIntervalDate,
getDataSourceName: getDataSourceName,
getResourceFilter:getResourceFilter
}
111 changes: 111 additions & 0 deletions controllers/v1/resource.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/**
* name : resource.js
* author : Ankit Shahu
* created-date : 10-April-2023
* Description : Resource level data for program and solution.
*/


const resourceHelper = require("../../helper/resource")
const {ResourceType, ResourceTypeProjection} = require("../../common/constants")

/**
* @api {post} /mlreports/api/v1/resource/filtervalues?resourceType=program&resourceId=6013eab15faeea0e88a26ef5
* List of data based on collection
* @apiVersion 1.0.0
* @apiGroup public
* @apiSampleRequest /mlreports/api/v1/resource/filtervalues
* @param {json} Request-Body:
{
"projection": "block",
"query":{ // optional required for block
"districtLocationId": "b5c35cfc-6c1e-4266-94ef-a425c43c7f4e"
}
"solutionType": "observation"/"survey"/"improvementProject" //Required only for resourceType=solution,
"programId": "6013eab15faeea0e88a26efd"
}
* @apiParamExample {json} Response:
* {
"message": "Program resource fetched successfully ",
"status": 200,
"result": {
"districts": [
{
"id": "98ae45d7-9257-4c14-a16a-9760a442ff28",
"name": "PRAKASAM"
},
{
"id": "0c0391ba-610b-4796-8645-338d047b1e28",
"name": "TIRUVALLUR"
}
],
"organisations": [
{
"id": "0126796199493140480",
"name": "Staging Custodian Organization"
}
]
}
* }
* @apiUse successBody
* @apiUse errorBody
*/

/**
* List of data based on collection
* @method
* @name filtervalues
* @returns {JSON} list of data.
*/
exports.filtervalues = async function (req, res) {

//userExtension will validate whether user have access to the program as designer or manager.
const userExtension = await resourceHelper.userExtensions(req,res);
if(userExtension){
if(req.query.resourceType == ResourceType.PROGRAM || req.query.resourceType == ResourceType.SOLUTION){
if(!req.query.resourceId){
res.status(400).send({
message: "Resource id not passed"
})
}
if(req.body.projection == ResourceTypeProjection.DISTRICT){
//Gets list of district where program or solution started
const getDistict = await resourceHelper.getDistricts( req ,res)
//Gets list of Organisation where program or solution started
const getOrganisation = await resourceHelper.getOrganisations(req,res)
if(getDistict || getOrganisation){
const districtOrganisationResponse = {
message: req.query.resourceType == ResourceType.SOLUTION? "Solution details fetched successfully":"Program details fetched successfully",
status: "success",
result:{
districts: getDistict,
organisations: getOrganisation
}
}
res.status(200).send(districtOrganisationResponse)
}
} else if(req.body.projection == ResourceTypeProjection.BLOCK){
//Gets list of block where program or solution started
const getBlock = await resourceHelper.getBlocks( req,res )
if(getBlock){
const blockResponse = {
message: req.query.resourceType == ResourceType.SOLUTION? "Solution details fetched successfully":"Program details fetched successfully",
status: "success",
result:{
block: getBlock,
}
}
res.status(200).send(blockResponse)
}
}
}else{
res.status(400).send({
message: "No data found"
})
}
}else {
res.status(401).send({
message: "You are not authorised to access this resource"
})
}
}
16 changes: 16 additions & 0 deletions envVariables.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,22 @@ let enviromentVariables = {
"message" : "Required",
"optional" : false
},
"PROJECT_RESOURCE_DATASOURCE_NAME" : {
"message" : "Required",
"optional" : false
},
"OBSERVATION_RESOURCE_DATASOURCE_NAME" : {
"message" : "Required",
"optional" : false
},
"SURVEY_RESOURCE_DATASOURCE_NAME" : {
"message" : "Required",
"optional" : false
},
"PROGRAM_RESOURCE_DATASOURCE_NAME" : {
"message" : "Required",
"optional" : false
},
"ENTITY_SCORE_REPORT_THRESHOLD" : {
"message" : "Required",
"optional" : false
Expand Down
30 changes: 29 additions & 1 deletion helper/kendra_service.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,36 @@ async function getPreSignedUrl(file) {
})
}

async function getUserExtension(token){
return new Promise(async function (resolve, reject) {

let url = urlPrefix + endpoints.GET_USER_EXTENSION;
let options = {
method: "POST",
json: true,
headers: {
"x-authenticated-user-token": token,
"internal-access-token": process.env.INTERNAL_ACCESS_TOKEN,
"Content-Type": "application/json",
},
body: {},
uri: url
}

rp(options)
.then(result => {
return resolve(result);
})
.catch(err => {
return resolve(err);
})
})

}


module.exports = {
getDownloadableUrl: getDownloadableUrl,
getPreSignedUrl: getPreSignedUrl
getPreSignedUrl: getPreSignedUrl,
getUserExtension:getUserExtension
}
Loading

0 comments on commit b546a44

Please sign in to comment.