tritonse / pap-inventory-processing Goto Github PK
View Code? Open in Web Editor NEWWeb app built for nonprofit organization Patriots and Paws to process & analyze veteran service requests
License: MIT License
Web app built for nonprofit organization Patriots and Paws to process & analyze veteran service requests
License: MIT License
Add the ability for staff and admin users to reset their own password from the login page.
Add the ability for an admin to delete any other user from the accounts page on the staff portal.
Create a new API route, DELETE /api/user/{uid}
, to delete a user by their UID (firebase ID, which is also a field in our MongoDB database of users). This route should require the requesting user to be admin (use the requireAdmin
middleware). This route should call firebaseAuth.deleteUser(uid)
to delete the user with the provided UID. It should then delete the user with the given UID from our MongoDB database. If a user with the provided UID is not found, it should throw a 404 not found error.
Implement the following user flow to delete a user:
Proof-of-Concept for reading from and writing to PDF files, for eventual use in exporting a VSR form to a PDF. We will have a template PDF file with blank fields for the data specific to each form (e.g. date-of-birth, military status, etc.) that our backend code will fill in. The required capabilities for this task are to read an existing PDF file (use any PDF with text fields), write to it by filling in text fields, and save the result. Then, open the result file and verify it is valid and has been filled in correctly. I'd recommend the PDF-Lib NPM package.
Resources:
Proof-of-Concept for writing data to an Excel (.xlsx
) file, for use in exporting VSR data to Excel from our backend code. Use the ExcelJS NPM package. Play around with it and ensure that you can write data to a sheet, save it, and view it in Excel. Then, create a function to write a given 2D array of data to an Excel sheet, given the file name and data.
Resources:
Implement searching, sorting, and filtering on the VSR table view.
The user should be able to type a search term into the search bar on the VSR table page, and then the VSR list should update to show only VSRs that match the search term.
Add a search
query parameter to the GET /api/vsr
API route (the getAllVSRS
method) with a string to search for. If this search term is provided and is not the empty string, then this route should only return VSRs where any of the fields (except _id
, which is a random string) match the search term. For example, if the user makes a request to GET /api/vsr?search=Ben
, then you should filter the VSRs to those with a match for "Ben". See the MongoDB documentation and this StackOverflow answer for examples of how to search.
Add a listener to the search text input field to detect when the user types a search term. You should use the MaterialUI debounce
function (see this StackOverflow answer) with a time of 500 ms to only fire changes at most every 500 ms (so that we don't detect changes to every character as the user types). When an input change is detected, send a new request to the backend to get the VSRs, using the search term that the user entered.
By default, the VSRs in the table should be sorted by the following criteria:
You can look at the GET /api/furnitureItems
API route code for an example of sorting model fields by multiple criteria.
Change the GET /api/vsr
API route's query to implement the given sorting. It should do this no matter what (i.e. regardless of any parameters the frontend provides).
No changes necessary, since all the sorting will be done on the backend.
Add the ability for users to filter by the following fields:
For each field that can be filtered by, have the GET /api/vsr
API route take a query parameter for that field (e.g. GET /api/vsr?status=Received
). If the query parameter is provided and is not set to the empty string, then the list of returned VSRs should be filtered to those matching the given query parameter(s) (e.g. in the previous example, we would filter to only VSRs with a status of "Received").
The status filter should be implemented by enabling the user to select a status from the status dropdown above the VSRs table; when they select a status, the frontend should use that status as the status
query parameter sent to the backend, in order to filter by that status.
The income level and zip code filters should be implemented as on the Figma designs. There is a popup that is opened/closed when the user clicks the "Filter" button. On that popup, the user can select an income level and/or zip code(s) to filter by. For these fields, only apply the filter (i.e. send the filter request to the backend) when the user clicks the "Apply filter" button.
Proof-of-Concept of using Firebase APIs for authentication. This is the first stage of the authentication feature, and involves ensuring that our Firebase credentials are valid and we know how to use the Firebase APIs.
.env
file) and receive an auth token (JWT)Resources:
Add the ability for staff to update a VSR's status. The possible statuses are:
The status flow works like this:
Create an API route to edit the status of a VSR. I'd recommend something like PATCH /api/vsr/{id}/status
, where the PATCH
method means to partially update an existing resource (VSR, in this case). The request body can contain the requested new status, and backend must update the corresponding VSR in the database to that status, then return a response with the new status (or the entire contents of that VSR, if you feel that would be necessary).
On the VSR individual page, we need some UI for the staff to edit a VSR's status. Specifically:
Create the VSR table view page for staff to see a list of VSRs. Focus on the frontend at first, because the backend route for this task depends on the backend routes and DB models for other tasks being completed.
/staff/vsr
URL/api/vsr/
that will return a list of all submitted VSRs. This route should require the user to be authenticated and have the staff
or admin
role. The frontend will then use this data to populate the VSRs table.Implement the second page of the VSR form. The Figma design can be found here. The first page has already been developed, so you'll essentially be expanding on the form by adding a second page. The task writeup for the VSR form first page describes what work is involved at each layer of the tech stack, but here's a quick summary for this page specifically:
VSR
data model to include all fields on the 2nd page of the formuseState
for the current page, and showing a different component for the correct page UI based on the current page value.Proof-of-Concept for sending email notifications from our backend. Use the nodemailer NPM package to send an email from our backend, from [email protected]. Write an async function that takes a destination email address, subject, and body (all strings) and resolves on success, or rejects on error. Test it by sending an email to your own email address.
Resources:
Add the ability for staff/admin users to export all VSR data to a spreadsheet.
GET /api/vsr/bulk_export
that exports all VSRs. The route should return an Excel (.xlsx
) file with the VSRs in itAdd the ability for admins to delete VSRs. Note that only users with the admin role should be able to do this, not just any staff.
/api/vsr/{id}
, to delete a single VSR by its ID. This route should check that the user is an admin (by using the Firebase JWT token to look up the user in our users database) before doing the deletion. The frontend can call this route once for each VSR that the user wants to delete.Implement the profile home page (need to figure out latest version of the design on Figma)
GET /api/user
. This route should be admin only (see the backend middleware for requiring a certain role)GET /api/user/whoami
and the data about all users using the new route you created, and displays this data on the page/staff/profile
Implement the third page (furniture items) of the VSR form. The Figma design is here. Please read the descriptions of the following tasks for information about the overall system and how to implement a new page of the VSR:
This task is essentially to add the third page of the VSR, which will entail the same actions described in the write-up for #19. Additionally, fetching the list of available furniture items from the backend and submitting the requested items will be done based on the description in the writeup for #15.
Implement the mobile version of the staff login page, Figma is here. This should only require a couple very minor changes (I think):
Add the ability for staff to edit an existing VSR. The Figma design can be found here.
Create a new API route to edit a VSR. I'd recommend PUT /api/vsr/{id}
, since the PUT
HTTP method means to completely update an existing resource (a VSR in this case). This route will be very similar to the route for creating a new VSR, except that it will overwrite the fields in an existing VSR in the database instead of creating a new VSR in the database.
Implement the UI for the edit VSR page and the functionality to switch between the view and edit pages as described. When the user saves their changes, the frontend should call the API route to edit a VSR, sending the new inputs to the VSR form fields.
Implement the new Navbar for admin, staff, and veterans.
Figma link
For admins, the Navbar should show the US flag on the left (which is already implemented) and a profile picture on the right. When the user clicks on the profile picture, it should display a dropdown of links to the various pages (the Figma has the list). For now, these links can be dead or broken since not all pages are implemented yet.
Figma link
For staff, the Navbar should be very similar to the admin Navbar, but should only have links to the dashboard, profile page, and logout, since staff are not authorized to edit the furniture items or email template. You can check if a user is staff or admin using the papUser.role
property on the result of useContext(UserContext)
(there are many examples in the code).
Figma link
For veterans, the Navbar should show a "Contact Us" button on the right. When the user clicks it, it should open a pop-up (see the Figma). When the user clicks "Email now", it should be a link (NextJS Link
component) to email them (href="mailto:[email protected]"
)
End-to-end feature: Staff can sign into the web application using an email and password (no need for sign in with Google account for now), and our backend can retrieve their corresponding user account and role in our MongoDB database.
/login
(see Figma design)/api/whoami
route that will return details about the current user (their role, username, email, etc.).users
model in our database to represent the users of our application. For now, the only fields we need are:role
, a string that should be either be staff
or admin
.uid
, a string that should be the user's unique ID in Firebase. This allows us to associate a Firebase token/user with a user in our DB..env
file)/api/whoami
that should ensure the user is authenticated and should return information about their corresponding record in our DB. Use the Firebase API to validate the Firebase JWT token in the request header, and use that token to retrieve the user UID from firebase. Then, find the user in our DB with that UID, and send that user's UID, role, and ID in the response. If that UID is not found in our DB, return an error message saying the user does not exist.See #4.
Add the ability for staff/admin users to edit the list of furniture items available for veterans to select on page 3 of the VSR.
POST /api/furnitureItems
to create a new furniture itemPUT /api/furnitureItems/{id}
to edit a new furniture item (replacing all fields with the values specified in the request body)DELETE /api/furnitureItems/{id}
to delete a furniture item/staff/furnitureItems
Implement the first page (Personal Information) of the VSR design on Figma. We'll eventually add the other 2 pages on, with "Next" and "Back" buttons to navigate between them. But for now, just put the "Submit" button on the first page, and have that button submit the form to our backend, so we can test the first page end-to-end.
/api/vsr
to submit a VSR. This route should NOT require the user to be authenticated (authentication is only for staff). On this route, verify that all required fields are present in the request body and meet validation rules (see the Frontend section for examples of validation). I'd recommend using Express Validator to validate the request. This is the library used in the TSE Onboarding repo, so feel free to reference that repo as an example of validating request data. If all validation checks pass, create an entry in the VSR database using the data in the request body./vsr
URL (this might change later)/api/vsr
.Add the ability for an admin to create a new user from the accounts page.
Create an API route, POST /api/user
, to create a new user. This route should require the requesting user to be an admin (use the requireAdmin
middleware). This route should take name
, email
, and password
fields in the request body. It should then do the following:
/api/user/whoami
.Implement the following user flow:
When a VSR is submitted, we want a notification email to be sent to staff telling them a new VSR was submitted. This email should include the name and email address of the request. The purpose of this feature is so that staff can later search their email to find VSR submissions by name or email.
EMAIL_NOTIFICATIONS_RECIPIENT
. This way, we can have these emails be sent to ourselves or our TSE pap dev email address for now, and have them be send to the actual Patriots & Paws email address in production. Your code should use this environment variable as the address to send emails toWe need a way to store the available furniture items, and the items that a specific veteran has requested. On the third page of the VSR form (Figma link), it should show all the available furniture items and allow the veteran to select which items they want, as well as quantities.
For this task, focus on the database and backend first, since there is a lot of work involved just on the backend. We will also need separate tasks to update the create & retrieve VSR API routes, and the frontend for the VSR form and VSR individual view.
Create a DB model for a furniture item. It should have the following fields (all of which are required):
category
: String. Determines which section on the VSR form the item should show up on. E.g. "bedroom", "bathroom".name
: String. The name for the furniture item. E.g. "Matching Box Spring(s)", "Blankets"isGasElectric
: Boolean. Represents whether this item has gas and electric options available. Currently, only the stove and dryer should have this property set to true; all other items should have it set to false.allowMultiple
: Boolean. Represents whether we should allow veterans to ask for more than 1 of this item. For the items with the plus and minus buttons to select a quantity on the Figma, this property should be true, and for the items where you just select/deselect it but don't choose a quantity, it should be false.categoryIndex
: Number. Index of the item within its category. Should be an integer. Will be used to put items in a specific order within each category. For example, within "Bedroom", the "Matching Box Spring(s)" furniture item's category index is 1, "Matching Bed Frame(s)" should be 2, etc.We need a way of loading the current furniture items into the database. Creating the furniture item DB model will define what an item should look list, but we need to also define which items exist. Rather than manually entering them one at a time through MongoSH or something, we should create a script that will load the furniture items into the MongoDB database. By "script" I mean a JS/TS file that will run code to create all the items that exist. You can create a JSON file for the data itself, and the script will just read the items from that JSON file and insert them into the database. Creating a script for this will allow each developer to insert the data into their own local database, and will allow us to insert the data into the production database, in an automated way.
Now that we've defined what furniture items are available, we need a way to store which items each veteran has requested. We can do this by adding a field to the VSR model called requestedItems
. This field should be required, and is an array of objects, where each object has the following fields:
itemId
: Required. The ID (_id
field) of the item that was requested. I think there's an ObjectID type or something in Mongoose.quantity
: Number, required. The quantity of the item that the veteran requested. Should be 1 for items where you can't choose a quantity (allowMultiple
field).isGas
: Optional, boolean. Use this field only if the item has isGasElectric
set to true. Set this field to true if the veteran chose gas, and false if they chose electric.Additionally, we'll need an otherItems
field to the VSR model, an optional field for anything the veteran enters into the "Identify other necessary items" box.
Implement a 4th page of the VSR form for veterans to review their VSR before submitting. The purpose of this feature is to help veterans catch mistakes on their form so they are more likely to submit accurate information and not need to re-submit or email PAP about errors on their form.
The user flow should be as follows:
Note that this task is entirely frontend, it doesn't require any backend changes.
For the review page, I would recommend re-using the components on the VSR individual page that display details for each field.
Implement the VSR individual view page for staff. This should show one VSR in detail. Focus on the frontend first, because we need the VSR DB model to be completed in order to build the backend route for this task.
/staff/vsr/[id]
URL (see the NextJS dynamic routes documentation)/api/vsr/[id]
to get data on a specific VSR. The id
in the URL path should be the ID of the VSR (MongoDB assigns each DB entry a unique ID). This route should verify that the user is authenticated (using a Firebase token in the header) and has the staff
or admin
role. If these checks pass, retrieve the corresponding VSR and return its data in the responseA declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.