diff --git a/docs/Submission API.postman_collection.json b/docs/Submission API.postman_collection.json index 973c8d8b..6daadf4a 100755 --- a/docs/Submission API.postman_collection.json +++ b/docs/Submission API.postman_collection.json @@ -825,7 +825,7 @@ ], "body": { "mode": "raw", - "raw": "{\n\t\"score\": 92.5,\n\t\"scoreCardId\": 123456789,\n\t\"submissionId\": \"{{submissionID}}\",\n\t\"typeId\": \"c56a4180-65aa-42ec-a945-5fd21dec0503\",\n\t\"reviewerId\": \"c56a4180-65aa-42ec-a945-5fd21d3d26f8\"\n}" + "raw": "{\n\t\"score\": 92.5,\n\t\"scoreCardId\": 123456789,\n\t\"submissionId\": \"{{submissionID}}\",\n\t\"status\": \"queued\",\n\t\"typeId\": \"c56a4180-65aa-42ec-a945-5fd21dec0503\",\n\t\"reviewerId\": \"c56a4180-65aa-42ec-a945-5fd21d3d26f8\"\n}" }, "url": { "raw": "{{URL}}/reviews", @@ -1405,7 +1405,7 @@ ], "body": { "mode": "raw", - "raw": "{\n\t\"score\": 90.5,\n\t\"scoreCardId\": 123456789,\n\t\"submissionId\": \"{{submissionID}}\",\n\t\"typeId\": \"c56a4180-65aa-42ec-a945-5fd21dec0503\",\n\t\"reviewerId\": \"c56a4180-65aa-42ec-a945-5fd21d3d26f8\"\n}" + "raw": "{\n\t\"score\": 90.5,\n\t\"scoreCardId\": 123456789,\n\t\"submissionId\": \"{{submissionID}}\",\n\t\"status\": \"completed\",\n\t\"typeId\": \"c56a4180-65aa-42ec-a945-5fd21dec0503\",\n\t\"reviewerId\": \"c56a4180-65aa-42ec-a945-5fd21d3d26f8\"\n}" }, "url": { "raw": "{{URL}}/reviews/{{reviewID}}", diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 74923d39..ac0d73b7 100755 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -74,6 +74,7 @@ paths: - $ref: '#/parameters/filterSubmissionReviewReviewerId' - $ref: '#/parameters/filterSubmissionReviewScoreCardId' - $ref: '#/parameters/filterSubmissionReviewSubmissionId' + - $ref: '#/parameters/filterSubmissionReviewStatus' - $ref: '#/parameters/filterSubmissionReviewSummationScoreCardId' - $ref: '#/parameters/filterSubmissionReviewSummationSubmissionId' - $ref: '#/parameters/filterSubmissionReviewSummationAggregateScore' @@ -898,7 +899,7 @@ paths: description: | Get all reviews. Link headers are sent back and they have rel set to prev, next, first, last and contain the relevant URL. - Resulted collection of reviews can be filtered using filter parameters `score`, `typeId`, `reviewerId`, `scoreCardId` (all filter parameters are optional and combined by the logical operation `AND`). + Resulted collection of reviews can be filtered using filter parameters `score`, `typeId`, `reviewerId`, `scoreCardId`, `status` (all filter parameters are optional and combined by the logical operation `AND`). **Authorization:** Review is accessible by roles `admin` and `copilot`. tags: @@ -915,6 +916,7 @@ paths: - $ref: '#/parameters/filterReviewReviewerId' - $ref: '#/parameters/filterReviewScoreCardId' - $ref: '#/parameters/filterReviewSubmissionId' + - $ref: '#/parameters/filterReviewStatus' responses: 200: description: OK - the request was successful, the resource are returned. @@ -930,6 +932,7 @@ paths: reviewerId: 'c23a4180-65aa-42ec-a945-5fd21dec0503' scoreCardId: 123456789 submissionId: 'd67a4180-65aa-42ec-a945-5fd21dec0503' + status: 'queued' created: '2018-05-20T07:00:30.123Z' updated: '2018-06-01T07:36:28.178Z' createdBy: 'admin' @@ -940,6 +943,7 @@ paths: reviewerId: 'c23a4180-65aa-42ec-a945-5fd21dec0503' scoreCardId: 123456789 submissionId: 'd23a4180-65aa-42ec-a945-5fd21dec0503' + status: 'completed' created: '2018-05-20T07:00:30.123Z' updated: '2018-06-01T07:36:28.178Z' createdBy: 'admin' @@ -981,7 +985,7 @@ paths: description: | Get response status and headers information for the endpoint. Link headers are sent back and they have rel set to prev, next, first, last and contain the relevant URL. - Requested reviews can be filtered using filter parameters `score`, `typeId`, `reviewerId`, `scoreCardId` (all filter parameters are optional and combined by the logical operation `AND`). + Requested reviews can be filtered using filter parameters `score`, `typeId`, `reviewerId`, `scoreCardId`, `status` (all filter parameters are optional and combined by the logical operation `AND`). **Authorization:** Review is accessible by roles `admin` and `copilot`. tags: @@ -995,6 +999,7 @@ paths: - $ref: '#/parameters/filterReviewTypeId' - $ref: '#/parameters/filterReviewReviewerId' - $ref: '#/parameters/filterReviewScoreCardId' + - $ref: '#/parameters/filterReviewStatus' responses: 200: description: OK - The request was successful. @@ -1632,6 +1637,14 @@ parameters: description: The submissionId filter of the reviews associated with the submission. required: false type: string + + filterSubmissionReviewStatus: + in: query + name: review.status + description: The status of the reviews associated with the submission. + required: false + type: string + enum: [queued, completed] filterSubmissionReviewSummationScoreCardId: in: query @@ -1733,6 +1746,14 @@ parameters: required: false type: string + filterReviewStatus: + in: query + name: status + description: The status of the review, whether it queued or has been completed. + required: false + type: string + enum: [queued, completed] + filterReviewTypeName: in: query name: name @@ -1946,6 +1967,7 @@ definitions: - reviewerId - scoreCardId - submissionId + - status allOf: - type: object properties: @@ -1982,6 +2004,11 @@ definitions: type: string description: The submission id. example: 'a12bc180-65ab-42ec-a945-5fd2dec1567' + status: + type: string + enum: [queued, completed] + description: The status of the review, whether it is queued or has been completed. + example: 'queued' metadata: type: object description: Review Metadata in JSON format @@ -1995,6 +2022,7 @@ definitions: - reviewerId - scoreCardId - submissionId + - status allOf: - $ref: '#/definitions/PartiallyReview' diff --git a/src/bootstrap.js b/src/bootstrap.js index 5a3d1fa6..c411f721 100755 --- a/src/bootstrap.js +++ b/src/bootstrap.js @@ -13,6 +13,7 @@ joi.id = () => joi.number().integer().min(1) joi.score = () => joi.number() joi.pageSize = () => joi.number().integer().min(1).max(config.get('MAX_PAGE_SIZE')) joi.sortOrder = () => joi.string().valid('asc', 'desc', 'ASC', 'DESC') +joi.reviewStatus = () => joi.string().valid('queued', 'completed') function buildServices (dir) { const files = fs.readdirSync(dir) diff --git a/src/services/ReviewService.js b/src/services/ReviewService.js index 49e8db3f..9ba9f59b 100644 --- a/src/services/ReviewService.js +++ b/src/services/ReviewService.js @@ -88,6 +88,7 @@ const listReviewsQuerySchema = { reviewerId: joi.alternatives().try(joi.id(), joi.string().uuid()), scoreCardId: joi.id(), submissionId: joi.string().uuid(), + status: joi.reviewStatus(), page: joi.id(), perPage: joi.pageSize(), orderBy: joi.sortOrder() @@ -159,6 +160,7 @@ createReview.schema = { .error(errors => ({message: '"reviewerId" must be a number or a string'})), scoreCardId: joi.id().required(), submissionId: joi.string().uuid().required(), + status: joi.reviewStatus().required(), metadata: joi.object() }).required() } @@ -189,7 +191,7 @@ function * _updateReview (authUser, reviewId, entity) { 'id': reviewId }, UpdateExpression: `set score = :s, scoreCardId = :sc, submissionId = :su, - typeId = :t, reviewerId = :r, + typeId = :t, reviewerId = :r, #st = :st, updated = :ua, updatedBy = :ub`, ExpressionAttributeValues: { ':s': entity.score || exist.score, @@ -197,8 +199,12 @@ function * _updateReview (authUser, reviewId, entity) { ':su': entity.submissionId || exist.submissionId, ':t': entity.typeId || exist.typeId, ':r': entity.reviewerId || exist.reviewerId, + ':st': entity.status || exist.status, ':ua': currDate, ':ub': authUser.handle || authUser.sub + }, + ExpressionAttributeNames: { + '#st': 'status' } } @@ -256,6 +262,7 @@ updateReview.schema = { reviewerId: joi.alternatives().try(joi.id(), joi.string().uuid()).required(), scoreCardId: joi.id().required(), submissionId: joi.string().uuid().required(), + status: joi.reviewStatus().required(), metadata: joi.object() }).required() } @@ -280,6 +287,7 @@ patchReview.schema = { reviewerId: joi.alternatives().try(joi.id(), joi.string().uuid()), scoreCardId: joi.id(), submissionId: joi.string().uuid(), + status: joi.reviewStatus(), metadata: joi.object() }) } diff --git a/src/services/SubmissionService.js b/src/services/SubmissionService.js index c146ecb7..180f1e64 100755 --- a/src/services/SubmissionService.js +++ b/src/services/SubmissionService.js @@ -197,6 +197,7 @@ const listSubmissionsQuerySchema = { 'review.reviewerId': joi.string().uuid(), 'review.scoreCardId': joi.id(), 'review.submissionId': joi.string().uuid(), + 'review.status': joi.reviewStatus(), 'reviewSummation.scoreCardId': joi.id(), 'reviewSummation.submissionId': joi.string().uuid(), 'reviewSummation.aggregateScore': joi.score(), diff --git a/test/common/testData.js b/test/common/testData.js index e932a3a2..7dac36ee 100644 --- a/test/common/testData.js +++ b/test/common/testData.js @@ -252,6 +252,7 @@ const testReview = { reviewerId: 'c23a4180-65aa-42ec-a945-5fd21dec0503', submissionId: 'a12a4180-65aa-42ec-a945-5fd21dec0501', scoreCardId: 123456789, + status: 'queued', typeId: 'c56a4180-65aa-42ec-a945-5fd21dec0501', created: '2018-05-20T07:00:30.123Z', updated: '2018-06-01T07:36:28.178Z', @@ -267,6 +268,7 @@ const testReviewPatch = { reviewerId: 'c23a4180-65aa-42ec-a945-5fd21dec0503', submissionId: 'a12a4180-65aa-42ec-a945-5fd21dec0501', scoreCardId: 123456789, + status: 'queued', typeId: 'c56a4180-65aa-42ec-a945-5fd21dec0501', created: '2018-05-20T07:00:30.123Z', updated: '2018-06-01T07:36:28.178Z', @@ -289,6 +291,7 @@ const testReviewES = { reviewerId: 'c23a4180-65aa-42ec-a945-5fd21dec0503', submissionId: 'a12a4180-65aa-42ec-a945-5fd21dec0501', scoreCardId: 123456789, + status: 'queued', typeId: 'c56a4180-65aa-42ec-a945-5fd21dec0501', created: '2018-05-20T07:00:30.123Z', updated: '2018-06-01T07:36:28.178Z', @@ -311,6 +314,7 @@ const testReviewsES = { { score: 95.5, reviewerId: 'c23a4180-65aa-42ec-a945-5fd21dec0503', submissionId: 'a12a4180-65aa-42ec-a945-5fd21dec0501', + status: 'queued', updatedBy: 'admin', createdBy: 'admin', scoreCardId: 123456789, @@ -329,6 +333,7 @@ const testReviewsES = { updatedBy: 'admin', createdBy: 'admin', scoreCardId: 123456789, + status: 'queued', created: '2018-05-20T07:00:30.123Z', typeId: 'c56a4180-65aa-42ec-a945-5fd21dec0503', id: 'd24d4180-65aa-42ec-a945-5fd21dec0504', @@ -344,6 +349,7 @@ const testReviewsES = { updatedBy: 'admin', createdBy: 'admin', scoreCardId: 123456789, + status: 'queued', created: '2018-05-20T07:00:30.123Z', typeId: 'c56a4180-65aa-42ec-a945-5fd21dec0503', id: 'd24d4180-65aa-42ec-a945-5fd21dec0502', @@ -359,6 +365,7 @@ const testReviewsES = { updatedBy: 'admin', createdBy: 'admin', scoreCardId: 123456789, + status: 'queued', created: '2018-05-20T07:00:30.123Z', typeId: 'c56a4180-65aa-42ec-a945-5fd21dec0503', id: 'd24d4180-65aa-42ec-a945-5fd21dec0503',