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

Commit 56b6e05

Browse files
authored
Merge pull request #115 from dhruvit-r/develop
feat: apply skillsets when a challenge is created
2 parents 2376e7c + eea39d7 commit 56b6e05

File tree

8 files changed

+83
-10
lines changed

8 files changed

+83
-10
lines changed

config/default.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,15 @@ module.exports = {
6868
GRANT_TYPE: 'client_credentials',
6969

7070
// used as base to construct various URLs
71-
WEBSITE_SECURE: process.env.WEBSITE_SECURE || 'https://topcoderx.topcoder-dev.com',
71+
WEBSITE_SECURE: process.env.WEBSITE_SECURE || 'http://topcoderx.topcoder-dev.com',
7272

7373
ROLE_ID_COPILOT: process.env.ROLE_ID_COPILOT || 'cfe12b3f-2a24-4639-9d8b-ec86726f76bd',
7474
ROLE_ID_ITERATIVE_REVIEWER: process.env.ROLE_ID_ITERATIVE_REVIEWER || 'f6df7212-b9d6-4193-bfb1-b383586fce63',
7575
ROLE_ID_SUBMITTER: process.env.ROLE_ID_SUBMITTER || '732339e7-8e30-49d7-9198-cccf9451e221',
7676
TYPE_ID_TASK: process.env.TYPE_ID_TASK || 'ecd58c69-238f-43a4-a4bb-d172719b9f31',
7777
DEFAULT_TIMELINE_TEMPLATE_ID: process.env.DEFAULT_TIMELINE_TEMPLATE_ID || '53a307ce-b4b3-4d6f-b9a1-3741a58f77e6',
7878
DEFAULT_TRACK_ID: process.env.DEFAULT_TRACK_ID || '9b6fc876-f4d9-4ccb-9dfd-419247628825',
79+
WORK_TYPE_ID: process.env.WORK_TYPE_ID || 'b658b280-6c4d-11e5-9d70-22000b2c9aef',
7980
GITLAB_ACCESS_TOKEN_DEFAULT_EXPIRATION: 3600 * 2,
8081
GITLAB_REFRESH_TOKEN_BEFORE_EXPIRATION: 300,
8182
GITLAB_CLIENT_ID: process.env.GITLAB_CLIENT_ID,

models/Project.js

+27-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const Schema = dynamoose.Schema;
1717
* @property {String} id The id.
1818
* @property {String} title The title.
1919
* @property {Number} tcDirectId The tc direct id.
20-
* @property {String} tags The tags.
20+
* @property {Array<{id: string, name: string}>} tags The tags.
2121
* @property {String} rocketChatWebhook The rocket chat webhook.
2222
* @property {String} rocketChatChannelName The rocket chat channel name.
2323
* @property {String} archived The archived.
@@ -41,9 +41,33 @@ const schema = new Schema({
4141
required: true
4242
},
4343
tags: {
44-
type: String,
44+
type: 'list',
45+
list: [{
46+
type: 'map',
47+
map: {
48+
id: {type: String, required: true},
49+
name: {type: String, required: true}
50+
}
51+
}],
4552
required: true,
46-
default: ''
53+
default: [],
54+
fromDynamo(value) {
55+
if (value.S) {
56+
return value.S;
57+
}
58+
if (value.L) {
59+
return value.L.map((item) => {
60+
if (item.M && item.M.name && item.M.id) {
61+
return {
62+
id: item.M.id.S,
63+
name: item.M.name.S
64+
};
65+
}
66+
return null;
67+
});
68+
}
69+
return [];
70+
}
4771
},
4872
rocketChatWebhook: {type: String, required: false},
4973
rocketChatChannelName: {type: String, required: false},

services/ChallengeService.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const dbHelper = require('../utils/db-helper');
2020
* @param {Object} event the event
2121
*/
2222
async function handleChallengeTagsUpdate(event) {
23-
const tags = event.data.tags.split(',');
23+
const tags = event.data.tags.map((tag) => tag.name);
2424
await Promise.all(
2525
event.data.challengeUUIDsList.map(async (challengeUUIDs) => {
2626
if (_.isString(challengeUUIDs)) { // repoUrl
@@ -54,7 +54,12 @@ process.schema = Joi.object().keys({
5454
challengeUUIDsList: Joi.array().items(
5555
Joi.alternatives().try(Joi.string(), Joi.array().items(Joi.string()))
5656
).required(),
57-
tags: Joi.string().required()
57+
tags: Joi.array().items(
58+
Joi.object().keys({
59+
id: Joi.string().required(),
60+
name: Joi.string().required()
61+
})
62+
).required()
5863
}).required(),
5964
retryCount: Joi.number().integer().default(0).optional()
6065
});

services/CopilotPaymentService.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ async function handlePaymentAdd(event, payment) {
194194
const newChallenge = {
195195
name: challengeTitle,
196196
projectId: project.tcDirectId,
197-
tags: !!project.tags ? project.tags.split(',') : [],
197+
tags: project.tags ? project.tags.map((tag) => tag.name) : [],
198198
detailedRequirements: challengeRequirements,
199199
prizes: [payment.amount],
200200
reviewType: 'INTERNAL'
@@ -203,6 +203,9 @@ async function handlePaymentAdd(event, payment) {
203203
// Create a new challenge
204204
const challengeUUID = await topcoderApiHelper.createChallenge(newChallenge);
205205

206+
// Apply skills to the challenge
207+
await topcoderApiHelper.applySkillsSet(challengeUUID, project.tags);
208+
206209
logger.debug(`updating database payment with new challenge id:${challengeUUID}`);
207210

208211
// update db payment

services/IssueService.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -635,11 +635,14 @@ async function handleIssueCreate(event, issue, forceAssign = false) {
635635
issue.challengeUUID = await topcoderApiHelper.createChallenge({
636636
name: issue.title,
637637
projectId,
638-
tags: project.tags ? project.tags.split(',') : [],
638+
tags: project.tags ? project.tags.map((tag) => tag.name) : [],
639639
detailedRequirements: issue.body,
640640
prizes: issue.prizes
641641
});
642642

643+
// Apply skills to the challenge
644+
await topcoderApiHelper.applySkillsSetToChallenge(issue.challengeUUID, project.tags);
645+
643646
// Save
644647
// update db payment
645648
await dbHelper.update(models.Issue, dbIssue.id, {

utils/db-helper.js

+1
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,7 @@ async function acquireLockOnUser(userId, lockId, ttl) {
490490
}
491491
});
492492
}
493+
493494
/**
494495
* Release lock on user
495496
* @param {String} id ID of the user

utils/logger.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ logger.logFullError = function logFullError(err, signature) {
3232
if (!err || err.logged) {
3333
return;
3434
}
35-
logger.error(`Error happened in ${signature}\n${err.stack}`);
35+
logger.error(`Error happened in ${signature}\n${err.stack || err.message}`);
3636
err.logged = true;
3737
};
3838

utils/topcoder-api-helper.js

+37-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ async function createChallenge(challenge) {
7676
}],
7777
timelineTemplateId: config.DEFAULT_TIMELINE_TEMPLATE_ID,
7878
projectId: challenge.projectId,
79-
tags: challenge.tags,
79+
tags: challenge.tags.map((tag) => tag.name),
8080
trackId: config.DEFAULT_TRACK_ID,
8181
legacy: {
8282
pureV5Task: true
@@ -163,6 +163,41 @@ async function activateChallenge(id) {
163163
}
164164
}
165165

166+
/**
167+
* Apply skills set to the challenge
168+
* @param {String} challengeId the challenge id
169+
* @param {Array<{id: string, name: string}>} tags the list of tags applied to the challenge
170+
*/
171+
async function applySkillsSetToChallenge(challengeId, tags) {
172+
const apiKey = await getM2Mtoken();
173+
logger.debug(`Applying skills set to the challenge ${challengeId}`);
174+
const url = `${config.TC_API_URL}/standardized-skills/work-skills`;
175+
const payload = {
176+
workId: challengeId,
177+
workTypeId: config.WORK_TYPE_ID,
178+
skillIds: tags.map((tag) => tag.id)
179+
};
180+
const params = {
181+
headers: {
182+
authorization: `Bearer ${apiKey}`,
183+
'Content-Type': 'application/json'
184+
}
185+
};
186+
try {
187+
const response = await axios.post(url, payload, params);
188+
const statusCode = response.status ? response.status : null;
189+
loggerFile.info(`EndPoint: POST /standardized-skills/work-skills,
190+
POST parameters: ${circularJSON.stringify(payload)}, Status Code:${statusCode}, Response: ${circularJSON.stringify(response.data)}`);
191+
logger.debug(`Skills set applied successfully to the challenge ${challengeId}`);
192+
return response.data;
193+
} catch (err) {
194+
loggerFile.info(`EndPoint: POST /standardized-skills/work-skills, POST parameters: ${circularJSON.stringify(payload)}, Status Code:null,
195+
Error: 'Failed to apply skills set to the challenge.', Details: ${circularJSON.stringify(err)}`);
196+
logger.error(`Response Data: ${JSON.stringify(err.response.data)}`);
197+
throw errors.convertTopcoderApiError(err, 'Failed to apply skills set to the challenge.');
198+
}
199+
}
200+
166201
/**
167202
* Get challenge details by id
168203
* @param {String} id challenge ID
@@ -511,6 +546,7 @@ module.exports = {
511546
createChallenge,
512547
updateChallenge,
513548
activateChallenge,
549+
applySkillsSetToChallenge,
514550
closeChallenge,
515551
getProjectBillingAccountId,
516552
getTopcoderMemberId,

0 commit comments

Comments
 (0)