Skip to content

Commit f94c842

Browse files
author
James Cori
committed
Merge branch 'develop'
2 parents 75e0d76 + a1e5cc6 commit f94c842

10 files changed

+80
-15
lines changed

app.js

+4
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ app.use((err, req, res, next) => {
9292
}
9393
}
9494

95+
if (!_.isUndefined(err.metadata)) {
96+
errorResponse.metadata = err.metadata
97+
}
98+
9599
res.status(status).json(errorResponse)
96100
})
97101

config/default.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ module.exports = {
2323
AUTH0_PROXY_SERVER_URL: process.env.AUTH0_PROXY_SERVER_URL,
2424

2525
TERMS_API_URL: process.env.TERMS_API_URL || 'https://api.topcoder-dev.com/v5/terms',
26-
MEMBER_API_URL: process.env.MEMBER_API_URL || 'https://api.topcoder-dev.com/v3/members',
26+
MEMBER_API_URL: process.env.MEMBER_API_URL || 'https://api.topcoder-dev.com/v5/members',
2727
USER_API_URL: process.env.USER_API_URL || 'https://api.topcoder-dev.com/v3/users',
2828
CHALLENGE_API_URL: process.env.CHALLENGE_API_URL || 'http://localhost:4000/v5/challenges',
2929
CHALLENGE_PHASES_API_URL: process.env.CHALLENGE_PHASES_API_URL || 'https://api.topcoder-dev.com/v5/challenge-phases',

docs/swagger.yaml

+21
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,9 @@ definitions:
577577
type: string
578578
description: The unauthorized error message.
579579
example: Unable to authenticate the user.
580+
metadata:
581+
type: object
582+
description: freeform metadata object
580583
NotFound:
581584
type: object
582585
description: The not found error entity.
@@ -585,6 +588,9 @@ definitions:
585588
type: string
586589
description: The not found error message.
587590
example: A resource with the name could not be found.
591+
metadata:
592+
type: object
593+
description: freeform metadata object
588594
ServerError:
589595
type: object
590596
description: The server error entity.
@@ -596,6 +602,9 @@ definitions:
596602
Something went wrong while processing your request. We’re sorry for
597603
the trouble. We’ve been notified of the error and will correct it as
598604
soon as possible. Please try your request again in a moment.
605+
metadata:
606+
type: object
607+
description: freeform metadata object
599608
ServiceUnavailable:
600609
type: object
601610
description: The server is unavailable
@@ -604,6 +613,9 @@ definitions:
604613
type: string
605614
description: The server error message.
606615
example: Something went wrong with the server.
616+
metadata:
617+
type: object
618+
description: freeform metadata object
607619
BadRequest:
608620
type: object
609621
description: The bad request error entity.
@@ -612,6 +624,9 @@ definitions:
612624
type: string
613625
description: The bad request error message.
614626
example: Invalid input.
627+
metadata:
628+
type: object
629+
description: freeform metadata object
615630
Forbidden:
616631
type: object
617632
description: The permission error entity.
@@ -620,6 +635,9 @@ definitions:
620635
type: string
621636
description: The forbidden error message.
622637
example: You are not allowed to access the request.
638+
metadata:
639+
type: object
640+
description: freeform metadata object
623641
Conflict:
624642
type: object
625643
description: The conflict error entity.
@@ -630,3 +648,6 @@ definitions:
630648
type: string
631649
description: The conflict error message.
632650
example: Creating a resource with a name already exists.
651+
metadata:
652+
type: object
653+
description: freeform metadata object

src/common/errors.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@ function createError (name, statusCode) {
1515
* The error constructor
1616
* @param {String} message the error message
1717
* @param {String} [cause] the error cause
18+
* @param {Object} metadata the metadata
1819
* @constructor
1920
*/
20-
function ErrorCtor (message, cause) {
21+
function ErrorCtor (message, cause, metadata) {
2122
Error.call(this)
2223
Error.captureStackTrace(this)
2324
this.message = message || name
2425
this.cause = cause
26+
this.metadata = metadata
2527
this.httpStatus = statusCode
2628
}
2729

src/common/helper.js

+28-5
Original file line numberDiff line numberDiff line change
@@ -177,13 +177,13 @@ async function getMemberIdByHandle (handle) {
177177
async function getMemberIdByHandleFromV3Members (handle) {
178178
let memberId
179179
try {
180-
logger.warn(`getMemberIdByHandle ${handle} from v3`)
180+
logger.warn(`getMemberIdByHandle ${handle} from v5`)
181181
const res = await getRequest(`${config.MEMBER_API_URL}/${handle}`)
182-
if (_.get(res, 'body.result.content.userId')) {
183-
memberId = String(res.body.result.content.userId)
182+
if (_.get(res, 'body.userId')) {
183+
memberId = String(res.body.userId)
184184
}
185185
// handle return from v3 API, handle and memberHandle are the same under case-insensitive condition
186-
handle = _.get(res, 'body.result.content.handle')
186+
handle = _.get(res, 'body.handle')
187187
} catch (error) {
188188
// re-throw all error except 404 Not-Founded, BadRequestError should be thrown if 404 occurs
189189
if (error.status !== 404) {
@@ -256,6 +256,23 @@ async function scan (modelName, scanParams) {
256256
})
257257
}
258258

259+
/**
260+
* Get all data collection (avoid default page limit of DynamoDB) by scan parameters
261+
* @param {Object} modelName The dynamoose model name
262+
* @param {Object} scanParams The scan parameters object
263+
* @returns {Array}
264+
*/
265+
async function scanAll (modelName, scanParams) {
266+
let results = await models[modelName].scan(scanParams).exec()
267+
let lastKey = results.lastKey
268+
while (!_.isUndefined(results.lastKey)) {
269+
const newResult = await models[modelName].scan(scanParams).startAt(lastKey).exec()
270+
results = [...results, ...newResult]
271+
lastKey = newResult.lastKey
272+
}
273+
return results
274+
}
275+
259276
/**
260277
* Get data collection by query parameters
261278
* @param {Object} modelName The dynamoose model name
@@ -430,15 +447,20 @@ function partialMatch (filter, value) {
430447
*/
431448
async function checkAgreedTerms (userId, terms) {
432449
const unAgreedTerms = []
450+
const missingTerms = []
433451
for (const term of terms) {
434452
const res = await getRequest(`${config.TERMS_API_URL}/${term.id}`, { userId })
435453
if (!_.get(res, 'body.agreed', false)) {
436454
unAgreedTerms.push(_.get(res, 'body.title', term))
455+
missingTerms.push({
456+
termId: term.id,
457+
roleId: term.roleId
458+
})
437459
}
438460
}
439461

440462
if (unAgreedTerms.length > 0) {
441-
throw new errors.ForbiddenError(`The user has not yet agreed to the following terms: [${unAgreedTerms.join(', ')}]`)
463+
throw new errors.ForbiddenError(`The user has not yet agreed to the following terms: [${unAgreedTerms.join(', ')}]`, null, { missingTerms })
442464
}
443465
}
444466

@@ -455,6 +477,7 @@ module.exports = {
455477
update,
456478
query,
457479
scan,
480+
scanAll,
458481
validateDuplicate,
459482
getRequest,
460483
postEvent,

src/controllers/ResourceRoleController.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*/
44

55
const service = require('../services/ResourceRoleService')
6+
const helper = require('../common/helper')
67

78
/**
89
* Get resource roles.
@@ -11,7 +12,8 @@ const service = require('../services/ResourceRoleService')
1112
*/
1213
async function getResourceRoles (req, res) {
1314
const result = await service.getResourceRoles(req.query)
14-
res.send(result)
15+
helper.setResHeaders(req, res, result)
16+
res.send(result.data)
1517
}
1618

1719
/**

src/controllers/ResourceRolePhaseDependencyController.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*/
44

55
const service = require('../services/ResourceRolePhaseDependencyService')
6+
const helper = require('../common/helper')
67

78
/**
89
* Get dependencies.
@@ -11,7 +12,8 @@ const service = require('../services/ResourceRolePhaseDependencyService')
1112
*/
1213
async function getDependencies (req, res) {
1314
const result = await service.getDependencies(req.query)
14-
res.send(result)
15+
helper.setResHeaders(req, res, result)
16+
res.send(result.data)
1517
}
1618

1719
/**

src/services/ResourceRolePhaseDependencyService.js

+8-3
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,15 @@ async function getDependencies (criteria) {
2424
options.resourceRoleId = { eq: criteria.resourceRoleId }
2525
}
2626
if (!_.isNil(criteria.phaseState)) {
27-
options.phaseState = { eq: criteria.phaseState }
27+
options.phaseState = { eq: criteria.phaseState === 'true' }
28+
}
29+
const list = await helper.scanAll('ResourceRolePhaseDependency', options)
30+
return {
31+
data: list,
32+
total: list.length,
33+
page: 1,
34+
perPage: Math.max(10, list.length)
2835
}
29-
const list = await helper.scan('ResourceRolePhaseDependency', options)
30-
return list
3136
}
3237

3338
getDependencies.schema = {

src/services/ResourceRoleService.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const payloadFields = ['id', 'name', 'legacyId', 'fullReadAccess', 'fullWriteAcc
1717
* @returns {Array} the search result
1818
*/
1919
async function getResourceRoles (criteria) {
20-
let records = await helper.scan('ResourceRole')
20+
let records = await helper.scanAll('ResourceRole')
2121
if (criteria.name) records = _.filter(records, e => (criteria.name === e.name))
2222
if (criteria.id) records = _.filter(records, e => (criteria.id === e.id))
2323
if (criteria.legacyId) records = _.filter(records, e => (_.toNumber(criteria.legacyId) === _.toNumber(e.legacyId)))
@@ -26,7 +26,13 @@ async function getResourceRoles (criteria) {
2626
if (!_.isUndefined(criteria.fullReadAccess)) records = _.filter(records, e => (e.fullReadAccess === (criteria.fullReadAccess === 'true')))
2727
if (!_.isUndefined(criteria.fullWriteAccess)) records = _.filter(records, e => (e.fullWriteAccess === (criteria.fullWriteAccess === 'true')))
2828

29-
return _.map(records, e => _.pick(e, payloadFields))
29+
const result = _.map(records, e => _.pick(e, payloadFields))
30+
return {
31+
data: result,
32+
total: result.length,
33+
page: 1,
34+
perPage: Math.max(10, result.length)
35+
}
3036
}
3137

3238
getResourceRoles.schema = {

src/services/ResourceService.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ async function deleteResource (currentUser, resource) {
385385
undefined)
386386

387387
if (!ret) {
388-
throw new errors.BadRequestError(`User ${handle || resource.memberHandle} doesn't have resource with roleId: ${resource.roleId} in challenge ${challengeId}`)
388+
throw new errors.NotFoundError(`User ${handle || resource.memberHandle} doesn't have resource with roleId: ${resource.roleId} in challenge ${challengeId}`)
389389
}
390390

391391
await ret.delete()

0 commit comments

Comments
 (0)