Skip to content
This repository was archived by the owner on Jan 23, 2025. It is now read-only.

Commit af8d750

Browse files
author
James Cori
committed
Merge branch 'develop'
2 parents 555f903 + bba32e3 commit af8d750

File tree

4 files changed

+466
-51
lines changed

4 files changed

+466
-51
lines changed

src/constants.js

Lines changed: 76 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/**
22
* constants
33
*/
4+
const metadataExtractor = require('./utils/metadataExtractor')
45

56
const prizeSetTypes = {
67
ChallengePrizes: 'placement',
@@ -57,12 +58,81 @@ const prizeTypesIds = {
5758
}
5859

5960
const supportedMetadata = {
60-
allowStockArt: 52,
61-
drPoints: 30,
62-
submissionViewable: 53,
63-
submissionLimit: 51,
64-
codeRepo: 85,
65-
environment: 84
61+
32: {
62+
method: metadataExtractor.extractBillingProject,
63+
defaultValue: null,
64+
description: 'Billing Project'
65+
},
66+
30: {
67+
method: metadataExtractor.extractDrPoints,
68+
defaultValue: 0,
69+
description: 'DR points'
70+
},
71+
35: {
72+
method: metadataExtractor.extractSpecReviewCost,
73+
defaultValue: null,
74+
description: 'Spec review cost'
75+
},
76+
41: {
77+
method: metadataExtractor.extractApprovalRequired,
78+
defaultValue: true,
79+
description: 'Approval Required'
80+
},
81+
44: {
82+
method: metadataExtractor.extractPostMortemRequired,
83+
defaultValue: true,
84+
description: 'Post-Mortem Required'
85+
},
86+
48: {
87+
method: metadataExtractor.extractTrackLateDeliverablesRequired,
88+
defaultValue: true,
89+
description: 'Track Late Deliverables'
90+
},
91+
51: {
92+
method: metadataExtractor.extractSubmissionLimit,
93+
defaultValue: null,
94+
description: 'Maximum submissions'
95+
},
96+
52: {
97+
method: metadataExtractor.extractAllowStockArtRequired,
98+
defaultValue: false,
99+
description: 'Allow Stock Art'
100+
},
101+
53: {
102+
method: metadataExtractor.extractSubmissionViewable,
103+
defaultValue: false,
104+
description: 'Viewable Submissions Flag'
105+
},
106+
59: {
107+
method: metadataExtractor.extractReviewFeedback,
108+
defaultValue: true,
109+
description: 'Review Feedback Flag'
110+
},
111+
84: {
112+
method: metadataExtractor.extractEnvironment,
113+
defaultValue: null,
114+
description: 'Environment'
115+
},
116+
85: {
117+
method: metadataExtractor.extractCodeRepo,
118+
defaultValue: null,
119+
description: 'Code repo'
120+
},
121+
88: {
122+
method: metadataExtractor.extractEstimateEffortHours,
123+
defaultValue: 0,
124+
description: 'Effort Hours Estimate'
125+
},
126+
89: {
127+
method: metadataExtractor.extractEstimateEffortOffshore,
128+
defaultValue: 0,
129+
description: 'Estimate Effort Days offshore'
130+
},
131+
90: {
132+
method: metadataExtractor.extractEstimateEffortOnsite,
133+
defaultValue: 0,
134+
description: 'Estimate Effort Days Onsite'
135+
}
66136
}
67137

68138
module.exports = {

src/services/ProcessorService.js

Lines changed: 91 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,53 @@ const timelineService = require('./timelineService')
1717
const metadataService = require('./metadataService')
1818
const paymentService = require('./paymentService')
1919

20+
/**
21+
* Drop and recreate phases in ifx
22+
* @param {Number} legacyId the legacy challenge ID
23+
* @param {Array} v5Phases the v5 phases
24+
* @param {String} createdBy the createdBy
25+
*/
26+
async function recreatePhases (legacyId, v5Phases, createdBy) {
27+
logger.info('recreatePhases :: start')
28+
const phaseTypes = await timelineService.getPhaseTypes()
29+
const phasesFromIFx = await timelineService.getChallengePhases(legacyId)
30+
logger.debug('Creating phases that exist on v5 and not on legacy...')
31+
for (const phase of v5Phases) {
32+
const phaseLegacyId = _.get(_.find(phaseTypes, pt => pt.name === phase.name), 'phase_type_id')
33+
logger.debug(`Phase ${phase.name} has legacy phase type id ${phaseLegacyId}`)
34+
const existingLegacyPhase = _.find(phasesFromIFx, p => p.phase_type_id === phaseLegacyId)
35+
if (!existingLegacyPhase && phaseLegacyId) {
36+
const statusTypeId = phase.isOpen
37+
? constants.PhaseStatusTypes.Open
38+
: (new Date().getTime() <= new Date(phase.scheduledEndDate).getTime() ? constants.PhaseStatusTypes.Scheduled : constants.PhaseStatusTypes.Closed)
39+
logger.debug(`Will create phase ${phase.name}/${phaseLegacyId} with duration ${phase.duration} seconds`)
40+
await timelineService.createPhase(
41+
legacyId,
42+
phaseLegacyId,
43+
statusTypeId,
44+
phase.scheduledStartDate,
45+
phase.actualStartDate,
46+
phase.scheduledEndDate,
47+
phase.actualEndDate,
48+
phase.duration * 1000,
49+
createdBy
50+
)
51+
} else if (!phaseLegacyId) {
52+
logger.warn(`Could not create phase ${phase.name} on legacy!`)
53+
}
54+
}
55+
logger.debug('Deleting phases that exist on legacy and not on v5...')
56+
for (const phase of phasesFromIFx) {
57+
const phaseName = _.get(_.find(phaseTypes, pt => pt.phase_type_id === phase.phase_type_id), 'name')
58+
const v5Equivalent = _.find(v5Phases, p => p.name === phaseName)
59+
if (!v5Equivalent) {
60+
logger.debug(`Will delete phase ${phaseName}`)
61+
await timelineService.dropPhase(legacyId, phase.project_phase_id)
62+
}
63+
}
64+
logger.info('recreatePhases :: end')
65+
}
66+
2067
/**
2168
* Sync the information from the v5 phases into legacy
2269
* @param {Number} legacyId the legacy challenge ID
@@ -283,7 +330,7 @@ async function getLegacyTrackInformation (trackId, typeId, tags, m2mToken) {
283330
try {
284331
const res = await helper.getRequest(`${config.V5_CHALLENGE_MIGRATION_API_URL}/convert-to-v4?${query.join('&')}`, m2mToken)
285332
return {
286-
track: res.body.track,
333+
// track: res.body.track,
287334
subTrack: res.body.subTrack,
288335
...(res.body.isTask ? { task: true } : {})
289336
}
@@ -390,8 +437,19 @@ async function parsePayload (payload, m2mToken, isCreated = true, informixGroupI
390437
const techResult = await getTechnologies(m2mToken)
391438
data.technologies = _.filter(techResult.result.content, e => payload.tags.includes(e.name))
392439

440+
if (data.technologies.length < 1) {
441+
data.technologies = _.filter(techResult.result.content, e => e.name === 'Other')
442+
}
443+
393444
const platResult = await getPlatforms(m2mToken)
394445
data.platforms = _.filter(platResult.result.content, e => payload.tags.includes(e.name))
446+
447+
if (data.platforms.length < 1) {
448+
data.platforms = _.filter(platResult.result.content, e => e.name === 'Other')
449+
}
450+
451+
logger.debug(`Technologies: ${JSON.stringify(data.technologies)}`)
452+
logger.debug(`Platforms: ${JSON.stringify(data.platforms)}`)
395453
}
396454
if (payload.groups && _.get(payload, 'groups.length', 0) > 0) {
397455
const oldGroups = _.map(informixGroupIds, g => _.toString(g))
@@ -505,16 +563,16 @@ async function processCreate (message) {
505563
try {
506564
logger.info(`processCreate :: Skip Forums - ${config.V4_CHALLENGE_API_URL}?filter=skipForum=true body: ${JSON.stringify({ param: _.omit(saveDraftContestDTO, ['groupsToBeAdded', 'groupsToBeDeleted']) })}`)
507565
const newChallenge = await helper.postRequest(`${config.V4_CHALLENGE_API_URL}?filter=skipForum=true`, { param: _.omit(saveDraftContestDTO, ['groupsToBeAdded', 'groupsToBeDeleted']) }, m2mToken)
508-
566+
const legacyId = newChallenge.body.result.content.id
509567
let forumId = 0
510568
if (message.payload.legacy && message.payload.legacy.forumId) {
511569
forumId = message.payload.legacy.forumId
512570
}
513571
forumId = _.get(newChallenge, 'body.result.content.forumId', forumId)
514-
await helper.forceV4ESFeeder(newChallenge.body.result.content.id)
515-
await associateChallengeGroups(saveDraftContestDTO.groupsToBeAdded, saveDraftContestDTO.groupsToBeDeleted, newChallenge.body.result.content.id)
516-
// await associateChallengeTerms(saveDraftContestDTO.termsToBeAdded, saveDraftContestDTO.termsToBeRemoved, newChallenge.body.result.content.id)
517-
await setCopilotPayment(challengeUuid, newChallenge.body.result.content.id, _.get(message, 'payload.prizeSets'), _.get(message, 'payload.createdBy'), _.get(message, 'payload.updatedBy'), m2mToken)
572+
await helper.forceV4ESFeeder(legacyId)
573+
// jmc - removed because this will happen in update - await associateChallengeGroups(saveDraftContestDTO.groupsToBeAdded, saveDraftContestDTO.groupsToBeDeleted, legacyId)
574+
// // await associateChallengeTerms(saveDraftContestDTO.termsToBeAdded, saveDraftContestDTO.termsToBeRemoved, legacyId)
575+
// jmc - removed because this will happen in update - await setCopilotPayment(challengeUuid, legacyId, _.get(message, 'payload.prizeSets'), _.get(message, 'payload.createdBy'), _.get(message, 'payload.updatedBy'), m2mToken)
518576
await helper.patchRequest(`${config.V5_CHALLENGE_API_URL}/${challengeUuid}`, {
519577
legacy: {
520578
...message.payload.legacy,
@@ -524,13 +582,13 @@ async function processCreate (message) {
524582
directProjectId: newChallenge.body.result.content.projectId,
525583
forumId
526584
},
527-
legacyId: newChallenge.body.result.content.id
585+
legacyId
528586
}, m2mToken)
529587
// Repost all challenge resource on Kafka so they will get created on legacy by the legacy-challenge-resource-processor
530588
await rePostResourcesOnKafka(challengeUuid, m2mToken)
531-
await timelineService.enableTimelineNotifications(newChallenge.body.result.content.id, _.get(message, 'payload.createdBy'))
589+
await timelineService.enableTimelineNotifications(legacyId, _.get(message, 'payload.createdBy'))
532590
logger.debug('End of processCreate')
533-
return newChallenge.body.result.content.id
591+
return legacyId
534592
} catch (e) {
535593
logger.error('processCreate Catch', e)
536594
throw e
@@ -600,6 +658,7 @@ async function processUpdate (message) {
600658
} else if (!legacyId) {
601659
logger.debug('Legacy ID does not exist. Will create...')
602660
legacyId = await processCreate(message)
661+
await recreatePhases(legacyId, message.payload.phases, _.get(message, 'payload.updatedBy') || _.get(message, 'payload.createdBy'))
603662
}
604663
const m2mToken = await helper.getM2MToken()
605664

@@ -637,44 +696,32 @@ async function processUpdate (message) {
637696

638697
const saveDraftContestDTO = await parsePayload(message.payload, m2mToken, false, v4GroupIds)
639698
logger.debug('Result from parsePayload:')
640-
logger.debug(JSON.stringify(saveDraftContestDTO, null, 2))
699+
logger.debug(JSON.stringify(saveDraftContestDTO))
641700
// logger.debug('Parsed Payload', saveDraftContestDTO)
642701
try {
643-
try {
644-
if (challenge) {
645-
await helper.putRequest(`${config.V4_CHALLENGE_API_URL}/${legacyId}`, { param: _.omit(saveDraftContestDTO, ['groupsToBeAdded', 'groupsToBeDeleted']) }, m2mToken)
646-
}
647-
} catch (e) {
648-
logger.warn('Failed to update the challenge via the V4 API')
649-
logger.error(e)
650-
}
651-
652-
// Update metadata in IFX
653-
if (message.payload.metadata && message.payload.metadata.length > 0) {
654-
for (const metadataKey of _.keys(constants.supportedMetadata)) {
655-
const entry = _.find(message.payload.metadata, meta => meta.name === metadataKey)
656-
if (entry) {
657-
if (metadataKey === 'submissionLimit') {
658-
// data here is JSON stringified
659-
try {
660-
const parsedEntryValue = JSON.parse(entry.value)
661-
if (parsedEntryValue.limit) {
662-
entry.value = parsedEntryValue.count
663-
} else {
664-
entry.value = null
665-
}
666-
} catch (e) {
667-
entry.value = null
668-
}
669-
}
670-
try {
671-
await metadataService.createOrUpdateMetadata(legacyId, constants.supportedMetadata[metadataKey], entry.value, _.get(message, 'payload.updatedBy') || _.get(message, 'payload.createdBy'))
672-
} catch (e) {
673-
logger.warn(`Failed to set ${metadataKey} (${constants.supportedMetadata[metadataKey]})`)
674-
}
702+
// extract metadata from challenge and insert into IFX
703+
let metaValue
704+
for (const metadataKey of _.keys(constants.supportedMetadata)) {
705+
try {
706+
metaValue = constants.supportedMetadata[metadataKey].method(message.payload, constants.supportedMetadata[metadataKey].defaultValue)
707+
if (metaValue !== null && metaValue !== '') {
708+
logger.info(`Setting ${constants.supportedMetadata[metadataKey].description} to ${metaValue}`)
709+
await metadataService.createOrUpdateMetadata(legacyId, metadataKey, metaValue, _.get(message, 'payload.updatedBy') || _.get(message, 'payload.createdBy'))
675710
}
711+
} catch (e) {
712+
logger.warn(`Failed to set ${constants.supportedMetadata[metadataKey].description} to ${metaValue}`)
676713
}
677714
}
715+
// Thomas - get rid of this and add required info directly via IFX
716+
// try {
717+
// if (challenge) {
718+
// await helper.putRequest(`${config.V4_CHALLENGE_API_URL}/${legacyId}`, { param: _.omit(saveDraftContestDTO, ['groupsToBeAdded', 'groupsToBeDeleted']) }, m2mToken)
719+
// }
720+
// } catch (e) {
721+
// logger.warn('Failed to update the challenge via the V4 API')
722+
// logger.error(e)
723+
// }
724+
678725
if (message.payload.status && challenge) {
679726
// logger.info(`The status has changed from ${challenge.currentStatus} to ${message.payload.status}`)
680727
if (message.payload.status === constants.challengeStatuses.Active && challenge.currentStatus !== constants.challengeStatuses.Active) {
@@ -699,11 +746,11 @@ async function processUpdate (message) {
699746
}
700747
}
701748
if (!_.get(message.payload, 'task.isTask')) {
702-
await syncChallengePhases(message.payload.legacyId, message.payload.phases)
749+
await syncChallengePhases(legacyId, message.payload.phases)
703750
} else {
704751
logger.info('Will skip syncing phases as the challenge is a task...')
705752
}
706-
await updateMemberPayments(message.payload.legacyId, message.payload.prizeSets, _.get(message, 'payload.updatedBy') || _.get(message, 'payload.createdBy'))
753+
await updateMemberPayments(legacyId, message.payload.prizeSets, _.get(message, 'payload.updatedBy') || _.get(message, 'payload.createdBy'))
707754
await associateChallengeGroups(saveDraftContestDTO.groupsToBeAdded, saveDraftContestDTO.groupsToBeDeleted, legacyId)
708755
await associateChallengeTerms(message.payload.terms, legacyId, _.get(message, 'payload.createdBy'), _.get(message, 'payload.updatedBy') || _.get(message, 'payload.createdBy'))
709756
await setCopilotPayment(message.payload.id, legacyId, _.get(message, 'payload.prizeSets'), _.get(message, 'payload.createdBy'), _.get(message, 'payload.updatedBy') || _.get(message, 'payload.createdBy'), m2mToken)

0 commit comments

Comments
 (0)