Final Project
GIFTR

Due before 11:59 pm on Thursday April 20, 2023.

This is the final deadline. There will be no extensions.
Counts for 30% of your MAD9124 final grade.

# Joint Project

The final project will be a two part joint assignment between MAD9124 and MAD9022. You will build a complete full-stack solution. The web service API portion will be graded for MAD9124, and the front-end application functionality, design, and usability will be graded for MAD9022.

# The Brief

Using Node.js, Express, Mongoose and MongoDB, you will build the RESTful API web service for a prototype of a fictitious application to track gift ideas for your friends. This initial proof of concept (PoC) will have limited capabilities but should demonstrate the potential of a full-scale application.

Each registered user can create a list of people for whom they are collecting gift ideas. The user can then add one or more gift ideas for each person on their list.

Your PoC will allow authenticated users to perform basic CRUD operations on two primary resources: people and gifts. The Person model represent the people for whom you are collecting gift ideas and will have an array of embedded Gift models. It will also have a ownerId relationship to the owning User model.

# Core Requirements

  • Implement basic user user management functions

    • authentication with Google OAuth and JWT
    • logout current user
  • Protected API routes require a valid JWT in the Authorization header.

  • Middleware functions should be employed to avoid repetitive route handler code.

  • Single resource requests should return any related resources as fully populated embedded documents.

  • Resource list requests should return an array of the primary resource objects only, without populating any related objects.

  • All requests containing user/client supplied data should be sanitized to protect against XSS and Query Injection attacks.

  • All schema validation errors should be caught and returned to the client with the correct status code and error message.

# Response Payload

  • All responses will be in the form of a JSON formatted object.
  • This payload object must include one of (but not both at the same time) a data property or an error property.
  • For "list" routes, the data property must be populated an array of zero or more of the requested resource objects.
  • For "retrieve" routes, the data property must be populated with a single resource object.
  • If the requested single resource, or sub-resource (embedded document) does not exist, a 404 error response should be sent.

# Example Data Response

GET /api/people

{
  "data": [
    {
      "_id": "641f45cc4de5a0f56bbc702e",
      "name": "Caitlin",
      "dob": "2023-03-25T19:04:43.966Z"
    }
  ]
}

# Example Errors Response

GET /api/people/[bad_id]

// Status 404
{
  "error": "Person with id [bad_id] not found"
}

# Example Unauthenticated Response

GET /api/people/ headers: { Authorization: 'Invalid or missing JWT' }

// Status 401
{
  "error": "JWT error: invalid token"
}

# Auth Routes

The user management actions will be exposed separately from the main API routes and will use the /auth route prefix.

Action Method Resource Path
Authenticate User GET /auth/google?redirect_url
Accept google response GET /auth/google/callback
Logout User GET /auth/logout

Successful authenticresation response from google at auth/google/callback will redirect to the redirect_url provided to auth/google, and will include the jwt token in the response query params. Ex http://localhost:3000/login-succes?token=ey.asdfasdf...

# API Routes

The primary application capabilities will be grouped under the /api resource route prefix. All routes will be limited to authorized users. The client application must send a valid JWT in the Authorization header property for all /api routes.

# Person Routes

Action Method Resource Path Notes
List all people GET /api/people Gift ideas not populated
Get details for a person GET /api/people/:id Gift ideas fully populated
Create a person POST /api/people
Replace a person PUT /api/people/:id
Update a person PATCH /api/people/:id
Remove a person DELETE /api/people/:id

Users should only see and be able to act on their own people.

All gift ideas for a given person should be returned as an array of embedded documents with the requested Person object.

# Gift Routes

Action Method Resource Path
List all gifts GET /api/people/:id/gifts
Get details for a gift GET /api/people/:id/gifts/:giftId
Create a gift POST /api/people/:id/gifts
Update a gift PATCH /api/people/:id/gifts/:giftId
Remove a gift DELETE /api/people/:id/gifts/:giftId

Users should only see and be able to act on gifts associated to their people.

# Resource Schema

There are three required model classes. Their schema requirements are listed below.

Remember

Mongoose will automatically create the _id property for all objects.

# Person

Property Type Required Max (length/value) Default
name String true
dob Date true
ownerId ObjectId, ref: 'User' true Current user
gifts [ Gift ]
createdAt Date Date.now()
updatedAt Date Date.now()

The createdAt and updatedAt properties should be set automatically by the database (opens new window). Any client supplied data for these two properties should be discarded.

The gifts property takes an array of zero or more Gift sub-documents (opens new window).
The ownerId property takes a single User ID.

# Gift

Property Type Required
txt String true
store String true
url String true
createdAt Date handled by mongoose
updatedAt Date handled by mongoose

# User

Property Type Required Default Unique Notes
name String true comes from google
googleId String true true comes from google
createdAt Date true handled by mongoose
updatedAt Date true handled by mongoose

# Logistics

  • Create a new private repository on Github.
  • Clone the repo to your laptop.
  • Initialize the repository yarn init (make sure to fill it out with correct values)
  • Install dependencies with yarn.
  • Build the project on your laptop.
  • Test each route with Postman, making sure to test both valid and invalid data.
  • Make git commits as you complete each requirement.
  • When everything is complete, push the final commit back up to GitHub
  • Submit both two URLs on Brightspace: the GitHub repo URL and the URL to your deployed Render API.

Remember

Pay attention to clean code practices.

Last Updated: 4/15/2023, 7:20:27 PM