Skip to content

Commit 4125d07

Browse files
authored
Merge pull request #73 from topcoder-platform/develop
feat: skills endpoint & validation rule updates
2 parents 35de2e2 + b0b5530 commit 4125d07

File tree

5 files changed

+85
-12
lines changed

5 files changed

+85
-12
lines changed

.circleci/config.yml

+1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ workflows:
6767
branches:
6868
only:
6969
- develop
70+
- feat/create-skill-obj
7071

7172
# Production builds are exectuted only on tagged commits to the
7273
# master branch.

src/controllers/StatisticsController.js

+11
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,16 @@ async function getMemberSkills (req, res) {
4343
res.send(result)
4444
}
4545

46+
/**
47+
* Create member skills
48+
* @param {Object} req the request
49+
* @param {Object} res the response
50+
*/
51+
async function createMemberSkills (req, res) {
52+
const result = await service.createMemberSkills(req.authUser, req.params.handle, req.body)
53+
res.send(result)
54+
}
55+
4656
/**
4757
* Partially update member skills
4858
* @param {Object} req the request
@@ -58,5 +68,6 @@ module.exports = {
5868
getHistoryStats,
5969
getMemberStats,
6070
getMemberSkills,
71+
createMemberSkills,
6172
partiallyUpdateMemberSkills
6273
}

src/routes.js

+6
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,12 @@ module.exports = {
131131
allowNoToken: true,
132132
scopes: [MEMBERS.READ, MEMBERS.ALL]
133133
},
134+
post: {
135+
controller: 'StatisticsController',
136+
method: 'createMemberSkills',
137+
auth: 'jwt',
138+
scopes: [MEMBERS.CREATE, MEMBERS.ALL]
139+
},
134140
patch: {
135141
controller: 'StatisticsController',
136142
method: 'partiallyUpdateMemberSkills',

src/services/MemberService.js

+8-12
Original file line numberDiff line numberDiff line change
@@ -202,25 +202,21 @@ updateMember.schema = {
202202
data: Joi.object().keys({
203203
firstName: Joi.string(),
204204
lastName: Joi.string(),
205-
description: Joi.string(),
205+
description: Joi.string().allow(''),
206206
otherLangName: Joi.string(),
207207
status: Joi.string(),
208208
email: Joi.string().email(),
209209
addresses: Joi.array().items(Joi.object().keys({
210-
streetAddr1: Joi.string(),
211-
streetAddr2: Joi.string(),
212-
city: Joi.string(),
213-
zip: Joi.string(),
214-
stateCode: Joi.string(),
215-
type: Joi.string(),
216-
createdAt: Joi.date(),
217-
updatedAt: Joi.date(),
218-
createdBy: Joi.string(),
219-
updatedBy: Joi.string()
210+
streetAddr1: Joi.string().allow(''),
211+
streetAddr2: Joi.string().allow(''),
212+
city: Joi.string().allow(''),
213+
zip: Joi.string().allow(''),
214+
stateCode: Joi.string().allow(''),
215+
type: Joi.string()
220216
})),
221217
homeCountryCode: Joi.string(),
222218
competitionCountryCode: Joi.string(),
223-
photoURL: Joi.string().uri(),
219+
photoURL: Joi.string().uri().allow('').allow(null),
224220
tracks: Joi.array().items(Joi.string())
225221
}).required()
226222
}

src/services/StatisticsService.js

+59
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,63 @@ getMemberSkills.schema = {
244244
throwError: Joi.boolean()
245245
}
246246

247+
async function createMemberSkills (currentUser, handle, data) {
248+
// get member by handle
249+
const member = await helper.getMemberByHandle(handle)
250+
// check authorization
251+
if (!helper.canManageMember(currentUser, member)) {
252+
throw new errors.ForbiddenError('You are not allowed to update the member skills.')
253+
}
254+
// fetch tags data
255+
if (!this.allTags) {
256+
this.allTags = await helper.getAllTags(config.TAGS.TAGS_BASE_URL + config.TAGS.TAGS_API_VERSION + config.TAGS.TAGS_FILTER)
257+
}
258+
let memberEnteredSkill = {
259+
userId: member.userId,
260+
createdAt: new Date().getTime(),
261+
createdBy: currentUser.handle || currentUser.sub,
262+
handleLower: handle,
263+
userHandle: handle,
264+
skills: {}
265+
}
266+
267+
// merge skills
268+
memberEnteredSkill = helper.mergeSkills(memberEnteredSkill, {}, this.allTags)
269+
// cleanup data
270+
var tempSkill = {}
271+
_.forIn(data, (value, key) => {
272+
var tag = helper.findTagById(this.allTags, Number(key))
273+
if (tag) {
274+
value.tagName = tag.name
275+
if (!value.hasOwnProperty('hidden')) {
276+
value.hidden = false
277+
}
278+
if (!value.hasOwnProperty('score')) {
279+
value.score = 1
280+
}
281+
value.sources = [ 'USER_ENTERED' ]
282+
tempSkill[key] = value
283+
}
284+
})
285+
_.assignIn(memberEnteredSkill.skills, tempSkill)
286+
await helper.create('MemberEnteredSkills', memberEnteredSkill)
287+
288+
// get skills by member handle
289+
const memberSkill = await this.getMemberSkills(currentUser, handle, {}, true)
290+
return memberSkill
291+
}
292+
293+
createMemberSkills.schema = {
294+
currentUser: Joi.any(),
295+
handle: Joi.string().required(),
296+
data: Joi.object().min(1).pattern(/.*/, Joi.object().keys({
297+
tagName: Joi.string(),
298+
hidden: Joi.boolean(),
299+
score: Joi.number().min(0),
300+
sources: Joi.array().items(Joi.string())
301+
}).required()).required()
302+
}
303+
247304
/**
248305
* Partially update member skills.
249306
* @param {Object} currentUser the user who performs operation
@@ -264,6 +321,7 @@ async function partiallyUpdateMemberSkills (currentUser, handle, data) {
264321
}
265322
// get member entered skill by member user id
266323
let memberEnteredSkill = await helper.getEntityByHashKey(handle, 'MemberEnteredSkills', 'userId', member.userId, true)
324+
267325
// cleanup - convert string to object
268326
memberEnteredSkill = helper.convertToObjectSkills(memberEnteredSkill)
269327
// cleanup
@@ -311,6 +369,7 @@ module.exports = {
311369
getHistoryStats,
312370
getMemberStats,
313371
getMemberSkills,
372+
createMemberSkills,
314373
partiallyUpdateMemberSkills
315374
}
316375

0 commit comments

Comments
 (0)