@@ -10,8 +10,19 @@ const config = require('config')
1010const logger = require ( '../common/logger' )
1111const helper = require ( '../common/helper' )
1212const constants = require ( '../constants' )
13- const showdown = require ( 'showdown' )
14- const converter = new showdown . Converter ( )
13+ // TODO: Remove this
14+ // const showdown = require('showdown')
15+ // const converter = new showdown.Converter()
16+
17+ /**
18+ * Get group information by V5 UUID
19+ * @param {String } v5GroupId the v5 group UUID
20+ * @param {String } m2mToken token for accessing the API
21+ */
22+ async function getGroup ( v5GroupId , m2mToken ) {
23+ const response = await helper . getRequest ( `${ config . V5_GROUPS_API_URL } /${ v5GroupId } ` , m2mToken )
24+ return response . body
25+ }
1526
1627/**
1728 * Get technologies from V4 API
@@ -56,46 +67,36 @@ async function getDirectProjectId (m2mToken, projectId) {
5667}
5768
5869/**
59- * Get legacy challenge track and subTrack values based on the v5 legacy.track and typeId
60- * @param {String } legacyTrack the legacy. track value from the v5 challenge object
70+ * Get legacy challenge track and subTrack values based on the v5 trackId, typeId and tags
71+ * @param {String } trackId the V5 track ID
6172 * @param {String } typeId the v5 type ID
73+ * @param {Array<String> } tags the v5 tags
6274 * @param {String } m2mToken the M2M token
6375 */
64- async function getLegacyTrackInformation ( legacyTrack , typeId , m2mToken ) {
65- const data = {
66- track : _ . toUpper ( legacyTrack )
67- }
68- if ( _ . isUndefined ( data . track ) ) {
69- throw new Error ( `Cannot create a challenge without a track. Please use one of [${ _ . values ( constants . challengeTracks ) . join ( ', ' ) } ]` )
76+ async function getLegacyTrackInformation ( trackId , typeId , tags , m2mToken ) {
77+ if ( _ . isUndefined ( trackId ) ) {
78+ throw new Error ( 'Cannot create a challenge without a trackId.' )
7079 }
7180 if ( _ . isUndefined ( typeId ) ) {
7281 throw new Error ( 'Cannot create a challenge without a typeId.' )
7382 }
74-
75- // Use the configured subTrack if set for the given track/typeId
76- if ( constants . legacySubTrackMapping [ _ . toLower ( legacyTrack ) ] && constants . legacySubTrackMapping [ _ . toLower ( legacyTrack ) ] [ typeId ] ) {
77- data . subTrack = constants . legacySubTrackMapping [ _ . toLower ( legacyTrack ) ] [ typeId ]
78- } else {
79- // otherwise fetch v4 challenge type based on the v5 type.legacyId
80- const v5Type = await helper . getRequest ( `${ config . V5_CHALLENGE_TYPE_API_URL } /${ typeId } ` , m2mToken )
81- const v4TypeList = await helper . getRequest ( `${ config . V4_CHALLENGE_TYPE_API_URL } ` , m2mToken )
82- const v4Type = _ . find ( _ . get ( v4TypeList , 'body.result.content' , [ ] ) , type => type . id === v5Type . body . legacyId )
83- if ( ! v4Type ) {
84- throw new Error ( `There is no mapping between v5 Type ${ v5Type . body . name } and V4` )
85- }
86- data . subTrack = v4Type . subTrack
87- data . legacyTypeId = v5Type . body . legacyId
88- }
89-
90- // If it's a private task, set the `task` property to `true`
91- if ( _ . values ( config . TASK_TYPE_IDS ) . includes ( typeId ) ) {
92- // Tasks can only be created for the develop and design tracks so we're setting the track for QA/DS to DEVELOP
93- if ( data . track === constants . challengeTracks . QA || data . track !== constants . challengeTracks . DATA_SCIENCE ) {
94- data . track = constants . challengeTracks . DEVELOP
83+ const query = [
84+ `trackId=${ trackId } ` ,
85+ `typeId=${ typeId } `
86+ ]
87+ _ . each ( ( tags || [ ] ) , ( tag ) => {
88+ query . push ( `tags[]=${ tag } ` )
89+ } )
90+ try {
91+ const res = await helper . getRequest ( `${ config . V5_CHALLENGE_MIGRATION_API_URL } /convert-to-v4?${ query . join ( '&' ) } ` , m2mToken )
92+ return {
93+ track : res . body . track ,
94+ subTrack : res . body . subTrack ,
95+ ...( res . body . isTask ? { task : true } : { } )
9596 }
96- data . task = true
97+ } catch ( e ) {
98+ throw new Error ( _ . get ( e , 'message' , 'Failed to get V4 track/subTrack information' ) )
9799 }
98- return data
99100}
100101
101102/**
@@ -115,7 +116,7 @@ async function parsePayload (payload, m2mToken, isCreated = true) {
115116 if ( ! projectId ) throw new Error ( `Could not find Direct Project ID for Project ${ payload . projectId } ` )
116117 }
117118
118- const legacyTrackInfo = await getLegacyTrackInformation ( _ . get ( payload , 'legacy.track' ) , payload . typeId , m2mToken )
119+ const legacyTrackInfo = await getLegacyTrackInformation ( payload . trackId , payload . typeId , payload . tags , m2mToken )
119120
120121 const data = {
121122 ...legacyTrackInfo ,
@@ -140,20 +141,15 @@ async function parsePayload (payload, m2mToken, isCreated = true) {
140141 data . submissionVisibility = true
141142 data . milestoneId = 1
142143 }
143- if ( payload . description ) {
144- try {
145- data . detailedRequirements = converter . makeHtml ( payload . description )
146- } catch ( e ) {
147- data . detailedRequirements = payload . description
148- }
149- }
144+
145+ data . detailedRequirements = payload . description
150146 if ( payload . privateDescription ) {
151- try {
152- data . privateDescription = converter . makeHtml ( payload . privateDescription )
153- } catch ( e ) {
154- data . privateDescription = payload . privateDescription
155- }
147+ // don't include the private description as there could be
148+ // info that shouldn't be public. Just identify the v5 challenge id
149+ data . detailedRequirements += '\n\r'
150+ data . detailedRequirements += 'V5 Challenge - Additional Details: ' + payload . id
156151 }
152+
157153 if ( payload . phases ) {
158154 const registrationPhase = _ . find ( payload . phases , p => p . phaseId === config . REGISTRATION_PHASE_ID )
159155 const submissionPhase = _ . find ( payload . phases , p => p . phaseId === config . SUBMISSION_PHASE_ID )
@@ -202,6 +198,22 @@ async function parsePayload (payload, m2mToken, isCreated = true) {
202198 const platResult = await getPlatforms ( m2mToken )
203199 data . platforms = _ . filter ( platResult . result . content , e => payload . tags . includes ( e . name ) )
204200 }
201+ if ( payload . groups && _ . get ( payload , 'groups.length' , 0 ) > 0 ) {
202+ const legacyGroups = [ ]
203+ for ( const group of payload . groups ) {
204+ try {
205+ const groupInfo = await getGroup ( group , m2mToken )
206+ if ( ! _ . isEmpty ( _ . get ( groupInfo , 'oldId' ) ) ) {
207+ legacyGroups . push ( _ . get ( groupInfo , 'oldId' ) )
208+ }
209+ } catch ( e ) {
210+ logger . warn ( `Failed to load details for group ${ group } ` )
211+ }
212+ }
213+ if ( legacyGroups . length > 0 ) {
214+ data . groupIds = legacyGroups
215+ }
216+ }
205217 return data
206218 } catch ( err ) {
207219 // Debugging
@@ -256,9 +268,11 @@ async function processCreate (message) {
256268 await helper . patchRequest ( `${ config . V5_CHALLENGE_API_URL } /${ challengeUuid } ` , {
257269 legacy : {
258270 ...message . payload . legacy ,
271+ track : saveDraftContestDTO . track ,
272+ subTrack : saveDraftContestDTO . subTrack ,
273+ isTask : saveDraftContestDTO . task || false ,
259274 directProjectId : newChallenge . body . result . content . projectId ,
260- forumId : _ . get ( newChallenge , 'body.result.content.forumId' , message . payload . legacy . forumId ) ,
261- informixModified : _ . get ( newChallenge , 'body.result.content.updatedAt' , new Date ( ) )
275+ forumId : _ . get ( newChallenge , 'body.result.content.forumId' , message . payload . legacy . forumId )
262276 } ,
263277 legacyId : newChallenge . body . result . content . id
264278 } , m2mToken )
@@ -277,14 +291,20 @@ processCreate.schema = {
277291 'mime-type' : Joi . string ( ) . required ( ) ,
278292 payload : Joi . object ( ) . keys ( {
279293 id : Joi . string ( ) . required ( ) ,
280- typeId : Joi . string ( ) ,
294+ typeId : Joi . string ( ) . required ( ) ,
295+ trackId : Joi . string ( ) . required ( ) ,
281296 legacy : Joi . object ( ) . keys ( {
282297 track : Joi . string ( ) . required ( ) ,
283298 reviewType : Joi . string ( ) . required ( ) ,
284299 confidentialityType : Joi . string ( ) ,
285300 directProjectId : Joi . number ( ) ,
286301 forumId : Joi . number ( ) . integer ( ) . positive ( )
287302 } ) . unknown ( true ) ,
303+ task : Joi . object ( ) . keys ( {
304+ isTask : Joi . boolean ( ) . default ( false ) ,
305+ isAssigned : Joi . boolean ( ) . default ( false ) ,
306+ memberId : Joi . string ( ) . allow ( null )
307+ } ) ,
288308 billingAccountId : Joi . number ( ) ,
289309 name : Joi . string ( ) . required ( ) ,
290310 description : Joi . string ( ) ,
@@ -303,7 +323,8 @@ processCreate.schema = {
303323 projectId : Joi . number ( ) . integer ( ) . positive ( ) . required ( ) ,
304324 copilotId : Joi . number ( ) . integer ( ) . positive ( ) . optional ( ) ,
305325 status : Joi . string ( ) . valid ( _ . values ( Object . keys ( constants . createChallengeStatusesMap ) ) ) . required ( ) ,
306- startDate : Joi . date ( ) ,
326+ groups : Joi . array ( ) . items ( Joi . string ( ) ) ,
327+ startDate : Joi . date ( )
307328 } ) . unknown ( true ) . required ( )
308329 } ) . required ( )
309330}
@@ -343,6 +364,7 @@ async function processUpdate (message) {
343364 if ( ! challenge ) {
344365 throw new Error ( `Could not find challenge ${ message . payload . legacyId } ` )
345366 }
367+
346368 await helper . putRequest ( `${ config . V4_CHALLENGE_API_URL } /${ message . payload . legacyId } ` , { param : saveDraftContestDTO } , m2mToken )
347369
348370 if ( message . payload . status ) {
@@ -355,16 +377,16 @@ async function processUpdate (message) {
355377 if ( message . payload . status === constants . challengeStatuses . Completed && challenge . currentStatus !== constants . challengeStatuses . Completed ) {
356378 const challengeUuid = message . payload . id
357379 const v5Challenge = await helper . getRequest ( `${ config . V5_CHALLENGE_API_URL } /${ challengeUuid } ` , m2mToken )
358- if ( _ . values ( config . TASK_TYPE_IDS ) . includes ( v5Challenge . body . typeId ) ) {
359- logger . info ( 'Challenge type is TASK' )
380+ if ( v5Challenge . body . task . isTask ) {
381+ logger . info ( 'Challenge is a TASK' )
360382 if ( ! message . payload . winners || message . payload . winners . length === 0 ) {
361383 throw new Error ( 'Cannot close challenge without winners' )
362384 }
363385 const winnerId = _ . find ( message . payload . winners , winner => winner . placement === 1 ) . userId
364386 logger . info ( `Will close the challenge with ID ${ message . payload . legacyId } . Winner ${ winnerId } !` )
365387 await closeChallenge ( message . payload . legacyId , winnerId )
366388 } else {
367- logger . info ( ` Challenge type is ${ v5Challenge . body . typeId } .. Skip closing challenge...` )
389+ logger . info ( ' Challenge type is not a task.. Skip closing challenge...' )
368390 }
369391 }
370392 }
@@ -397,11 +419,16 @@ processUpdate.schema = {
397419 reviewType : Joi . string ( ) . required ( ) ,
398420 confidentialityType : Joi . string ( ) ,
399421 directProjectId : Joi . number ( ) ,
400- forumId : Joi . number ( ) . integer ( ) . positive ( ) ,
401- informixModified : Joi . string ( )
422+ forumId : Joi . number ( ) . integer ( ) . positive ( )
402423 } ) . unknown ( true ) ,
424+ task : Joi . object ( ) . keys ( {
425+ isTask : Joi . boolean ( ) . default ( false ) ,
426+ isAssigned : Joi . boolean ( ) . default ( false ) ,
427+ memberId : Joi . string ( ) . allow ( null )
428+ } ) ,
403429 billingAccountId : Joi . number ( ) ,
404- typeId : Joi . string ( ) ,
430+ typeId : Joi . string ( ) . required ( ) ,
431+ trackId : Joi . string ( ) . required ( ) ,
405432 name : Joi . string ( ) ,
406433 description : Joi . string ( ) ,
407434 privateDescription : Joi . string ( ) ,
@@ -417,6 +444,7 @@ processUpdate.schema = {
417444 } ) . unknown ( true ) ) . min ( 1 ) ,
418445 tags : Joi . array ( ) . items ( Joi . string ( ) . required ( ) ) . min ( 1 ) , // tag names
419446 projectId : Joi . number ( ) . integer ( ) . positive ( ) . allow ( null ) ,
447+ groups : Joi . array ( ) . items ( Joi . string ( ) ) ,
420448 startDate : Joi . date ( )
421449 } ) . unknown ( true ) . required ( )
422450 } ) . required ( )
@@ -427,4 +455,4 @@ module.exports = {
427455 processUpdate
428456}
429457
430- logger . buildService ( module . exports )
458+ // logger.buildService(module.exports)
0 commit comments