Skip to content

The Missing Piece was created by an international team of both FrontEnd and BackEnd developers for the Women Who Code (WWC) Hackathon for Social Good 2023.

Notifications You must be signed in to change notification settings

WWC-Hackathon-2023/missing_piece_api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation


Logo

The Missing Piece

Together we can create a better world. One individual piece at a time.


An item exchange app to get local retirees swapping puzzles to keep their minds sharp & meet others in their local neighborhood. So if you have a collection of puzzles and are eager for new challenges, you're in the right spot: Join our community of fellow puzzle enthusiasts and dive into a world of delightful exchanges. Happy Puzzle-ing!



Table of Contents
  1. About The Project
  2. Getting Started
  3. Endpoints
  4. New Technologies Used
  5. Contributors
  6. Future Iterations

About The Project

đź’ś Production Website
đź’ś Backend Service
đź’ś Front End Repository
đź’ś Submission Presentation

Women Who Code Hackathon for Social Good 2023

The Missing Piece was created by an international team of both FrontEnd and BackEnd developers for the Women Who Code (WWC) Hackathon for Social Good 2023.

The Women Who Code Hackathon for Social Good requires that every project aims to support a target group: The Missing Piece Team chose to address is the emotional and mental wellbeing of retirees and seniors by creating an app to facilitate the sharing of items. For our MVP (minimum viable product) we chose to focus on one item type: puzzles.

Why puzzles? Well, puzzles tend to accumulate over a lifetime and end up in boxes in the attic, never to be seen again. They're purchased, completed a few times, and then put away. A puzzle is a type of item that can be exchanged and returned over and over... plus it's fun to work on new ones without having to buy yet another puzzle!

  • Challenge Statement

    According to the National Institute of Health, prior to the COVID outbreak, investigators found out that 24% of American individuals 65 and over were socially isolated. That's approximately 7.7 million people. The U.S. Health and Retirement Study reports that 43% of Americans aged 60 or older also reported feeling lonely, which can lead to debilitating issues like depression and anxiety for our loved ones... now think about this on a global scale! ref

    In an already isolated world, how do we use technology to connect our seniors through a common interest that is simple to use and can lead to actual genuine connections? By joining the Missing Piece!

  • Solution Statement The Missing Piece aims to connect retirees through a common interest with an easy, low-pressure opportunity to share puzzles with other locals (without the pressure of attending an event). Not only will this app encourage them get out of the house in order to swap puzzles with others but could hopefully lead to building genuine friendships with people in their local neighborhood. Who knows, maybe they'll start puzzle-parties and work together too!

    On top of this, studies have shown that solving puzzles keep our minds sharp! It reduces the rate of cognitive decline and increases short-term memory, concentration, and visual-spatial reasoning. Plus, through the simple act of solving a little puzzle, improvements in mood and lower stress-levels have been found.

    With the Missing Piece app, users can search for puzzles in their local area. Then they can sign up or login to see their dashboard where they'll be able to upload their own collection of puzzles, see who's requested to borrow a puzzle, and track their own requests to borrow. Once an owner of a puzzle accepts the request, both user's email and phone number are provided so they can coordinate when and where to exchange the puzzle. Once a puzzle has been returned, it is then ready to be borrowed again!

(back to top)

Built With

Ruby Ruby on Rails Rspec Badge Postgresql VScode Heroku GitHubActions Postman Cloudinary Notion Miro Figma

(back to top)

Getting Started

If you'd like to demo this API on your local machine:

  1. Ensure you have the prerequisites
  2. Clone this repo: [email protected]:WWC-Hackathon-2023/missing_piece_api.git
  3. Navigate to the root folder: cd missing_piece_api
  4. Run: bundle install
  5. Run: rails db:{create,migrate}
  6. Inspect the /db/schema.rb and compare to the 'Schema' section below to ensure migration has been done successfully
  7. Run: rails s
  8. Visit http://localhost:3000/

Prerequisites

  • Ruby Version 3.1.1
  • Rails Version 7.0.8.x
  • Bundler Version 2.4.13

Schema

Missing Piece Schema

Testing

To test the entire spec suite, run bundle exec rspec. All tests should be passing.

Happy path and sad path testing were considered and tested. When a request cannot be completed, an error object is returned.

Error Objects
    
{
  "errors": [
    {
      "status": "404"
      "title": "Invalid Request",
      "detail": [
        "Couldn't find User with 'id'="
         ]
     }
   ]
}
    
  
    
{ 
  "error": "Unable to update loan status" 
}
    
  

(back to top)

Endpoints

PUT "/api/v1/puzzles" Request Body:
    
{
  "zip_code": 12345
}
    
  

