Skip to content

Commit 6d6f0c1

Browse files
authored
Merge pull request #275 from cagdas001/feature/role-intake
feat(job-service): accept `roles` array
2 parents de72b27 + 0304e68 commit 6d6f0c1

File tree

11 files changed

+190
-39
lines changed

11 files changed

+190
-39
lines changed

config/default.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ module.exports = {
4040

4141
TOPCODER_USERS_API: process.env.TOPCODER_USERS_API || 'https://api.topcoder-dev.com/v3/users',
4242
// the api to find topcoder members
43-
TOPCODER_MEMBERS_API: process.env.TOPCODER_MEMBERS_API || 'https://api.topcoder-dev.com/v3/members',
43+
TOPCODER_MEMBERS_API: process.env.TOPCODER_MEMBERS_API || 'https://api.topcoder-dev.com/v5/members',
4444
// rate limit of requests to user api
4545
MAX_PARALLEL_REQUEST_TOPCODER_USERS_API: process.env.MAX_PARALLEL_REQUEST_TOPCODER_USERS_API || 100,
4646

data/demo-data.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@
184184
"jobCandidateId": "881a19de-2b0c-4bb9-b36a-4cb5e223bdb5",
185185
"googleCalendarId": null,
186186
"customMessage": null,
187-
"xaiTemplate": "interview-30",
187+
"templateUrl": "interview-30",
188188
"round": 1,
189189
"startTimestamp": null,
190190
"attendeesList": null,
@@ -213,7 +213,7 @@
213213
"jobCandidateId": "827ee401-df04-42e1-abbe-7b97ce7937ff",
214214
"googleCalendarId": "dummyId",
215215
"customMessage": "This is a custom message",
216-
"xaiTemplate": "interview-30",
216+
"templateUrl": "interview-30",
217217
"round": 2,
218218
"startTimestamp": null,
219219
"attendeesList": null,
@@ -228,7 +228,7 @@
228228
"jobCandidateId": "827ee401-df04-42e1-abbe-7b97ce7937ff",
229229
"googleCalendarId": null,
230230
"customMessage": null,
231-
"xaiTemplate": "interview-30",
231+
"templateUrl": "interview-30",
232232
"round": 1,
233233
"startTimestamp": null,
234234
"attendeesList": null,
@@ -257,7 +257,7 @@
257257
"jobCandidateId": "a4ea7bcf-5b99-4381-b99c-a9bd05d83a36",
258258
"googleCalendarId": "dummyId",
259259
"customMessage": "This is a custom message",
260-
"xaiTemplate": "interview-30",
260+
"templateUrl": "interview-30",
261261
"round": 3,
262262
"startTimestamp": null,
263263
"attendeesList": [
@@ -275,7 +275,7 @@
275275
"jobCandidateId": "a4ea7bcf-5b99-4381-b99c-a9bd05d83a36",
276276
"googleCalendarId": "dummyId",
277277
"customMessage": "This is a custom message",
278-
"xaiTemplate": "interview-30",
278+
"templateUrl": "interview-30",
279279
"round": 2,
280280
"startTimestamp": null,
281281
"attendeesList": [
@@ -293,7 +293,7 @@
293293
"jobCandidateId": "a4ea7bcf-5b99-4381-b99c-a9bd05d83a36",
294294
"googleCalendarId": null,
295295
"customMessage": null,
296-
"xaiTemplate": "interview-30",
296+
"templateUrl": "interview-30",
297297
"round": 1,
298298
"startTimestamp": null,
299299
"attendeesList": null,

docs/Topcoder-bookings-api.postman_collection.json

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,113 @@
491491
},
492492
"response": []
493493
},
494+
{
495+
"name": "search jobs with request body",
496+
"protocolProfileBehavior": {
497+
"disableBodyPruning": true
498+
},
499+
"request": {
500+
"method": "GET",
501+
"header": [
502+
{
503+
"key": "Authorization",
504+
"type": "text",
505+
"value": "Bearer {{token_bookingManager}}"
506+
}
507+
],
508+
"body": {
509+
"mode": "raw",
510+
"raw": "{\r\n \"jobIds\": [\"{{jobId}}\",\"{{jobIdCreatedByM2M}}\"]\r\n}",
511+
"options": {
512+
"raw": {
513+
"language": "json"
514+
}
515+
}
516+
},
517+
"url": {
518+
"raw": "{{URL}}/jobs",
519+
"host": [
520+
"{{URL}}"
521+
],
522+
"path": [
523+
"jobs"
524+
],
525+
"query": [
526+
{
527+
"key": "page",
528+
"value": "0",
529+
"disabled": true
530+
},
531+
{
532+
"key": "perPage",
533+
"value": "3",
534+
"disabled": true
535+
},
536+
{
537+
"key": "sortBy",
538+
"value": "id",
539+
"disabled": true
540+
},
541+
{
542+
"key": "sortOrder",
543+
"value": "asc",
544+
"disabled": true
545+
},
546+
{
547+
"key": "projectId",
548+
"value": "21",
549+
"disabled": true
550+
},
551+
{
552+
"key": "externalId",
553+
"value": "1212",
554+
"disabled": true
555+
},
556+
{
557+
"key": "description",
558+
"value": "Dummy",
559+
"disabled": true
560+
},
561+
{
562+
"key": "startDate",
563+
"value": "2020-09-27T04:17:23.131Z",
564+
"disabled": true
565+
},
566+
{
567+
"key": "resourceType",
568+
"value": "Dummy Resource Type",
569+
"disabled": true
570+
},
571+
{
572+
"key": "skill",
573+
"value": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
574+
"disabled": true
575+
},
576+
{
577+
"key": "rateType",
578+
"value": "hourly",
579+
"disabled": true
580+
},
581+
{
582+
"key": "status",
583+
"value": "sourcing",
584+
"disabled": true
585+
},
586+
{
587+
"key": "workload",
588+
"value": "full-time",
589+
"disabled": true
590+
},
591+
{
592+
"key": "title",
593+
"value": "dummy",
594+
"disabled": true
595+
}
596+
]
597+
}
598+
},
599+
"response": []
600+
},
494601
{
495602
"name": "search jobs with with m2m all",
496603
"request": {

docs/swagger.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,11 @@ paths:
181181
type: string
182182
enum: ["sourcing", "in-review", "assigned", "closed", "cancelled"]
183183
description: The rate type.
184+
requestBody:
185+
content:
186+
application/json:
187+
schema:
188+
$ref: "#/components/schemas/JobSearchBody"
184189
responses:
185190
"200":
186191
description: OK
@@ -603,6 +608,12 @@ paths:
603608
"cancelled",
604609
"interview",
605610
"topcoder-rejected",
611+
"applied",
612+
"rejected-pre-screen",
613+
"skills-test",
614+
"phone-screen",
615+
"job-closed",
616+
"offered"
606617
]
607618
description: The job candidate status.
608619
- in: query
@@ -3363,6 +3374,15 @@ components:
33633374
type: string
33643375
example: "topcoder user"
33653376
description: "The user who updated the job last time.(Will get the user info from the token)"
3377+
JobSearchBody:
3378+
properties:
3379+
jobIds:
3380+
type: array
3381+
items:
3382+
type: string
3383+
format: uuid
3384+
description: "The array of job ids"
3385+
33663386
JobRequestBody:
33673387
required:
33683388
- projectId

src/bootstrap.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Joi.rateType = () => Joi.string().valid('hourly', 'daily', 'weekly', 'monthly')
1616
Joi.jobStatus = () => Joi.string().valid('sourcing', 'in-review', 'assigned', 'closed', 'cancelled')
1717
Joi.resourceBookingStatus = () => Joi.string().valid('placed', 'closed', 'cancelled')
1818
Joi.workload = () => Joi.string().valid('full-time', 'fractional')
19-
Joi.jobCandidateStatus = () => Joi.string().valid('open', 'placed', 'selected', 'client rejected - screening', 'client rejected - interview', 'rejected - other', 'cancelled', 'interview', 'topcoder-rejected', 'applied','rejected-pre-screen','skills-test','skills-test','phone-screen','job-closed')
19+
Joi.jobCandidateStatus = () => Joi.string().valid('open', 'placed', 'selected', 'client rejected - screening', 'client rejected - interview', 'rejected - other', 'cancelled', 'interview', 'topcoder-rejected', 'applied','rejected-pre-screen','skills-test','skills-test','phone-screen','job-closed','offered')
2020
Joi.title = () => Joi.string().max(128)
2121
Joi.paymentStatus = () => Joi.string().valid('pending', 'partially-completed', 'completed', 'cancelled')
2222
Joi.xaiTemplate = () => Joi.string().valid(...allowedXAITemplate)

src/common/helper.js

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ esIndexPropertyMapping[config.get('esConfig.ES_INDEX_JOB')] = {
111111
rateType: { type: 'keyword' },
112112
workload: { type: 'keyword' },
113113
skills: { type: 'keyword' },
114+
roles: { type: 'keyword' },
114115
status: { type: 'keyword' },
115116
isApplicationPageActive: { type: 'boolean' },
116117
createdAt: { type: 'date' },
@@ -1304,21 +1305,18 @@ async function getMemberDetailsByHandles(handles) {
13041305
}
13051306
const token = await getM2MToken();
13061307
const res = await request
1307-
.get(`${config.TOPCODER_MEMBERS_API}/_search`)
1308+
.get(`${config.TOPCODER_MEMBERS_API}/`)
13081309
.query({
1309-
query: _.map(
1310-
handles,
1311-
(handle) => `handleLower:${handle.toLowerCase()}`
1312-
).join(' OR '),
1313-
fields: 'userId,handle,firstName,lastName,email',
1310+
'handlesLower[]': handles.map(handle => handle.toLowerCase()),
1311+
fields: 'userId,handle,handleLower,firstName,lastName,email',
13141312
})
13151313
.set('Authorization', `Bearer ${token}`)
13161314
.set('Accept', 'application/json');
13171315
localLogger.debug({
13181316
context: 'getMemberDetailsByHandles',
13191317
message: `response body: ${JSON.stringify(res.body)}`,
13201318
});
1321-
return _.get(res.body, 'result.content');
1319+
return res.body;
13221320
}
13231321

13241322
/**
@@ -1327,17 +1325,14 @@ async function getMemberDetailsByHandles(handles) {
13271325
* @param {String} handle the user handle
13281326
* @returns {Object} the member details
13291327
*/
1330-
async function getV3MemberDetailsByHandle(handle) {
1331-
const token = await getM2MToken();
1332-
const res = await request
1333-
.get(`${config.TOPCODER_MEMBERS_API}/${handle}`)
1334-
.set('Authorization', `Bearer ${token}`)
1335-
.set('Accept', 'application/json');
1336-
localLogger.debug({
1337-
context: 'getV3MemberDetailsByHandle',
1338-
message: `response body: ${JSON.stringify(res.body)}`,
1339-
});
1340-
return _.get(res.body, 'result.content');
1328+
async function getMemberDetailsByHandle(handle) {
1329+
const [memberDetails] = await getMemberDetailsByHandles([handle])
1330+
1331+
if (!memberDetails) {
1332+
throw new errors.NotFoundError(`Member details are not found by handle "${handle}".`)
1333+
}
1334+
1335+
return memberDetails
13411336
}
13421337

13431338
/**
@@ -1756,7 +1751,7 @@ module.exports = {
17561751
getAuditM2Muser,
17571752
checkIsMemberOfProject,
17581753
getMemberDetailsByHandles,
1759-
getV3MemberDetailsByHandle,
1754+
getMemberDetailsByHandle,
17601755
getMemberDetailsByEmails,
17611756
createProjectMember,
17621757
listProjectMembers,

src/controllers/JobController.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ async function deleteJob (req, res) {
5757
* @param res the response
5858
*/
5959
async function searchJobs (req, res) {
60+
if (req.body && req.body.jobIds) {
61+
req.query.jobIds = req.body.jobIds
62+
}
6063
const result = await service.searchJobs(req.authUser, req.query)
6164
helper.setResHeaders(req, res, result)
6265
res.send(result.result)

src/models/Job.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ module.exports = (sequelize) => {
9494
type: Sequelize.JSONB,
9595
allowNull: false
9696
},
97+
roles: {
98+
type: Sequelize.ARRAY(Sequelize.UUID)
99+
},
97100
status: {
98101
type: Sequelize.STRING(255),
99102
allowNull: false

0 commit comments

Comments
 (0)