From 1fe253221c4eee02ae32a3cf4419c46678981736 Mon Sep 17 00:00:00 2001 From: Thomas Kranitsas Date: Thu, 1 Apr 2021 03:17:51 +0300 Subject: [PATCH 01/15] use onsiteEfforts and offshoreEfforts --- src/utils/metadataExtractor.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/metadataExtractor.js b/src/utils/metadataExtractor.js index dea646e..c8fb45c 100644 --- a/src/utils/metadataExtractor.js +++ b/src/utils/metadataExtractor.js @@ -165,7 +165,7 @@ function extractEstimateEffortHours (challenge, defaultValue) { * @param {Any} defaultValue the default value */ function extractEstimateEffortOffshore (challenge, defaultValue) { - const entry = getMeta(challenge.metadata, 'effortHoursOffshore') + const entry = getMeta(challenge.metadata, 'offshoreEfforts') if (!entry) return _.toString(defaultValue) return _.toNumber(entry.value) } @@ -176,7 +176,7 @@ function extractEstimateEffortOffshore (challenge, defaultValue) { * @param {Any} defaultValue the default value */ function extractEstimateEffortOnsite (challenge, defaultValue) { - const entry = getMeta(challenge.metadata, 'effortHoursOnshore') + const entry = getMeta(challenge.metadata, 'onsiteEfforts') if (!entry) return _.toString(defaultValue) return _.toNumber(entry.value) } From 7a2a8af6f0d959416cc2ae4e20732bdc3a678428 Mon Sep 17 00:00:00 2001 From: Thomas Kranitsas Date: Tue, 6 Apr 2021 01:13:41 +0300 Subject: [PATCH 02/15] Set the copilot payment to 0 if it's not defined --- src/services/ProcessorService.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/services/ProcessorService.js b/src/services/ProcessorService.js index c4e0d54..cb6baeb 100644 --- a/src/services/ProcessorService.js +++ b/src/services/ProcessorService.js @@ -254,7 +254,7 @@ async function associateChallengeTerms (v5Terms, legacyChallengeId, createdBy, u */ async function setCopilotPayment (challengeId, legacyChallengeId, prizeSets = [], createdBy, updatedBy, m2mToken) { try { - const copilotPayment = _.get(_.find(prizeSets, p => p.type === config.COPILOT_PAYMENT_TYPE), 'prizes[0].value', null) + const copilotPayment = _.get(_.find(prizeSets, p => p.type === config.COPILOT_PAYMENT_TYPE), 'prizes[0].value', 0) if (copilotPayment) { logger.debug('Fetching challenge copilot...') const res = await helper.getRequest(`${config.V5_RESOURCES_API_URL}?challengeId=${challengeId}&roleId=${config.COPILOT_ROLE_ID}`, m2mToken) @@ -264,9 +264,7 @@ async function setCopilotPayment (challengeId, legacyChallengeId, prizeSets = [] return } logger.debug(`Setting Copilot Payment: ${copilotPayment} for legacyId ${legacyChallengeId} for copilot ${copilotResource.memberId}`) - if (copilotPayment !== null && copilotPayment >= 0) { - await copilotPaymentService.setManualCopilotPayment(legacyChallengeId, createdBy, updatedBy) - } + await copilotPaymentService.setManualCopilotPayment(legacyChallengeId, createdBy, updatedBy) await copilotPaymentService.setCopilotPayment(legacyChallengeId, copilotPayment, createdBy, updatedBy) } } catch (e) { From 4a5274b240e2e6ad44c2201bfc03de9484af0a0b Mon Sep 17 00:00:00 2001 From: Thomas Kranitsas Date: Tue, 6 Apr 2021 19:03:37 +0300 Subject: [PATCH 03/15] always set the copilot payment --- src/services/ProcessorService.js | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/services/ProcessorService.js b/src/services/ProcessorService.js index cb6baeb..2f44db6 100644 --- a/src/services/ProcessorService.js +++ b/src/services/ProcessorService.js @@ -255,18 +255,16 @@ async function associateChallengeTerms (v5Terms, legacyChallengeId, createdBy, u async function setCopilotPayment (challengeId, legacyChallengeId, prizeSets = [], createdBy, updatedBy, m2mToken) { try { const copilotPayment = _.get(_.find(prizeSets, p => p.type === config.COPILOT_PAYMENT_TYPE), 'prizes[0].value', 0) - if (copilotPayment) { - logger.debug('Fetching challenge copilot...') - const res = await helper.getRequest(`${config.V5_RESOURCES_API_URL}?challengeId=${challengeId}&roleId=${config.COPILOT_ROLE_ID}`, m2mToken) - const [copilotResource] = res.body - if (!copilotResource) { - logger.warn(`Copilot does not exist for challenge ${challengeId} (legacy: ${legacyChallengeId})`) - return - } - logger.debug(`Setting Copilot Payment: ${copilotPayment} for legacyId ${legacyChallengeId} for copilot ${copilotResource.memberId}`) - await copilotPaymentService.setManualCopilotPayment(legacyChallengeId, createdBy, updatedBy) - await copilotPaymentService.setCopilotPayment(legacyChallengeId, copilotPayment, createdBy, updatedBy) + logger.debug('Fetching challenge copilot...') + const res = await helper.getRequest(`${config.V5_RESOURCES_API_URL}?challengeId=${challengeId}&roleId=${config.COPILOT_ROLE_ID}`, m2mToken) + const [copilotResource] = res.body + if (!copilotResource) { + logger.warn(`Copilot does not exist for challenge ${challengeId} (legacy: ${legacyChallengeId})`) + return } + logger.debug(`Setting Copilot Payment: ${copilotPayment} for legacyId ${legacyChallengeId} for copilot ${copilotResource.memberId}`) + await copilotPaymentService.setManualCopilotPayment(legacyChallengeId, createdBy, updatedBy) + await copilotPaymentService.setCopilotPayment(legacyChallengeId, copilotPayment, createdBy, updatedBy) } catch (e) { logger.error('Failed to set the copilot payment!') logger.debug(e) From fdf0ee54e841887ec1069f8abd83663630f61167 Mon Sep 17 00:00:00 2001 From: Thomas Kranitsas Date: Thu, 29 Apr 2021 21:34:30 +0300 Subject: [PATCH 04/15] sync phases on tasks --- src/services/ProcessorService.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/services/ProcessorService.js b/src/services/ProcessorService.js index 2f44db6..8b5180e 100644 --- a/src/services/ProcessorService.js +++ b/src/services/ProcessorService.js @@ -688,12 +688,7 @@ async function processMessage (message) { logger.info('Challenge type is not a task.. Skip closing challenge...') } } - - if (!_.get(message.payload, 'task.isTask')) { - await syncChallengePhases(legacyId, message.payload.phases) - } else { - logger.info('Will skip syncing phases as the challenge is a task...') - } + await syncChallengePhases(legacyId, message.payload.phases) } try { From e8bfe0342ffce1dbfaa0134489ac2452ba8ea7b1 Mon Sep 17 00:00:00 2001 From: Thomas Kranitsas Date: Thu, 29 Apr 2021 22:50:12 +0300 Subject: [PATCH 05/15] Revert "sync phases on tasks" This reverts commit fdf0ee54e841887ec1069f8abd83663630f61167. --- src/services/ProcessorService.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/services/ProcessorService.js b/src/services/ProcessorService.js index 8b5180e..2f44db6 100644 --- a/src/services/ProcessorService.js +++ b/src/services/ProcessorService.js @@ -688,7 +688,12 @@ async function processMessage (message) { logger.info('Challenge type is not a task.. Skip closing challenge...') } } - await syncChallengePhases(legacyId, message.payload.phases) + + if (!_.get(message.payload, 'task.isTask')) { + await syncChallengePhases(legacyId, message.payload.phases) + } else { + logger.info('Will skip syncing phases as the challenge is a task...') + } } try { From 1cf9e085e0d7fd8e25d86895836cf377699d89aa Mon Sep 17 00:00:00 2001 From: Thomas Kranitsas Date: Thu, 29 Apr 2021 22:57:20 +0300 Subject: [PATCH 06/15] Ignore messages from configured originators --- config/default.js | 4 +++- src/app.js | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/config/default.js b/config/default.js index 4a1844b..a87a344 100644 --- a/config/default.js +++ b/config/default.js @@ -85,5 +85,7 @@ module.exports = { SYNC_V5_TERM_UUID: process.env.SYNC_V5_TERM_UUID || '317cd8f9-d66c-4f2a-8774-63c612d99cd4', SYNC_V5_WRITE_ENABLED: process.env.SYNC_V5_WRITE_ENABLED === 'true' || false, - TIMEZONE: process.env.TIMEZONE || 'America/New_York' + TIMEZONE: process.env.TIMEZONE || 'America/New_York', + + IGNORED_ORIGINATORS: process.env.IGNORED_ORIGINATORS ? process.env.IGNORED_ORIGINATORS.split(',') : ['legacy-migration-script'] } diff --git a/src/app.js b/src/app.js index e14212a..80b2a3f 100644 --- a/src/app.js +++ b/src/app.js @@ -46,6 +46,14 @@ const dataHandler = (messageSet, topic, partition) => Promise.each(messageSet, a return } + if (_.includes(config.IGNORED_ORIGINATORS, messageJSON.originator)) { + logger.error(`The message originator is in the ignored list. Originator: ${messageJSON.originator}`) + + // commit the message and ignore it + await consumer.commitOffset({ topic, partition, offset: m.offset }) + return + } + // do not trust the message payload // the message.payload will be replaced with the data from the API try { From 7fc9a0cd863a1bd07a301b2baa054bbfcbf6272a Mon Sep 17 00:00:00 2001 From: Thomas Kranitsas Date: Mon, 3 May 2021 20:37:54 +0300 Subject: [PATCH 07/15] Extract markup metadata --- src/constants.js | 5 +++++ src/utils/metadataExtractor.js | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/constants.js b/src/constants.js index c59b2ae..61a5d88 100644 --- a/src/constants.js +++ b/src/constants.js @@ -68,6 +68,11 @@ const supportedMetadata = { defaultValue: 0, description: 'DR points' }, + 57: { + method: metadataExtractor.extractMarkup, + defaultValue: 0, + description: 'Markup' + }, 35: { method: metadataExtractor.extractSpecReviewCost, defaultValue: null, diff --git a/src/utils/metadataExtractor.js b/src/utils/metadataExtractor.js index c8fb45c..48bd3f8 100644 --- a/src/utils/metadataExtractor.js +++ b/src/utils/metadataExtractor.js @@ -19,6 +19,15 @@ function extractBillingProject (challenge, defaultValue) { return _.get(challenge, 'billingAccountId', _.get(challenge, 'billing.billingAccountId', _.toString(defaultValue))) } +/** + * Extract markup + * @param {Object} challenge the challenge object + * @param {Any} defaultValue the default value + */ +function extractMarkup (challenge, defaultValue) { + return _.toString(_.get(challenge, 'billing.markup', defaultValue)) +} + /** * Extract submission limit * @param {Object} challenge the challenge object @@ -182,6 +191,7 @@ function extractEstimateEffortOnsite (challenge, defaultValue) { } module.exports = { + extractMarkup, extractBillingProject, extractSubmissionLimit, extractSpecReviewCost, From deb253414b3c52d70f1792b4c2f4be9a5a570404 Mon Sep 17 00:00:00 2001 From: Thomas Kranitsas Date: Tue, 1 Jun 2021 16:27:58 +0300 Subject: [PATCH 08/15] skip pureV5 challenges --- src/services/ProcessorService.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/ProcessorService.js b/src/services/ProcessorService.js index 2f44db6..3ca635e 100644 --- a/src/services/ProcessorService.js +++ b/src/services/ProcessorService.js @@ -605,8 +605,8 @@ async function createChallenge (saveDraftContestDTO, challengeUuid, createdByUse * @param {Object} message the kafka message */ async function processMessage (message) { - if (_.get(message, 'payload.legacy.pureV5Task')) { - logger.debug(`Challenge ${message.payload.id} is a pure v5 task. Will skip...`) + if (_.get(message, 'payload.legacy.pureV5Task') || _.get(message, 'payload.legacy.pureV5')) { + logger.debug(`Challenge ${message.payload.id} is a pure v5 task or challenge. Will skip...`) return } From ba3a6a7e2d5128525de55e36c59f79be3ca37bee Mon Sep 17 00:00:00 2001 From: James Cori Date: Tue, 6 Jul 2021 10:53:01 -0400 Subject: [PATCH 09/15] Debugging Terms --- src/services/ProcessorService.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/services/ProcessorService.js b/src/services/ProcessorService.js index 3ca635e..d3afff1 100644 --- a/src/services/ProcessorService.js +++ b/src/services/ProcessorService.js @@ -216,10 +216,10 @@ async function associateChallengeTerms (v5Terms, legacyChallengeId, createdBy, u const standardTerms = _.find(v5Terms, e => e.id === config.V5_TERMS_STANDARD_ID) const legacyStandardTerms = _.find(legacyTermsArray, e => _.toNumber(e.id) === _.toNumber(config.LEGACY_TERMS_STANDARD_ID)) - // logger.debug(`NDA: ${config.V5_TERMS_NDA_ID} - ${JSON.stringify(nda)}`) - // logger.debug(`Standard Terms: ${config.V5_TERMS_STANDARD_ID} - ${JSON.stringify(standardTerms)}`) - // logger.debug(`Legacy NDA: ${JSON.stringify(legacyNDA)}`) - // logger.debug(`Legacy Standard Terms: ${JSON.stringify(legacyStandardTerms)}`) + logger.debug(`NDA: ${config.V5_TERMS_NDA_ID} - ${JSON.stringify(nda)}`) + logger.debug(`Standard Terms: ${config.V5_TERMS_STANDARD_ID} - ${JSON.stringify(standardTerms)}`) + logger.debug(`Legacy NDA: ${JSON.stringify(legacyNDA)}`) + logger.debug(`Legacy Standard Terms: ${JSON.stringify(legacyStandardTerms)}`) const m2mToken = await helper.getM2MToken() if (standardTerms && standardTerms.id && !legacyStandardTerms) { From de6d90ccb94fee9d995d8a1d73927ec0ad493d63 Mon Sep 17 00:00:00 2001 From: Thomas Kranitsas Date: Thu, 30 Sep 2021 15:20:01 +0300 Subject: [PATCH 10/15] redeployed --- ReadMe.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ReadMe.md b/ReadMe.md index 98cfdfe..86c0264 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -207,6 +207,7 @@ npm run e2e - TBD + ## Verification Refer to the verification document `Verification.md` From cabb59c2f9b0af0883c0f8dcd30048cdc6e2d0c6 Mon Sep 17 00:00:00 2001 From: Thomas Kranitsas Date: Fri, 21 Jan 2022 15:34:21 +0200 Subject: [PATCH 11/15] map payment failed status to failed screening --- src/constants.js | 3 ++- src/services/ProcessorService.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/constants.js b/src/constants.js index 61a5d88..1430b85 100644 --- a/src/constants.js +++ b/src/constants.js @@ -43,7 +43,8 @@ const challengeStatuses = { CancelledWinnerUnresponsive: 'Cancelled - Winner Unresponsive', CancelledClientRequest: 'Cancelled - Client Request', CancelledRequirementsInfeasible: 'Cancelled - Requirements Infeasible', - CancelledZeroRegistrations: 'Cancelled - Zero Registrations' + CancelledZeroRegistrations: 'Cancelled - Zero Registrations', + CancelledPaymentFailed: 'Cancelled - Payment Failed' } const PhaseStatusTypes = { diff --git a/src/services/ProcessorService.js b/src/services/ProcessorService.js index d3afff1..91bc7d4 100644 --- a/src/services/ProcessorService.js +++ b/src/services/ProcessorService.js @@ -372,7 +372,7 @@ async function parsePayload (payload, m2mToken) { name: payload.name, reviewType: _.get(payload, 'legacy.reviewType', 'INTERNAL'), projectId, - status: payload.status + status: payload.status === constants.challengeStatuses.CancelledPaymentFailed ? constants.challengeStatuses.CancelledFailedScreening : payload.status } if (payload.billingAccountId) { data.billingAccountId = payload.billingAccountId From 31c3b4096f15cd3e547f7c21e3d5bcac339825b0 Mon Sep 17 00:00:00 2001 From: Thomas Kranitsas Date: Sat, 22 Jan 2022 01:11:38 +0200 Subject: [PATCH 12/15] Ignore approved state --- src/constants.js | 1 + src/services/ProcessorService.js | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/src/constants.js b/src/constants.js index 1430b85..60ec940 100644 --- a/src/constants.js +++ b/src/constants.js @@ -33,6 +33,7 @@ const createChallengeStatusesMap = { const challengeStatuses = { New: 'New', Draft: 'Draft', + Approved: 'Approved', Canceled: 'Canceled', Active: 'Active', Completed: 'Completed', diff --git a/src/services/ProcessorService.js b/src/services/ProcessorService.js index 91bc7d4..1182050 100644 --- a/src/services/ProcessorService.js +++ b/src/services/ProcessorService.js @@ -615,6 +615,11 @@ async function processMessage (message) { return } + if (message.payload.status === constants.challengeStatuses.Approved) { + logger.debug(`Will skip updating on legacy as status is ${constants.challengeStatuses.Approved}`) + return + } + logger.info(`Processing Kafka Message: ${JSON.stringify(message)}`) const createdByUserHandle = _.get(message, 'payload.createdBy') From 78cdaf1d682d8b2b5e7f82478b5b21bee5d417cb Mon Sep 17 00:00:00 2001 From: Thomas Kranitsas Date: Thu, 3 Feb 2022 04:37:45 +0200 Subject: [PATCH 13/15] set number of reviewers on self service challenges --- src/services/ProcessorService.js | 14 +++- src/services/selfServiceReviewerService.js | 84 ++++++++++++++++++++++ 2 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 src/services/selfServiceReviewerService.js diff --git a/src/services/ProcessorService.js b/src/services/ProcessorService.js index 1182050..4e167ae 100644 --- a/src/services/ProcessorService.js +++ b/src/services/ProcessorService.js @@ -16,6 +16,7 @@ const copilotPaymentService = require('./copilotPaymentService') const timelineService = require('./timelineService') const metadataService = require('./metadataService') const paymentService = require('./paymentService') +const { createOrSetNumberOfReviewers } = require('./selfServiceReviewerService') /** * Drop and recreate phases in ifx @@ -68,8 +69,10 @@ async function recreatePhases (legacyId, v5Phases, createdBy) { * Sync the information from the v5 phases into legacy * @param {Number} legacyId the legacy challenge ID * @param {Array} v5Phases the v5 phases + * @param {Boolean} isSelfService is the challenge self-service + * @param {String} createdBy the created by */ -async function syncChallengePhases (legacyId, v5Phases) { +async function syncChallengePhases (legacyId, v5Phases, createdBy, isSelfService) { const phaseTypes = await timelineService.getPhaseTypes() const phasesFromIFx = await timelineService.getChallengePhases(legacyId) logger.debug(`Phases from v5: ${JSON.stringify(v5Phases)}`) @@ -104,6 +107,10 @@ async function syncChallengePhases (legacyId, v5Phases) { } else { logger.info(`No v5 Equivalent Found for ${phaseName}`) } + if (isSelfService && phaseName === 'Review') { + // make sure to set the required reviewers to 2 + await createOrSetNumberOfReviewers(phase.project_phase_id, 2, createdBy) + } } // TODO: What about iterative reviews? There can be many for the same challenge. // TODO: handle timeline template updates @@ -695,7 +702,7 @@ async function processMessage (message) { } if (!_.get(message.payload, 'task.isTask')) { - await syncChallengePhases(legacyId, message.payload.phases) + await syncChallengePhases(legacyId, message.payload.phases, _.get(message, 'payload.legacy.selfService'), createdByUserId) } else { logger.info('Will skip syncing phases as the challenge is a task...') } @@ -721,7 +728,8 @@ processMessage.schema = { reviewType: Joi.string().required(), confidentialityType: Joi.string(), directProjectId: Joi.number(), - forumId: Joi.number().integer().positive() + forumId: Joi.number().integer().positive(), + selfService: Joi.boolean() }).unknown(true), task: Joi.object().keys({ isTask: Joi.boolean().default(false), diff --git a/src/services/selfServiceReviewerService.js b/src/services/selfServiceReviewerService.js new file mode 100644 index 0000000..5bf3cad --- /dev/null +++ b/src/services/selfServiceReviewerService.js @@ -0,0 +1,84 @@ +/** + * Number of reviewers Service + * Interacts with InformixDB + */ +const util = require('util') +const logger = require('../common/logger') +const helper = require('../common/helper') + +const QUERY_GET_ENTRY = 'SELECT parameter FROM phase_criteria WHERE project_phase_id = %d' +const QUERY_CREATE = 'INSERT INTO phase_criteria (project_phase_id, phase_criteria_type_id, parameter, create_user, create_date, modify_user, modify_date) VALUES (?, 6, ?, ?, CURRENT, ?, CURRENT)' +const QUERY_UPDATE = 'UPDATE phase_criteria SET parameter = ?, modify_user = ?, modify_date = CURRENT WHERE project_phase_id = ?' +const QUERY_DELETE = 'DELETE FROM phase_criteria WHERE project_phase_id = ?' + +/** + * Prepare Informix statement + * @param {Object} connection the Informix connection + * @param {String} sql the sql + * @return {Object} Informix statement + */ +async function prepare (connection, sql) { + // logger.debug(`Preparing SQL ${sql}`) + const stmt = await connection.prepareAsync(sql) + return Promise.promisifyAll(stmt) +} + +/** + * Get entry + * @param {Number} phaseId the phase ID + */ +async function getEntry (phaseId) { + // logger.debug(`Getting Groups for Challenge ${challengeLegacyId}`) + const connection = await helper.getInformixConnection() + let result = null + try { + result = await connection.queryAsync(util.format(QUERY_GET_ENTRY, phaseId)) + } catch (e) { + logger.error(`Error in 'getEntry' ${e}`) + throw e + } finally { + await connection.closeAsync() + } + return result +} + +/** + * Enable timeline notifications + * @param {Number} phaseId the legacy challenge ID + * @param {Number} typeId the type ID + * @param {Any} value the value + * @param {String} createdBy the created by + */ +async function createOrSetNumberOfReviewers (phaseId, value, createdBy) { + const connection = await helper.getInformixConnection() + let result = null + try { + await connection.beginTransactionAsync() + const [existing] = await getEntry(phaseId) + if (existing) { + if (value) { + const query = await prepare(connection, QUERY_UPDATE) + result = await query.executeAsync([value, createdBy, phaseId]) + } else { + const query = await prepare(connection, QUERY_DELETE) + result = await query.executeAsync([phaseId, value]) + } + } else { + const query = await prepare(connection, QUERY_CREATE) + result = await query.executeAsync([phaseId, value, createdBy, createdBy]) + } + await connection.commitTransactionAsync() + } catch (e) { + logger.error(`Error in 'createOrSetNumberOfReviewers' ${e}, rolling back transaction`) + await connection.rollbackTransactionAsync() + throw e + } finally { + await connection.closeAsync() + } + return result +} + +module.exports = { + getEntry, + createOrSetNumberOfReviewers +} From b9b4a06b681805adf8ba9f7a3be0b6e4b5c09eea Mon Sep 17 00:00:00 2001 From: Thomas Kranitsas Date: Thu, 3 Feb 2022 05:37:32 +0200 Subject: [PATCH 14/15] set autopilot to on --- src/services/ProcessorService.js | 3 + .../selfServiceNotificationService.js | 72 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 src/services/selfServiceNotificationService.js diff --git a/src/services/ProcessorService.js b/src/services/ProcessorService.js index 4e167ae..e8acd42 100644 --- a/src/services/ProcessorService.js +++ b/src/services/ProcessorService.js @@ -604,6 +604,7 @@ async function createChallenge (saveDraftContestDTO, challengeUuid, createdByUse // Repost all challenge resource on Kafka so they will get created on legacy by the legacy-challenge-resource-processor await rePostResourcesOnKafka(challengeUuid, m2mToken) await timelineService.enableTimelineNotifications(legacyId, createdByUserId) + await metadataService.createOrUpdateMetadata(legacyId, 9, 'On', createdByUserId) // autopilot return legacyId } @@ -684,6 +685,8 @@ async function processMessage (message) { logger.info('Activating challenge...') const activated = await activateChallenge(legacyId) logger.info(`Activated! ${JSON.stringify(activated)}`) + // make sure autopilot is on + await metadataService.createOrUpdateMetadata(legacyId, 9, 'On', createdByUserId) // autopilot // Repost all challenge resource on Kafka so they will get created on legacy by the legacy-challenge-resource-processor await rePostResourcesOnKafka(challengeUuid, m2mToken) } diff --git a/src/services/selfServiceNotificationService.js b/src/services/selfServiceNotificationService.js new file mode 100644 index 0000000..cf89d77 --- /dev/null +++ b/src/services/selfServiceNotificationService.js @@ -0,0 +1,72 @@ +/** + * timeline notification Service + * Interacts with InformixDB + */ +const util = require('util') +const logger = require('../common/logger') +const helper = require('../common/helper') + +const QUERY_GET_ENTRY = 'SELECT notification_type_id FROM notification WHERE external_ref_id = %d AND project_id = %d' +const QUERY_DELETE = 'DELETE FROM notification WHERE external_ref_id = ? AND project_id = ?' + +/** + * Prepare Informix statement + * @param {Object} connection the Informix connection + * @param {String} sql the sql + * @return {Object} Informix statement + */ +async function prepare (connection, sql) { + // logger.debug(`Preparing SQL ${sql}`) + const stmt = await connection.prepareAsync(sql) + return Promise.promisifyAll(stmt) +} + +/** + * Get entry + * @param {Number} legacyId the legacy challenge ID + * @param {String} userId the userId + */ +async function getEntry (legacyId, userId) { + const connection = await helper.getInformixConnection() + let result = null + try { + result = await connection.queryAsync(util.format(QUERY_GET_ENTRY, userId, legacyId)) + } catch (e) { + logger.error(`Error in 'getEntry' ${e}`) + throw e + } finally { + await connection.closeAsync() + } + return result +} + +/** + * Disable timeline notifications + * @param {Number} legacyId the legacy challenge ID + * @param {String} userId the userId + */ +async function disableTimelineNotifications (legacyId, userId) { + const connection = await helper.getInformixConnection() + let result = null + try { + await connection.beginTransactionAsync() + const [existing] = await getEntry(legacyId, userId) + if (existing) { + const query = await prepare(connection, QUERY_DELETE) + result = await query.executeAsync([userId, legacyId]) + } + await connection.commitTransactionAsync() + } catch (e) { + logger.error(`Error in 'disableTimelineNotifications' ${e}, rolling back transaction`) + await connection.rollbackTransactionAsync() + throw e + } finally { + await connection.closeAsync() + } + return result +} + +module.exports = { + getEntry, + disableTimelineNotifications +} From 1ed67c618c1c65b972ff1753e66cc11f20abf767 Mon Sep 17 00:00:00 2001 From: Thomas Kranitsas Date: Thu, 3 Feb 2022 05:39:32 +0200 Subject: [PATCH 15/15] disable notifications for creator --- src/services/ProcessorService.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/services/ProcessorService.js b/src/services/ProcessorService.js index e8acd42..d131180 100644 --- a/src/services/ProcessorService.js +++ b/src/services/ProcessorService.js @@ -17,6 +17,7 @@ const timelineService = require('./timelineService') const metadataService = require('./metadataService') const paymentService = require('./paymentService') const { createOrSetNumberOfReviewers } = require('./selfServiceReviewerService') +const { disableTimelineNotifications } = require('./selfServiceNotificationService') /** * Drop and recreate phases in ifx @@ -649,6 +650,9 @@ async function processMessage (message) { logger.debug('Legacy ID does not exist. Will create...') legacyId = await createChallenge(saveDraftContestDTO, challengeUuid, createdByUserId, message.payload.legacy, m2mToken) await recreatePhases(legacyId, message.payload.phases, updatedByUserId) + if (_.get(message, 'payload.legacy.selfService')) { + await disableTimelineNotifications(legacyId, createdByUserId) // disable + } } let challenge