From 37112967d273ba80b48692b3385766ca9ecf6b55 Mon Sep 17 00:00:00 2001 From: Joe Armani <93854858+JoeArmani@users.noreply.github.com> Date: Tue, 26 Nov 2024 10:27:38 -0500 Subject: [PATCH 1/2] await response from 'submit' endpoint --- utils/connectApp.js | 20 ++++++- utils/firestore.js | 17 +++--- utils/shared.js | 2 +- utils/submission.js | 137 +++++++++++++++++++++----------------------- 4 files changed, 92 insertions(+), 84 deletions(-) diff --git a/utils/connectApp.js b/utils/connectApp.js index 492aee54..bafdf978 100644 --- a/utils/connectApp.js +++ b/utils/connectApp.js @@ -1,5 +1,5 @@ const { getResponseJSON, setHeadersDomainRestricted, getUserProfile } = require('./shared'); -const { recruitSubmit, submitSocial, getUserSurveys, getUserCollections } = require('./submission'); +const { submit, submitSocial, getUserSurveys, getUserCollections } = require('./submission'); const { retrieveNotifications, sendEmailLink } = require('./notifications'); const { validateToken, generateToken, updateParticipantFirebaseAuthentication, validateUsersEmailPhone } = require('./validation'); @@ -37,9 +37,23 @@ const connectApp = async (req, res) => { console.log(`PWA API: ${api}, called from uid: ${uid}`); try { - if (api === 'submit') return await recruitSubmit(req, res, uid); + if (api === 'submit') { - if (api === 'submitSocial') return submitSocial(req, res, uid); + if (req.method !== 'POST') { + return res.status(405).json(getResponseJSON('Only POST requests are accepted!', 405)); + } + + const body = req.body; + + if (!body || Object.keys(body).length === 0) { + return res.status(400).json(getResponseJSON('Bad request!', 400)); + } + + // all 'submit' paths return res.status(code).json({ message, code }); + return await submit(res, body, uid); + } + + else if (api === 'submitSocial') return submitSocial(req, res, uid); else if (api === 'getUserProfile') return getUserProfile(req, res, uid); diff --git a/utils/firestore.js b/utils/firestore.js index 0cebeb45..7bca5329 100644 --- a/utils/firestore.js +++ b/utils/firestore.js @@ -101,16 +101,19 @@ const updateResponse = async (data, uid) => { try{ const snapshot = await db.collection('participants').where('state.uid', '==', uid).get(); printDocsCount(snapshot, "updateResponse"); - if(snapshot.size === 1) { - for(let doc of snapshot.docs){ - await db.collection('participants').doc(doc.id).update(data); - return true; - } + + if (snapshot.size !== 1) { + throw new Error(`updateResponse expected 1 document, found ${snapshot.size}. uid: ${uid}`); } + + const docId = snapshot.docs[0].id; + + await db.collection('participants').doc(docId).update(data); + return true; } catch(error){ - console.error(error); - return new Error(error) + console.error(`Error in updateResponse: ${error}`); + return new Error(`Error in updateResponse: ${error}`); } } diff --git a/utils/shared.js b/utils/shared.js index b978ce07..2dcfc0e0 100644 --- a/utils/shared.js +++ b/utils/shared.js @@ -784,7 +784,7 @@ const cleanSurveyData = (data) => { const admin = require('firebase-admin'); Object.keys(data).forEach(key => { - if(data[key] === null) { + if(data[key] == null) { data[key] = admin.firestore.FieldValue.delete(); } }); diff --git a/utils/submission.js b/utils/submission.js index 326fc271..630c1351 100644 --- a/utils/submission.js +++ b/utils/submission.js @@ -2,95 +2,99 @@ const { getResponseJSON, setHeaders, logIPAddress } = require('./shared'); const fieldMapping = require('./fieldToConceptIdMapping'); const submit = async (res, data, uid) => { - // Remove locked attributes. const { lockedAttributes } = require('./shared'); lockedAttributes.forEach(atr => delete data[atr]); - // generate Connect_ID if Consent form submitted - if(data[919254129] !== undefined && data[919254129] === 353358909) { - const { generateConnectID } = require('./shared'); - const { sanityCheckConnectID } = require('./firestore'); - let boo = false; - let Connect_ID; - while(boo === false){ - const ID = generateConnectID(); - const response = await sanityCheckConnectID(ID); - if(response === true) { - Connect_ID = ID; - boo = true; + try { + // generate Connect_ID if Consent form submitted + if(data[919254129] !== undefined && data[919254129] === 353358909) { + const { generateConnectID } = require('./shared'); + const { sanityCheckConnectID } = require('./firestore'); + let boo = false; + let Connect_ID; + while(boo === false){ + const ID = generateConnectID(); + const response = await sanityCheckConnectID(ID); + if(response === true) { + Connect_ID = ID; + boo = true; + } } + data = {...data, Connect_ID} } - data = {...data, Connect_ID} - } - let keys = Object.keys(data); + let keys = Object.keys(data); - // check if submitting survey - if (keys.length === 1) { + // check if submitting survey + if (keys.length === 1) { - const { moduleConceptsToCollections } = require('./shared'); + const { moduleConceptsToCollections } = require('./shared'); - let key = keys[0]; - let collection = moduleConceptsToCollections[key]; + let key = keys[0]; + let collection = moduleConceptsToCollections[key]; - if(collection) { - let moduleData = data[key]; - return await submitSurvey(res, moduleData, collection, uid) + if(collection) { + let moduleData = data[key]; + return await submitSurvey(res, moduleData, collection, uid) + } } - } - const { cleanSurveyData } = require('./shared'); - data = cleanSurveyData(data); + const { cleanSurveyData } = require('./shared'); + data = cleanSurveyData(data); - const { updateResponse } = require('./firestore'); - const response = await updateResponse(data, uid); + const { updateResponse } = require('./firestore'); - if (response) { - let moduleComplete = false; - let calculateScores = false; + // response is either true or an Error object + const response = await updateResponse(data, uid); - keys.forEach(key => { - const { moduleStatusConcepts } = require('./shared'); + if (response) { + let moduleComplete = false; + let calculateScores = false; - if (moduleStatusConcepts[key] && data[key] === 231311385) { - moduleComplete = true; + keys.forEach(key => { + const { moduleStatusConcepts } = require('./shared'); - if (key === '320303124') { - calculateScores = true; + if (moduleStatusConcepts[key] && data[key] === 231311385) { + moduleComplete = true; + + if (key === '320303124') { + calculateScores = true; + } } - } - }) + }) - if(moduleComplete) { + if (moduleComplete) { - const { checkDerivedVariables } = require('./validation'); - const { getTokenForParticipant, retrieveUserProfile } = require('./firestore'); + const { checkDerivedVariables } = require('./validation'); + const { getTokenForParticipant, retrieveUserProfile } = require('./firestore'); - const participant = await retrieveUserProfile(uid); - const siteCode = participant['827220437']; - const token = await getTokenForParticipant(uid); + const participant = await retrieveUserProfile(uid); + const siteCode = participant['827220437']; + const token = await getTokenForParticipant(uid); - await checkDerivedVariables(token, siteCode); + await checkDerivedVariables(token, siteCode); - if (calculateScores) { + if (calculateScores) { - //remove condition once implemented in dev tier - if (process.env.GCLOUD_PROJECT === 'nih-nci-dceg-connect-stg-5519' || process.env.GCLOUD_PROJECT === 'nih-nci-dceg-connect-prod-6d04') { - const { processPromisResults } = require('./promis'); - processPromisResults(uid); + //remove condition once implemented in dev tier + if (process.env.GCLOUD_PROJECT === 'nih-nci-dceg-connect-stg-5519' || process.env.GCLOUD_PROJECT === 'nih-nci-dceg-connect-prod-6d04') { + const { processPromisResults } = require('./promis'); + processPromisResults(uid); + } } } } + + if (response instanceof Error) { + return res.status(500).json(getResponseJSON(response.message, 500)); + } + return res.status(200).json(getResponseJSON('Data stored successfully!', 200)); + + } catch (error) { + console.error('Error in submit:', error); + return res.status(500).json(getResponseJSON(error.message, 500)); } - - if(response instanceof Error){ - return res.status(500).json(getResponseJSON(response.message, 500)); - } - if(!response) { - return res.status(500).json(getResponseJSON("Can't add/update data!", 500)); - } - return res.status(200).json(getResponseJSON('Data stored successfully!', 200)); }; const submitSurvey = async (res, data, collection, uid) => { @@ -129,18 +133,6 @@ const submitSurvey = async (res, data, collection, uid) => { return res.status(200).json(getResponseJSON('Survey data stored successfully!', 200)); } -const recruitSubmit = async (req, res, uid) => { - if(req.method !== 'POST') { - return res.status(405).json(getResponseJSON('Only POST requests are accepted!', 405)); - } - - const data = req.body; - if(Object.keys(data).length <= 0){ - return res.status(400).json(getResponseJSON('Bad request!', 400)); - } - return await submit(res, data, uid); -} - const submitSocial = async (req, res, uid) => { if (req.method !== 'POST') { @@ -744,7 +736,6 @@ const getTextAndVersionNumberFromGitHubCommit = async (sha, path, token) => { module.exports = { submit, - recruitSubmit, submitSocial, getFilteredParticipants, getParticipants, From 9762932cd73b371e360c2af4ad1f47623646a4dd Mon Sep 17 00:00:00 2001 From: Joe Armani <93854858+JoeArmani@users.noreply.github.com> Date: Mon, 2 Dec 2024 09:29:31 -0500 Subject: [PATCH 2/2] updates --- utils/firestore.js | 4 +--- utils/shared.js | 2 +- utils/submission.js | 14 ++------------ 3 files changed, 4 insertions(+), 16 deletions(-) diff --git a/utils/firestore.js b/utils/firestore.js index 7bca5329..92a373fc 100644 --- a/utils/firestore.js +++ b/utils/firestore.js @@ -106,9 +106,7 @@ const updateResponse = async (data, uid) => { throw new Error(`updateResponse expected 1 document, found ${snapshot.size}. uid: ${uid}`); } - const docId = snapshot.docs[0].id; - - await db.collection('participants').doc(docId).update(data); + await snapshot.docs[0].ref.update(data); return true; } catch(error){ diff --git a/utils/shared.js b/utils/shared.js index 2dcfc0e0..dd895e5f 100644 --- a/utils/shared.js +++ b/utils/shared.js @@ -784,7 +784,7 @@ const cleanSurveyData = (data) => { const admin = require('firebase-admin'); Object.keys(data).forEach(key => { - if(data[key] == null) { + if (data[key] === null || data[key] === undefined) { data[key] = admin.firestore.FieldValue.delete(); } }); diff --git a/utils/submission.js b/utils/submission.js index 630c1351..c07cc65a 100644 --- a/utils/submission.js +++ b/utils/submission.js @@ -1,9 +1,9 @@ -const { getResponseJSON, setHeaders, logIPAddress } = require('./shared'); +const { cleanSurveyData, getResponseJSON, lockedAttributes, setHeaders, logIPAddress, moduleConceptsToCollections, moduleStatusConcepts } = require('./shared'); +const { updateResponse } = require('./firestore'); const fieldMapping = require('./fieldToConceptIdMapping'); const submit = async (res, data, uid) => { // Remove locked attributes. - const { lockedAttributes } = require('./shared'); lockedAttributes.forEach(atr => delete data[atr]); try { @@ -28,9 +28,6 @@ const submit = async (res, data, uid) => { // check if submitting survey if (keys.length === 1) { - - const { moduleConceptsToCollections } = require('./shared'); - let key = keys[0]; let collection = moduleConceptsToCollections[key]; @@ -40,21 +37,15 @@ const submit = async (res, data, uid) => { } } - const { cleanSurveyData } = require('./shared'); data = cleanSurveyData(data); - const { updateResponse } = require('./firestore'); - // response is either true or an Error object const response = await updateResponse(data, uid); - if (response) { let moduleComplete = false; let calculateScores = false; keys.forEach(key => { - const { moduleStatusConcepts } = require('./shared'); - if (moduleStatusConcepts[key] && data[key] === 231311385) { moduleComplete = true; @@ -65,7 +56,6 @@ const submit = async (res, data, uid) => { }) if (moduleComplete) { - const { checkDerivedVariables } = require('./validation'); const { getTokenForParticipant, retrieveUserProfile } = require('./firestore');