diff --git a/.circleci/config.yml b/.circleci/config.yml index b49f0029..5ae70314 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -70,9 +70,7 @@ workflows: branches: only: - develop - - fix/challenge-timelines-edit-routes - - test/performance-profile - - July2022Updates + - fix/task-memberId-reset # Production builds are exectuted only on tagged commits to the # master branch. diff --git a/src/common/helper.js b/src/common/helper.js index c349ecfb..0db4a781 100644 --- a/src/common/helper.js +++ b/src/common/helper.js @@ -889,7 +889,7 @@ async function listChallengesByMember (memberId) { // get search is paginated, we need to get all pages' data let page = 1 while (true) { - let result = {}; + let result = {} try { result = await axios.get(`${config.RESOURCES_API_URL}/${memberId}/challenges`, { headers: { Authorization: `Bearer ${token}` }, diff --git a/src/routes.js b/src/routes.js index 3c778369..b02f79fe 100644 --- a/src/routes.js +++ b/src/routes.js @@ -70,7 +70,7 @@ module.exports = { '/challenges/:challengeId/statistics': { get: { controller: 'ChallengeController', - method: 'getChallengeStatistics', + method: 'getChallengeStatistics' } }, '/challenges/:challengeId/notifications': { diff --git a/src/services/ChallengeService.js b/src/services/ChallengeService.js index ed15a9a7..ee691b2c 100644 --- a/src/services/ChallengeService.js +++ b/src/services/ChallengeService.js @@ -274,7 +274,7 @@ async function searchChallenges (currentUser, criteria) { { wildcard: { name: `*${criteria.search}*` } }, { wildcard: { name: `${criteria.search}*` } }, { wildcard: { name: `*${criteria.search}` } }, - { match_phrase: { tags: criteria.search } }, + { match_phrase: { tags: criteria.search } } ] } }) } else { @@ -1649,6 +1649,39 @@ async function update (currentUser, challengeId, data, isFull) { await validateWinners(data.winners, challengeId) } + // Only m2m tokens are allowed to modify the `task.*` information on a challenge + if (!_.isUndefined(_.get(data, 'task')) && !currentUser.isMachine) { + if (!_.isUndefined(_.get(challenge, 'task'))) { + logger.info(`User ${currentUser.handle || currentUser.sub} is not allowed to modify the task information on challenge ${challengeId}`) + data.task = challenge.task + logger.info(`Task information on challenge ${challengeId} is reset to ${JSON.stringify(challenge.task)}. Original data: ${JSON.stringify(data.task)}`) + } else { + delete data.task + } + } + + // task.memberId goes out of sync due to another processor setting "task.memberId" but subsequent immediate update to the task + // will not have the memberId set. So we need to set it using winners to ensure it is always in sync. The proper fix is to correct + // the sync issue in the processor. However this is quick fix that works since winner.userId is task.memberId. + if (_.get(challenge, 'legacy.pureV5Task') && !_.isUndefined(data.winners)) { + const winnerMemberId = _.get(data.winners, '[0].userId') + logger.info(`Setting task.memberId to ${winnerMemberId} for challenge ${challengeId}. Task ${_.get(data, 'task')} - ${_.get(challenge, 'task')}`) + + if (winnerMemberId != null && _.get(data, 'task.memberId') !== winnerMemberId) { + logger.info(`Task ${challengeId} has a winner ${winnerMemberId}`) + data.task = { + isTask: true, + isAssigned: true, + memberId: winnerMemberId + } + logger.warn(`task.memberId mismatched with winner memberId. task.memberId is updated to ${winnerMemberId}`) + } else { + logger.info(`task ${challengeId} has no winner set yet.`) + } + } else { + logger.info(`${challengeId} is not a pureV5 challenge or has no winners set yet.`) + } + data.updated = moment().utc() data.updatedBy = currentUser.handle || currentUser.sub const updateDetails = {} @@ -1709,6 +1742,9 @@ async function update (currentUser, challengeId, data, isFull) { op = '$PUT' } else if (_.isUndefined(challenge[key]) || challenge[key] !== value) { op = '$PUT' + } else if (_.get(challenge, 'legacy.pureV5Task') && key === 'task') { + // always update task for pureV5 challenges + op = '$PUT' } if (op) { @@ -1848,15 +1884,6 @@ async function update (currentUser, challengeId, data, isFull) { const { track, type } = await validateChallengeData(_.pick(challenge, ['trackId', 'typeId'])) - // Only m2m tokens are allowed to modify the `task.*` information on a challenge - if (!_.isUndefined(_.get(data, 'task')) && !currentUser.isMachine) { - if (!_.isUndefined(_.get(challenge, 'task'))) { - data.task = challenge.task - } else { - delete data.task - } - } - if (_.get(type, 'isTask')) { if (!_.isEmpty(_.get(data, 'task.memberId'))) { const challengeResources = await helper.getChallengeResources(challengeId)