From 2d541541814da4269479b7095bb2238505b56443 Mon Sep 17 00:00:00 2001 From: Josh Worden Date: Wed, 30 Jul 2025 12:54:04 -0500 Subject: [PATCH] Support setting unverified custom select answers --- .../src/actions/user/set-unverified-data.js | 21 +++++++++++- .../user/update-custom-select-answers.js | 29 ++-------------- .../user/utils/set-custom-select-answers.js | 34 +++++++++++++++++++ .../src/graphql/definitions/app-user.js | 3 ++ .../graphql/src/graphql/resolvers/app-user.js | 6 ++++ 5 files changed, 65 insertions(+), 28 deletions(-) create mode 100644 services/application/src/actions/user/utils/set-custom-select-answers.js diff --git a/services/application/src/actions/user/set-unverified-data.js b/services/application/src/actions/user/set-unverified-data.js index adf07480..7fb37dee 100644 --- a/services/application/src/actions/user/set-unverified-data.js +++ b/services/application/src/actions/user/set-unverified-data.js @@ -2,6 +2,7 @@ const { createError } = require('micro'); const { createRequiredParamError } = require('@base-cms/micro').service; const { isObject, asArray } = require('@base-cms/utils'); const setConsentAnswer = require('./utils/set-regional-consent-answer'); +const setCustomSelectAnswers = require('./utils/set-custom-select-answers'); const { AppUser } = require('../../mongodb/models'); @@ -16,7 +17,25 @@ module.exports = async ({ applicationId, email, payload } = {}) => { // do nothing if the user is already verified. if (user.verified) return user; - const { regionalConsentAnswers, ...fields } = payload; + const { + // customBooleanFieldAnswers, + customSelectFieldAnswers, + // customTextFieldAnswers, + regionalConsentAnswers, + ...fields + } = payload; + + // if (asArray(customBooleanFieldAnswers).length) { + // setCustomBooleanAnswers({ user, answers: customBooleanFieldAnswers }); + // } + + if (asArray(customSelectFieldAnswers).length) { + setCustomSelectAnswers({ user, answers: customSelectFieldAnswers }); + } + + // if (asArray(customTextFieldAnswers).length) { + // setCustomTextAnswers({ user, answers: customTextFieldAnswers }); + // } // overwrite/set regional consent answers user.set('regionalConsentAnswers', []); diff --git a/services/application/src/actions/user/update-custom-select-answers.js b/services/application/src/actions/user/update-custom-select-answers.js index be066797..adcf5e15 100644 --- a/services/application/src/actions/user/update-custom-select-answers.js +++ b/services/application/src/actions/user/update-custom-select-answers.js @@ -3,6 +3,7 @@ const { createRequiredParamError } = require('@base-cms/micro').service; const { handleError } = require('@identity-x/utils').mongoose; const { AppUser } = require('../../mongodb/models'); +const setCustomSelectAnswers = require('./utils/set-custom-select-answers'); const { isArray } = Array; @@ -21,34 +22,8 @@ module.exports = async ({ // do not update user answers when passed answers are not an array if (!isArray(answers)) return user; - // get all current answers as object { id, value } - const userObj = user.customSelectFieldAnswers.reduce((obj, { _id, values, writeInValues }) => ({ - ...obj, - [_id]: { values, writeInValues }, - }), {}); + setCustomSelectAnswers({ user, answers }); - const newAnswers = answers - // Allow for optionIds to be empty if forceUnset is set to true - .filter(({ optionIds, forceUnset }) => optionIds.length || forceUnset) - .map(item => ({ _id: item.fieldId, ...item })) - .reduce((obj, { _id, optionIds, writeInValues }) => ({ - ...obj, - [_id]: { - values: optionIds, - writeInValues: (writeInValues || []).map(v => ({ _id: v.optionId, value: v.value })), - }, - }), {}); - - // merge new and old answers to account for old non active answers - const mergedAnswers = { ...userObj, ...newAnswers }; - - // convert merged answers into valid array of { _id, values } answers - const toSet = Object.keys(mergedAnswers).map((key) => { - const { values, writeInValues } = mergedAnswers[key]; - return { _id: key, values, writeInValues }; - }); - - user.set('customSelectFieldAnswers', toSet); if (profileLastVerifiedAt) { user.set('profileLastVerifiedAt', profileLastVerifiedAt); user.set('forceProfileReVerification', false); diff --git a/services/application/src/actions/user/utils/set-custom-select-answers.js b/services/application/src/actions/user/utils/set-custom-select-answers.js new file mode 100644 index 00000000..2b18b01a --- /dev/null +++ b/services/application/src/actions/user/utils/set-custom-select-answers.js @@ -0,0 +1,34 @@ +const { createRequiredParamError } = require('@base-cms/micro').service; + +module.exports = ({ user, answers }) => { + if (!answers) throw createRequiredParamError('answers'); + + // get all current answers as object { id, value } + const userObj = user.customSelectFieldAnswers.reduce((obj, { _id, values, writeInValues }) => ({ + ...obj, + [_id]: { values, writeInValues }, + }), {}); + + const newAnswers = answers + // Allow for optionIds to be empty if forceUnset is set to true + .filter(({ optionIds, forceUnset }) => optionIds.length || forceUnset) + .map(item => ({ _id: item.fieldId, ...item })) + .reduce((obj, { _id, optionIds, writeInValues }) => ({ + ...obj, + [_id]: { + values: optionIds, + writeInValues: (writeInValues || []).map(v => ({ _id: v.optionId, value: v.value })), + }, + }), {}); + + // merge new and old answers to account for old non active answers + const mergedAnswers = { ...userObj, ...newAnswers }; + + // convert merged answers into valid array of { _id, values } answers + const toSet = Object.keys(mergedAnswers).map((key) => { + const { values, writeInValues } = mergedAnswers[key]; + return { _id: key, values, writeInValues }; + }); + + user.set('customSelectFieldAnswers', toSet); +}; diff --git a/services/graphql/src/graphql/definitions/app-user.js b/services/graphql/src/graphql/definitions/app-user.js index 48cf391d..f45ba80e 100644 --- a/services/graphql/src/graphql/definitions/app-user.js +++ b/services/graphql/src/graphql/definitions/app-user.js @@ -459,6 +459,9 @@ input SetAppUserUnverifiedDataMutationInput { mobileNumber: String phoneNumber: String + # customBooleanFieldAnswers: [UpdateAppUserCustomBooleanAnswer!] = [] + customSelectFieldAnswers: [UpdateAppUserCustomSelectAnswer!] = [] + # customTextFieldAnswers: [UpdateAppUserCustomTextAnswer!] = [] regionalConsentAnswers: [SetAppUserRegionalConsentAnswerInput!] = [] } diff --git a/services/graphql/src/graphql/resolvers/app-user.js b/services/graphql/src/graphql/resolvers/app-user.js index 0094e7a8..7994dd5d 100644 --- a/services/graphql/src/graphql/resolvers/app-user.js +++ b/services/graphql/src/graphql/resolvers/app-user.js @@ -612,6 +612,9 @@ module.exports = { mobileNumber, phoneNumber, regionalConsentAnswers, + // customBooleanFieldAnswers, + customSelectFieldAnswers, + // customTextFieldAnswers, } = input; const payload = { @@ -628,6 +631,9 @@ module.exports = { mobileNumber, phoneNumber, regionalConsentAnswers, + // customBooleanFieldAnswers, + customSelectFieldAnswers, + // customTextFieldAnswers, }; return applicationService.request('user.setUnverifiedData', {