Skip to content
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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

Azher2Ali
Copy link
Contributor

@Azher2Ali Azher2Ali commented Jan 29, 2025

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:

    1. DAC Review → Rejected
    2. Applications that are Rejected cannot be reopened or modified.
  • 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

  • Self Review
    • I have reviewed the code and ensured it meets the requirements.
    • The feature has been manually tested locally.
  • PR Format
    • The PR title is properly formatted to match the pattern: #{119}: feature: Add REST endpoint for DAC to reject applications
  • Labels Added
    • api, feature labels have been applied.
  • Local Testing
    • Successfully built all packages locally

@Azher2Ali Azher2Ali changed the title Add REST endpoint for DAC to reject applications (#119) #119 Add REST endpoint for DAC to reject applications Jan 29, 2025
@Azher2Ali Azher2Ali changed the title #119 Add REST endpoint for DAC to reject applications #119: Add REST endpoint for DAC to reject applications Jan 29, 2025
Copy link
Member

@surajgoraya surajgoraya left a 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',
Copy link
Member

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

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines 258 to 264
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.' });
}
Copy link
Member

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.

Copy link
Contributor

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?

Copy link
Member

@surajgoraya surajgoraya Jan 31, 2025

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

Comment on lines 357 to 361
schema:
type: object
properties:
error:
type: string
Copy link
Member

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'

Comment on lines 366 to 372
schema:
type: object
properties:
error:
type: string
details:
type: string
Copy link
Member

@surajgoraya surajgoraya Jan 30, 2025

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 :)

Copy link
Contributor

@JamesTLopez JamesTLopez left a 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

Comment on lines 275 to 276
let message = rejectedApplication.message || 'An unexpected error occurred.';
let errors = rejectedApplication.errors;
Copy link
Contributor

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.

Comment on lines 258 to 264
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.' });
}
Copy link
Contributor

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) {
Copy link
Contributor

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')) {
Copy link
Contributor

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.' });
}

Copy link
Contributor

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
Copy link
Contributor

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,
Copy link
Contributor

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

Copy link
Contributor

@demariadaniel demariadaniel left a 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants