-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#119: Add REST endpoint for DAC to reject applications #179
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall it looks solid! Great work :)
Just a few small suggestions + discussion points!
(also, don't forget to paste in a screenshot of the tests passing in your PR while we wait on getting automated testing working 🫡)
if (typeof applicationId !== 'number' || !applicationId) { | ||
res.status(400).send({ | ||
message: 'Invalid request. ApplicationId must be a valid number and is required.', | ||
errors: 'MissingOrInvalidParameters', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is likely out of the scope of this PR, so feel free to ignore this, but I wonder if we should add a code
object into this return which is specifically for a error code?
We also likely should make these a centralized thing, but again, that's likely out of the scope of this PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah useful information to communicate as part of: https://github.com/orgs/Pan-Canadian-Genome-Library/projects/1/views/1?pane=issue&itemId=95389716&issue=Pan-Canadian-Genome-Library%7Cdaco%7C176
if (state === ApplicationStates.REJECTED) { | ||
res.status(400).json({ message: 'Application is already rejected and cannot be modified.' }); | ||
} | ||
|
||
if (state !== ApplicationStates.DAC_REVIEW) { | ||
res.status(400).json({ message: 'Application must be in DAC Review status to be rejected.' }); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These two if blocks basically do the same thing, I wonder if it's worth it to specifically do a check for a application is already rejected? We could just provide the !== DAC_REVIEW message since it covers all scenarios.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These two if blocks basically do the same thing, I wonder if it's worth it to specifically do a check for a application is already rejected? We could just provide the !== DAC_REVIEW message since it covers all scenarios.
Should we make the message generic in this case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, maybe something like this?:
Application can only be rejected if under DAC Review
or
Application may only be rejected if in DAC Review
apps/api/src/resources/swagger.yaml
Outdated
schema: | ||
type: object | ||
properties: | ||
error: | ||
type: string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You likely should just reference the ClientErrors
scheme here? See other API defs in the file for a example.
content:
application/json:
schema:
$ref: '#/components/responses/ClientErrors'
apps/api/src/resources/swagger.yaml
Outdated
schema: | ||
type: object | ||
properties: | ||
error: | ||
type: string | ||
details: | ||
type: string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, similar thing here, it'll be a good idea to just reference the ServerError
schema here too. Might be a good idea to just copy and paste from a previously defined API, this helps standardize things :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just some small changes! But overall looks solid
let message = rejectedApplication.message || 'An unexpected error occurred.'; | ||
let errors = rejectedApplication.errors; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can probably use const
here.
if (state === ApplicationStates.REJECTED) { | ||
res.status(400).json({ message: 'Application is already rejected and cannot be modified.' }); | ||
} | ||
|
||
if (state !== ApplicationStates.DAC_REVIEW) { | ||
res.status(400).json({ message: 'Application must be in DAC Review status to be rejected.' }); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These two if blocks basically do the same thing, I wonder if it's worth it to specifically do a check for a application is already rejected? We could just provide the !== DAC_REVIEW message since it covers all scenarios.
Should we make the message generic in this case?
res.status(400).json({ message: 'Application ID is required.' }); | ||
} | ||
|
||
if (typeof applicationId !== 'number' || !applicationId) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can probably simplify this condition using something like this:
if (isNaN(parseInt(applicationId))) {
...
}
const { applicationId } = req.body; | ||
const { repId, reviewData, comment, role } = req.body; | ||
|
||
if (!role && (role !== 'REP' || role !== 'DAC')) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't this be OR ||
? Because if the role is undefined, then it should trigger the condition cause its not a valid role?
if (!role || (role !== 'REP' || role !== 'DAC')) {
...
}
if (!applicationId) { | ||
res.status(400).json({ message: 'Application ID is required.' }); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both of these if
blocks send status 400
and concern applicationId
so I think it would make sense to combine them:
if (!applicationId || isNaN(parseInt(applicationId))) {
res.status(400).json({ message: 'Invalid request. ApplicationId is required and must be a valid number.',
errors: 'MissingOrInvalidParameters', });
}
} | ||
}); | ||
|
||
// Endpoint for reps to request revisions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this /request-revisions
endpoint being added? It's not in the ticket and the requestApplicationRevisions
function does not exist in this branch
@@ -27,8 +27,11 @@ import { | |||
getAllApplications, | |||
getApplicationById, | |||
getApplicationStateTotals, | |||
rejectApplication, | |||
requestApplicationRevisions, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This requestApplicationRevisions
import doesn't exist in this branch, needs to be removed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to clarify what's going on with the rep-revisions
code
Summary
This PR introduces a new REST API endpoint to allow DAC to reject applications. Once an application is rejected, it cannot be reopened or modified. The application status transitions from DAC Review to Rejected, and a timestamp is recorded in the application history. The API returns a clear success or failure message. (#119)
Description of Changes
API Service
Added a new POST /applications/{applicationId}/reject endpoint for DAC to reject applications.
Ensured that DAC can only reject one application at a time.
Updated the application status transition logic:
Implemented history tracking by appending a timestamp when an application is rejected.
Standardized API response messages for success and failure scenarios.
Validation & Constraints
Ensured that only applications in DAC Review status can be rejected.
Applications already in Rejected status cannot be modified further.
Restricted the action to authorized DAC users only.
Database Changes
Added a timestamp field to track rejection events in the application history table.
Readiness Checklist
#{119}: feature: Add REST endpoint for DAC to reject applications
api, feature
labels have been applied.