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

Built out shift signup endpoints #90

Merged
merged 23 commits into from
Feb 6, 2022
Merged

Built out shift signup endpoints #90

merged 23 commits into from
Feb 6, 2022

Conversation

hujoseph99
Copy link
Contributor

@hujoseph99 hujoseph99 commented Jan 16, 2022

Ticket link

Closes #54

Implementation description

  • Defined CreateShiftSignupRequestDTO, UpdateShiftSignupRequestDTO, ShiftSignupResponseDTO types
  • Implemented the following CRUD endpoints with their corresponding graphql queries and mutations:
    • createShiftSignups
    • updateShiftSignup
    • getShiftSignupsForUser
  • Prisma schema changes (with corresponding migrations):
    • Added note varchar to Signup prisma model
    • Added foreign key constraint to userId in Signup model.
    • Added a unique key constraint to for shiftId and userId pair in Signup model

Steps to test

  1. Ensure that the docker containers are up and running
  2. Run prisma migration and generate commands
  3. Ensure that you have test data in the following tables: users, shifts, postings, branches.
  • If you don't have data, these commands might be helpful for getting some in easily:
  • Through the Postgres CLI:
    • insert into branches (id, name) values (1, 'test branch');
    • insert into postings (id, branch_id, type, title, description, auto_closing_date, start_date, end_date, status) values (1, 1, 'GROUP', 'a', 'a', '2022-01-09T21:33:51.302Z', '2022-01-09T21:33:51.302Z', '2022-01-09T21:33:51.302Z', 'DRAFT');
  • Through graphql interface (localhost:5000/graphql):
    • mutation { createShifts( shifts: { postingId: "1" times: [ { startTime: "2022-01-25T13:30", endTime: "2022-01-25T15:00" } { startTime: "2022-01-26T12:00", endTime: "2022-01-26T16:00" } ] endDate: "2022-03-15" recurrenceInterval: BIWEEKLY } ) { id postingId startTime endTime } }
  • Credits to @lambo-liu in Create Shift CRUD Methods and GraphQL Resolvers #55
  1. Go to localhost:5000/graphql and test the following new endpoints: createShiftSignups, updateShiftSignup, and getShiftSignupsForUser. The following are some query/mutations that I wrote in my own testing that you might be able to use:
query {
  getShiftSignupsForUser(userId: "1") {
    shiftId
    userId
    numVolunteers
    note
    status
  }
}

mutation {
  createShiftSignups(
    shifts: [{ shiftId: 2, userId: 1, numVolunteers: 3, note: "test" }]
  ) {
    shiftId
    userId
    numVolunteers
    note
  }
}

mutation {
  updateShiftSignup(
    shiftId: "2"
    userId: "1"
    update: { status: CONFIRMED, note: "test", numVolunteers: 3 }
  ) {
    shiftId
    userId
    numVolunteers
    note
    status
  }
}

What should reviewers focus on?

  • Ensure that it works for edge cases like duplicating shift signups, signing up for a shift that doesn't exist, a user that doesn't exist signing up for a shift, etc.
  • General testing for basic features

Checklist

  • My PR name is descriptive and in imperative tense
  • My commit messages are descriptive and in imperative tense. My commits are atomic and trivial commits are squashed or fixup'd into non-trivial commits
  • I have run the appropriate linter(s)
  • I have requested a review from the PL, as well as other devs who have background knowledge on this PR or who will be building on top of this PR

LenaNguyen
LenaNguyen previously approved these changes Jan 26, 2022
Copy link
Member

@LenaNguyen LenaNguyen left a comment

Choose a reason for hiding this comment

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

Just wait for this comment to be addressed. Everything looks great!

Copy link
Member

@sherryhli sherryhli left a comment

Choose a reason for hiding this comment

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

Just jumping in to point out a small issue with the order of migrations 🙂

@hujoseph99
Copy link
Contributor Author

Sorry for the late response, I've been busy these past two days. I've made the changes now!

@@ -128,6 +132,7 @@ const authorizedByAllRoles = () =>
const authorizedByAdmin = () => isAuthorizedByRole(new Set(["ADMIN"]));
const authorizedByAdminAndVolunteer = () =>
isAuthorizedByRole(new Set(["ADMIN", "VOLUNTEER"]));
const authorizedByVolunteer = () => isAuthorizedByRole(new Set(["VOLUNTEER"]));
Copy link
Member

Choose a reason for hiding this comment

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

we also want to check isAuthorizedByUserId here to check that the userid in the token is the same as the userid they are signingup the shift as

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added!

backend/services/implementations/shiftSignupService.ts Outdated Show resolved Hide resolved
backend/services/implementations/shiftSignupService.ts Outdated Show resolved Hide resolved
@@ -128,6 +132,11 @@ const authorizedByAllRoles = () =>
const authorizedByAdmin = () => isAuthorizedByRole(new Set(["ADMIN"]));
const authorizedByAdminAndVolunteer = () =>
isAuthorizedByRole(new Set(["ADMIN", "VOLUNTEER"]));
const authorizedByVolunteer = () => {
return (
isAuthorizedByRole(new Set(["VOLUNTEER"])) && isAuthorizedByUserId("userid")
Copy link
Member

Choose a reason for hiding this comment

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

I don't think isAuthorizedByUserId can be used as-is because it just checks the top-level argument with name userId, but in this case, we want a field called userId under an top-evel argument called shifts (which is an array). Would likely need a new middleware function to do this check.

@LenaNguyen Thoughts about making this a separate task as it was not included in the original ticket description?

Copy link
Member

Choose a reason for hiding this comment

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

We will likely need another ticket for sorting out access control anyways, we've been restricting nearly everything to admins only right now

Copy link
Member

Choose a reason for hiding this comment

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

yeah we can do it in a separate ticket

Copy link
Member

Choose a reason for hiding this comment

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

Made a ticket: #115

@@ -124,15 +124,16 @@ model Shift {
}

model Signup {
id Int @id @default(autoincrement())
shift Shift @relation(fields: [shiftId], references: [id])
shiftId Int @map("shifts_id")
user User @relation(fields: [userId], references: [id])
Copy link
Member

Choose a reason for hiding this comment

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

Another thought: we can just make the foreign key reference on the volunteers table rather than the base users table to enforce the "only volunteers can sign up" rule

Copy link
Member

Choose a reason for hiding this comment

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

That also works but I think our middleware for checking the role is good enough for now. We would still need to go through each shift to check that the volunteerID is the same as the volunteerID associated with the user in the token.

Copy link
Member

@LenaNguyen LenaNguyen left a comment

Choose a reason for hiding this comment

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

just one small thing and then i'll approve :))

@@ -128,6 +132,11 @@ const authorizedByAllRoles = () =>
const authorizedByAdmin = () => isAuthorizedByRole(new Set(["ADMIN"]));
const authorizedByAdminAndVolunteer = () =>
isAuthorizedByRole(new Set(["ADMIN", "VOLUNTEER"]));
const authorizedByVolunteer = () => {
return (
isAuthorizedByRole(new Set(["VOLUNTEER"])) && isAuthorizedByUserId("userid")
Copy link
Member

Choose a reason for hiding this comment

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

since the isAuthorizedByUserId doesn't work in this case, pls remove it

Copy link
Member

@LenaNguyen LenaNguyen left a comment

Choose a reason for hiding this comment

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

Thanks for handling the changes!

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

Successfully merging this pull request may close these issues.

Create SignupService and corresponding GraphQL resolvers
4 participants