Response:
Status: 200

    
{
    "data": [
        {
            "id": "1",
            "type": "puzzle",
            "attributes": {
                "user_id": 1,
                "status": "Available",
                "title": "Flower Cycle",
                "description": "A flower collage by Rosalind Wise",
                "total_pieces": 1000,
                "notes": "Very Difficult! Only for the brave of heart!",
                "puzzle_image_url": "https://cloudinary.com/image/Flower_Cycle.jpg"
            }
        },
        {
            "id": "2",
            "type": "puzzle",
            "attributes": {
                "user_id": 1,
                "status": "Available",
                "title": "Mountain Chalet",
                "description": "Cabin near lake and mountains",
                "total_pieces": 1000,
                "notes": "Relaxing, feels like you're in Colorado!",
                "puzzle_image_url": "https://cloudinary.com/image/Mountain_Chalet.jpg"
            }
        }, {...}
    ]
}
    
  
POST "/api/v1/users" Request Body:
    
{
  "full_name": "Diana Puzzler",
  "email": "[email protected]",
  "password": "PuzzleQueen1",
  "password_confirmation": "PuzzleQueen1",
  "zip_code": 12345, 
  "phone_number": 5051230000
}
    
  

Response:
Status: 201

    
{
    "data": {
        "id": "1",
        "type": "user",
        "attributes": {
            "full_name": "Diana Puzzler",
            "email": "[email protected]",
            "zip_code": 12345,
            "phone_number": "(505) 123-0000"
        }
    }
}
    
  
POST "/api/v1/login" Request Body:
    
{
  "email": "[email protected]",
  "password": "PuzzleQueen1"
}
    
  

Response:
Status: 201

    
{
    "data": {
        "id": "1",
        "type": "user",
        "attributes": {
            "full_name": "Diana Puzzler",
            "email": "[email protected]",
            "zip_code": 12345,
            "phone_number": "(505) 123-0000"
        }
    }
}
    
  
DELETE "/api/v1/users/:id/logout"

Response:
Status: 204

GET "/api/v1/users/:id"

Response:
Status: 200

    
{
    "data": {
        "id": "1",
        "type": "user",
        "attributes": {
            "full_name": "Diana Puzzler",
            "email": "[email protected]",
            "zip_code": 12345,
            "phone_number": "(505) 123-0000"
        }
    }
}
    
  
GET "/api/v1/users/:id/dashboard"

Response:
Status: 200

    
{
    "data": {
        "id": "1",
        "type": "dashboard",
        "attributes": {
            "user_info": {
                "full_name": "Diana Puzzler",
                "email": "[email protected]",
                "zip_code": 12345,
                "phone_number": "(505) 123-0000"
            },
            "owner_loans": [
                {
                    "loan_id": 1,
                    "owner_id": 1,
                    "borrower_id": 2,
                    "loan_status": "Pending",
                    "loan_created_at": "2023-10-21T02:52:18.777Z",
                    "puzzle_id": 1,
                    "puzzle_image_url": "https://cloudinary.com/imageFlower_Cycle.jpg",
                    "puzzle_title": "Flower Cycle",
                    "puzzle_status": "Pending"
                }, {...}
            ],
            "borrower_loans": [
                {
                    "loan_id": 5,
                    "owner_id": 2,
                    "borrower_id": 1,
                    "loan_status": "Accepted",
                    "loan_created_at": "2023-10-21T17:01:40.848Z",
                    "puzzle_id": 55,
                    "puzzle_image_url": "https://cloudinary.com/image/Maroon_Lake.jpg",
                    "puzzle_title": "Maroon Lake",
                    "puzzle_status": "Not Available"
                }, {...}
            ]
        }
    }
}
    
  
POST "/api/v1/users/:id/puzzles" Request Body:
    
{
    "title": "Wild Beauty",
    "description": "Horses running in the snow by Chris Cummings.",
    "total_pieces": 1000,
    "notes": "Lots of white snow...beware!",
    "puzzle_image_url": "https://cloudinary.com/image/Wild_Beauty.jpg"
}
    
  

Response:
Status: 201

    
{
    "data": {
        "id": "3",
        "type": "puzzle",
        "attributes": {
            "user_id": 1,
            "status": "Available",
            "title": "Wild Beauty",
            "description": "Horses running in the snow by Chris Cummings.",
            "total_pieces": 1000,
            "notes": Lots of white snow...beware!",
            "puzzle_image_url": "https://cloudinary.com/image/Wild_Beauty.jpg"
        }
    }
}
    
  
GET "/api/v1/users/:id/puzzles"

Response:
Status: 200

    
{
    "data": [
        {
            "id": "4",
            "type": "puzzle",
            "attributes": {
                "user_id": 1,
                "status": "Available",
                "title": "Humming Bird & Flowers",
                "description": "Hummingbirds investigating some pretty flowers.",
                "total_pieces": 1000,
                "notes": "Not as hard as you might think!",
                "puzzle_image_url": "https://res.cloudinary.com/image/info/Hummingbirds_Flowers.jpg"
            }
        },
        {
            "id": "5",
            "type": "puzzle",
            "attributes": {
                "user_id": 1,
                "status": "Available",
                "title": "Durango Silverton",
                "description": "Train coming around the bend!",
                "total_pieces": 1000,
                "notes": "Feels like a step back in time!",
                "puzzle_image_url": "https://res.cloudinary.com/image/info/Durango_Silverton.jpg"
            }
        }, {...}
    ]
}
    
  
GET "/api/v1/users/:id/puzzles/:id"

Response:
Status: 200

    
{
    "data": {
        "id": "1",
        "type": "puzzle",
        "attributes": {
            "user_id": 1,
            "status": "Available",
            "title": "Flower Cycle",
            "description": "A flower collage by Rosalind Wise",
            "total_pieces": 1000,
            "notes": "Very Difficult! Only for the brave of heart!",
            "puzzle_image_url": "https://cloudinary.com/image/Flower_Cycle.jpg"
        }
    }
}
    
  
PATCH "/api/v1/users/:id/puzzles/:id" Request Body:
    
{
  "status": 2, 
  "title": "Rosalind Wise Flower Cycle", 
  "description": "A colorful flower collage", 
  "total_pieces": 2000,
  "notes":  "Challenging but not too much. The brave of heart can do it!"
}
    
  

Response:
Status: 200

    
{
    "data": {
        "id": "1",
        "type": "puzzle",
        "attributes": {
            "user_id": 1,
            "status": "Not Available",
            "title": "Rosalind Wise Flower Cycle",
            "description": "A colorful flower collage",
            "total_pieces": 2000,
            "notes": "Challenging but not too much. The brave of heart can do it!",
            "puzzle_image_url": "https://res.cloudinary.com/image/info/Flower_Cycle.jpg"
        }
    }
}
    
  
POST "/api/v1/users/:id/loans" Request Body:
    
{
    "borrower_id": 2, 
    "puzzle_id": 2
}
    
  

Response:
Status: 201

    
{
    "data": {
        "id": "7",
        "type": "loan",
        "attributes": {
            "owner_id": 1,
            "borrower_id": 2,
            "puzzle_id": 2,
            "status": "Pending"
        }
    }
}
    
  
PATCH "/api/v1/users/:id/loans/:id"

owner clicks accept OR borrower clicks withdraw OR owner clicks deny OR when loan is complete Request Body:

    
{
  "action_type": "accept"
}
    
  

Response:
Status: 200

    
{
    "data": {
        "id": "7",
        "type": "loan",
        "attributes": {
            "owner_id": 1,
            "borrower_id": 2,
            "puzzle_id": 2,
            "status": "Accepted"
        }
    }
}
    
  

All endpoints can also be found in the JSON Contract

Run in Postman

(back to top)

New Technologies Used

Cloudinary

Cloudinary was used to allow users to seamlessly upload images for their puzzles.

Attempted New Technologies

AWS S3

Amazon Web Services s3 Bucket was attempted for image upload/cloud storage.

1Password

Passage by 1Password was attempted to authenticate users and ensure login was easy, safe, and quick.

(back to top)

Future Iterations

Refactor/Changes
Conduct a solid refactor of existing code
- With the limited time of the Hackathon, reviewing the code slower would be first
Allow a loan to have more than one puzzle
- This was the original idea for the schema and would involve a join table
Refactor our connectiong with Cloudinary for multiple image upload & profile images
- This would possibly require an new table to store puzzle image urls
Include other item types that could be borrowed
- Deciding which other item types might be most suited for this app
- And we'd create even more tables in the database
Incorporate internal communication tools
- Internal or external emails and/or text messages might be concidered
- If so we'd look to Twilio/Send Grid as a start
Allow users to create a 'Puzzle Party' and invite others
- Additional tables in the database would be required: parties and user_parties
- The user table might also become a self-referential table so users can store "friends"
Add functionality so users can share images or 'Puzzle Parties' on social media
- Examples would include Facebook and Instagram
Scale up for international participation
- Changes would need to be made to both FE form input and BE database validations to allow for multi-formatted and multi-length input of zip codes and phone numbers.
- As a website scales up run times become a consideration so we would also aim to implement background workers and caching

(back to top)

Contributors

Paola Andrea Ramirez Quintero Carmen Luna Natalia Torrejon Kemi Thomas Bisrat Melak Melony Erin Franchini
Andrea Ramirez Carmen Luna Natalia Torrejon Kemi Thomas Bisrat Melak Melony Erin Franchini
FrontEnd FrontEnd FrontEnd FullStack BackEnd BackEnd & Team Lead
GitHub GitHub GitHub GitHub GitHub GitHub
LinkedIn LinkedIn LinkedIn LinkedIn LinkedIn LinkedIn

(back to top)

About

The Missing Piece was created by an international team of both FrontEnd and BackEnd developers for the Women Who Code (WWC) Hackathon for Social Good 2023.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published