Skip to content

Quick-Command/qc-engine

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

QuickCommand Engine

About this Project

QuickCommand Engine is the backend web application that connects client side through 13 JSON API endpoints. Each endpoint allows for basic CRUD functionality for the intended user to display both open and closed incidents as well as show what contacts are associated with the incident once an incident has been declared, create a personnel for a given incident, search for both contacts and incidents and more. Receiving current weather and hour by hour forecasts where an incident is currently active ties this functionality into the Weather API Service built with Sinatra.

Table of Contents

Getting Started

To get the web application running, please follow these directions to set up your local machine's testing and development environments. Please follow the section for deployment to see how to deploy this application on Heroku.

Prerequisites

To run this application you will need Ruby 2.5.3 and Rails 5.2.5

Installation

1. Clone this repo using the following command:
  `$ git clone [email protected]:Quick-Command/qc-engine.git/`

2. Run bundle install:
  `$ bundle install`

3. Setup the database:
  `$ rails db:{create,migrate,seed}`

4. Add Environment Variables
 - First, add the Figaro gem to the development/test section of the Gemfile and `$ bundle install`: `gem "figaro"`
 - run the command `$ bundle exec figaro install`
 - Add the following environment variables to your `config/application.yml` for access to the WeatherService microservice.

 **IMPORTANT**
 It is imperative that the application.yml file is added to .gitignore so that the personal API keys are not exposed remotely.

Other Repos

  • To explore the full application capabilities, please visit the front end application which hooks into this engine and its endpoints:
  • For more information on the WeatherService microservice, please visit the following links

Service Oriented Architecture

QuickCommand Project Design Screen Shot 2021-05-27 at 9 05 26 AM

DB Schema

The following is a depiction of our Database Schema

db_schema

Endpoints

QuickCommand API Contract

HTTP verbs Paths Used for Output
GET /api/v1/incidents?active=true Get active incidents json
GET /api/v1/incidents?active=false Get resolved incidents json
GET /api/v1/incidents/:incident_id Get an incident's details json
PATCH /api/v1/incidents/:incident_id Update an incident's details json
GET /api/v1/incidents/:incident_id/contacts Get an incident's contacts and role in incident json
GET /api/v1/incidents/1/contact_search?role=ROLE Get a specific contact based on incident and role json
POST /api/v1/incidents Create a new incident json
POST /api/v1/contacts Create a new contact json
POST /api/v1/incidents/:incident_id/contacts/:contact_id Assign a Contact to an role in an Incident json
PATCH /api/v1/incidents/:incident_id/contacts/:contact_id Reassign a contact to a role in an Incident json
GET /api/v1/contacts/:contact_id Get a contact's details json
GET /api/v1/contacts/search?name=NAME Return contacts that match name query json
GET /api/v1/contacts?role=ROLE Return contacts that match role query json

Types of Incidents (an incident can be one type)

  • Fire
  • Accident
  • Earthquake
  • Hazmat Spill
  • Power Outage ​

Types of Roles (a contact can be many roles)

  1. Incident Commander
  2. Safety Officer
  3. Liaison Officer
  4. Operations Chief
  5. Logistics Chief ​

JSON Responses

​

Active Incidents

GET /api/v1/incidents?active=true

{
  "data": [
      {
          "id": "6",
          "type": "incident",
          "attributes": {
              "name": "Jim Creek Fire",
              "active": true,
              "incident_type": "Fire",
              "description": "2 alarm fire caused campfire embers",
              "start_date": "2020-10-10T00:00:00.000Z",
              "close_date": null,
              "location": "Jim Creek Trail",
              "city": "Denver",
              "state": "CO"
          }
      },
      {
          "id": "7",
          "type": "incident",
          "attributes": {
              "name": "Avery Substation - Summer black out",
              "active": true,
              "incident_type": "Power Outage",
              "description": "Outage for 12893 homes for 19 hours",
              "start_date": "2020-11-10T00:00:00.000Z",
              "close_date": null,
              "location": "Avery Substation",
              "city": "Denver ",
              "state": "CO"
          }
      }
  ]
}

Resolved Incidents

GET /api/v1/incidents?active=false

  {
    "data": [
        {
            "id": "1",
            "type": "incident",
            "attributes": {
                "name": "October 2011 2.0 earthquake",
                "active": false,
                "incident_type": "Earthquake",
                "description": "2.0 earthquake, facade damage to some buildings, 10 trees fell",
                "start_date": "2020-01-10T00:00:00.000Z",
                "close_date": "2020-11-05T00:00:00.000Z",
                "location": "City Proper",
                "city": "Denver",
                "state": "CO"
            }
        },
        {
            "id": "5",
            "type": "incident",
            "attributes": {
                "name": "5 car accident",
                "active": false,
                "incident_type": "Accident",
                "description": "Details in police report #PR0977237619",
                "start_date": "2020-09-10T00:00:00.000Z",
                "close_date": "2020-10-10T00:00:00.000Z",
                "location": "W 6TH AVE / N PERRY ST",
                "city": "Denver ",
                "state": "CO"
            }
        }
    ]
}

​

Create an Incident

POST /api/v1/incidents

  • Set header Content-Type to application/json
  • Body for request
    • Active attribute can be left out and it will default to true, or specify "active": false to input a resolved incident, but you must enter a close date for an inactive incident
  {
  "name": "Jim Creeks Fire",
  "incident_type": "Fire",
  "description": "5th alarm fire",
  "location": "Jims Creek",
  "city": "Denver",
  "state": "CO",
  "start_date": "2020-05-01",
  "close_date": ""
   }
  • Required attributes: name, start date, incident type, city, state, and close date if active is false.
  • Return data
  {
    "data": {
        "id": "34",
        "type": "incident",
        "attributes": {
            "name": "Jim Creeks Fire",
            "active": true,
            "incident_type": "Fire",
            "description": "5th alarm fire",
            "location": "Jims Creek",
            "start_date": "2020-05-01T00:00:00.000Z",
            "close_date": null
        }
    }
  }

Update an Incident

PATCH '/api/v1/incidents/:incident_id'

  • Set header Content-Type to application/json
  • Body for request
  {
  "name": "Denver Zoo Fire"
   }
  • Return Data
  {
    "data": {
        "id": "1",
        "type": "incident",
        "attributes": {
            "name": "Denver Zoo Fire",
            "active": false,
            "incident_type": "Earthquake",
            "description": "2.0 earthquake, facade damage to some buildings, 10 trees fell",
            "start_date": "2020-01-10T00:00:00.000Z",
            "close_date": "2020-11-05T00:00:00.000Z",
            "location": "City Proper",
            "city": "Denver",
            "state": "CO"
        }
    }
  }

Incident Details

GET /api/v1/incidents/:incident_id

  {
    "data": {
        "id": "1",
        "type": "incident",
        "attributes": {
            "name": "October 2011 2.0 earthquake",
            "active": false,
            "incident_type": "Earthquake",
            "description": "2.0 earthquake, facade damage to some buildings, 10 trees fell",
            "start_date": "2020-01-10T00:00:00.000Z",
            "close_date": "2020-11-05T00:00:00.000Z",
            "location": "City Proper",
            "city": "Denver",
            "state": "CO"
        }
    }
}

Contact Details

GET /api/v1/contacts/1

  {
    "data": {
        "id": "1",
        "type": "contact",
        "attributes": {
            "name": "Aaron Marks",
            "email": "[email protected]",
            "phone_number": " (221)830-7361",
            "job_title": "City Manager",
            "city": "Denver",
            "state": "CO"
        }
    }
}

Create a Contact

POST /api/v1/contacts

  • set header contact-type to application/json
  • body
      {
        "name": "Wells Fergi",
        "email": "[email protected]",
        "phone_number": "123-456-7890",
        "job_title": "Fire Commander",
        "city": "Denver",
        "state": "CO",
        "roles": ["Incident Commander", "Safety Officer"]
    }
    • return
      {
        "data": {
        "id": "5",
        "type": "contact",
        "attributes": {
            "name": "Wells Fergi",
            "email": "[email protected]",
            "phone_number": "123-456-7890",
            "job_title": "Fire Commander",
            "city": "Denver",
            "state": "CO",
            "roles": {
                "data": [
                    {
                        "id": "1",
                        "type": "role",
                        "attributes": {
                            "title": "Incident Commander"
                        }
                    },
                    {
                        "id": "2",
                        "type": "role",
                        "attributes": {
                            "title": "Safety Officer"
                        }
                    }
                ]
              }
            }
          }
        }

Assign a Contact to an Incident

POST /api/v1/incidents/:incident_id/contacts/:contact_id

  • Body
      {"title": "Safety Officer"}
  • Return
      {
        "data": {
          "id": "1",
          "type": "incident_contact",
          "attributes": {
              "name": "Aaron Marks",
              "title": "Safety Officer",
              "email": "[email protected]",
              "phone_number": " (221)830-7361",
              "city": "Denver",
              "state": "CO",
              "distance_miles": "20",
              "distance_minutes": "40"
          }
      }
    }

Incident Contact Details

GET /api/v1/incidents/:incident_id/contacts/:contact_id

  {
    "data": {
      "id": "1",
      "type": "incident_contact",
      "attributes": {
          "name": "Aaron Marks",
          "title": "Safety Officer",
          "email": "[email protected]",
          "phone_number": " (221)830-7361",
          "city": "Denver",
          "state": "CO",
          "distance_miles": "20",
          "distance_minutes": "40"
      }
  }
}

Incident Contacts

GET /api/v1/incidents/:incident_id/contacts

{
  "data": [
      {
          "id": "1",
          "type": "incident_contact",
          "attributes": {
              "name": "Aaron Marks",
              "title": "Inicdent Commander",
              "email": "[email protected]",
              "phone_number": " (221)830-7361",
              "city": "Denver",
              "state": "CO",
              "distance_miles": "16",
              "distance_minutes": "49"
          }
      },
      {
          "id": "2",
          "type": "incident_contact",
          "attributes": {
              "name": "Aly Snow",
              "title": "Safety Officer",
              "email": "[email protected]",
              "phone_number": " (485)062-4319",
              "city": "Denver",
              "state": "CO",
              "distance_miles": "68",
              "distance_minutes": "36"
          }
      },
      {
          "id": "3",
          "type": "incident_contact",
          "attributes": {
              "name": "Brian Blue",
              "title": "Liaison Officer",
              "email": "[email protected]",
              "phone_number": " (852)148-9979",
              "city": "Aurora",
              "state": "CO",
              "distance_miles": "83",
              "distance_minutes": "45"
          }
      },
      {
          "id": "4",
          "type": "incident_contact",
          "attributes": {
              "name": "Brie Button",
              "title": "Operations Cheif",
              "email": "[email protected]",
              "phone_number": " (672)832-4790",
              "city": "Littleton",
              "state": "CO",
              "distance_miles": "68",
              "distance_minutes": "77"
          }
      },
      {
          "id": "5",
          "type": "incident_contact",
          "attributes": {
              "name": "Carrie Washington",
              "title": "Logistics Chief",
              "email": "[email protected]",
              "phone_number": " (782)602-3793",
              "city": "Boulder",
              "state": "CO",
              "distance_miles": "26",
              "distance_minutes": "84"
          }
      }
  ]
}

Search Incident Contact by Role

GET /api/v1/incidents/1/contact_search?role=Commander

{
    "data": [
        {
            "id": "1",
            "type": "incident_contact",
            "attributes": {
                "name": "Aaron Marks",
                "title": "Inicdent Commander",
                "email": "[email protected]",
                "phone_number": " (221)830-7361",
                "city": "Denver",
                "state": "CO",
                "distance_miles": "28",
                "distance_minutes": "100"
            }
        },
        {
            "id": "1",
            "type": "incident_contact",
            "attributes": {
                "name": "Aaron Marks",
                "title": "Inicdent Commander",
                "email": "[email protected]",
                "phone_number": " (221)830-7361",
                "city": "Denver",
                "state": "CO",
                "distance_miles": "47",
                "distance_minutes": "98"
            }
        },
        {
            "id": "4",
            "type": "incident_contact",
            "attributes": {
                "name": "Brie Button",
                "title": "Operations Cheif",
                "email": "[email protected]",
                "phone_number": " (672)832-4790",
                "city": "Littleton",
                "state": "CO",
                "distance_miles": "93",
                "distance_minutes": "96"
            }
        },
        {
            "id": "4",
            "type": "incident_contact",
            "attributes": {
                "name": "Brie Button",
                "title": "Operations Cheif",
                "email": "[email protected]",
                "phone_number": " (672)832-4790",
                "city": "Littleton",
                "state": "CO",
                "distance_miles": "39",
                "distance_minutes": "59"
            }
        },
        {
            "id": "4",
            "type": "incident_contact",
            "attributes": {
                "name": "Brie Button",
                "title": "Operations Cheif",
                "email": "[email protected]",
                "phone_number": " (672)832-4790",
                "city": "Littleton",
                "state": "CO",
                "distance_miles": "26",
                "distance_minutes": "28"
            }
        },
        {
            "id": "6",
            "type": "incident_contact",
            "attributes": {
                "name": "Carl Jr",
                "title": null,
                "email": "[email protected]",
                "phone_number": " (366)338-9913",
                "city": "Denver",
                "state": "CO",
                "distance_miles": "11",
                "distance_minutes": "15"
            }
        },
        {
            "id": "6",
            "type": "incident_contact",
            "attributes": {
                "name": "Carl Jr",
                "title": null,
                "email": "[email protected]",
                "phone_number": " (366)338-9913",
                "city": "Denver",
                "state": "CO",
                "distance_miles": "6",
                "distance_minutes": "89"
            }
        },
        {
            "id": "8",
            "type": "incident_contact",
            "attributes": {
                "name": "Diane Furr",
                "title": null,
                "email": "[email protected]",
                "phone_number": " (227)860-8382",
                "city": "Aurora",
                "state": "CO",
                "distance_miles": "32",
                "distance_minutes": "49"
            }
        },
        {
            "id": "8",
            "type": "incident_contact",
            "attributes": {
                "name": "Diane Furr",
                "title": null,
                "email": "[email protected]",
                "phone_number": " (227)860-8382",
                "city": "Aurora",
                "state": "CO",
                "distance_miles": "1",
                "distance_minutes": "12"
            }
        },
        {
            "id": "9",
            "type": "incident_contact",
            "attributes": {
                "name": "Eugene Maroon",
                "title": null,
                "email": "[email protected]",
                "phone_number": " (721)386-6969",
                "city": "Littleton",
                "state": "CO",
                "distance_miles": "31",
                "distance_minutes": "74"
            }
        },
        {
            "id": "9",
            "type": "incident_contact",
            "attributes": {
                "name": "Eugene Maroon",
                "title": null,
                "email": "[email protected]",
                "phone_number": " (721)386-6969",
                "city": "Littleton",
                "state": "CO",
                "distance_miles": "40",
                "distance_minutes": "74"
            }
        },
        {
            "id": "11",
            "type": "incident_contact",
            "attributes": {
                "name": "Fran Moore",
                "title": null,
                "email": "[email protected]",
                "phone_number": " (437)750-2732",
                "city": "Denver",
                "state": "CO",
                "distance_miles": "47",
                "distance_minutes": "84"
            }
        },
        {
            "id": "11",
            "type": "incident_contact",
            "attributes": {
                "name": "Fran Moore",
                "title": null,
                "email": "[email protected]",
                "phone_number": " (437)750-2732",
                "city": "Denver",
                "state": "CO",
                "distance_miles": "36",
                "distance_minutes": "46"
            }
        },
        {
            "id": "26",
            "type": "incident_contact",
            "attributes": {
                "name": "Mike Moon",
                "title": null,
                "email": "[email protected]",
                "phone_number": " (651)563-1511",
                "city": "Denver",
                "state": "CO",
                "distance_miles": "25",
                "distance_minutes": "74"
            }
        },
        {
            "id": "27",
            "type": "incident_contact",
            "attributes": {
                "name": "Neil Buttstrong",
                "title": null,
                "email": "[email protected]",
                "phone_number": " (220)609-0224",
                "city": "Denver",
                "state": "CO",
                "distance_miles": "59",
                "distance_minutes": "38"
            }
        },
        {
            "id": "32",
            "type": "incident_contact",
            "attributes": {
                "name": "Patrick Clover",
                "title": null,
                "email": "[email protected]",
                "phone_number": " (149)775-6018",
                "city": "Boulder",
                "state": "CO",
                "distance_miles": "28",
                "distance_minutes": "73"
            }
        }
    ]
}

Reassign a Contact to a Role

PATCH /api/v1/incidents/:incident_id/contacts/:contact_id

  • Body
  {"title": "Safety Officer"}
  • Return
    {
      "data": {
        "id": "1",
        "type": "incident_contact",
        "attributes": {
            "name": "Aaron Marks",
            "title": "Safety Officer",
            "email": "[email protected]",
            "phone_number": " (221)830-7361",
            "city": "Denver",
            "state": "CO",
            "distance_miles": "20",
            "distance_minutes": "40"
        }
    }
  }

Search Contacts by Name

GET /api/v1/contacts/search?name=Mike

{
  "data": {
    "id": "26",
    "type": "contact",
    "attributes": {
      "name": "Mike Moon",
      "email": "[email protected]",
      "phone_number": " (651)563-1511",
      "job_title": "Associate Planner",
      "city": "Denver ",
      "state": "CO",
      "roles": {
        "data": [
          {
            "id": "1",
            "type": "role",
            "attributes": {
                            "title": "Incident Commander"
                          }
          }
        ]
      }
    }
  }
}

Get Weather Data for Incident

'GET api/v1/forecast?location=Denver,CO'

{
  "data": {
      "id": 1,
      "type": "forecast",
      "attributes": {
          "date": "2021-05-24",
          "sunrise": "2021-05-24 11:38:13 +0000",
          "sunset": "2021-05-25 02:15:45 +0000",
          "min_temp": 49.78,
          "max_temp": 73.44,
          "humidity": 22,
          "wind_speed": 11.12,
          "wind_deg": 71,
          "wind_gust": 9.75,
          "conditions": "clear sky",
          "precipitation": 0
          }
      }
  }

Built With

  • Ruby
  • Rails
  • RSpec
  • FactoryBot
  • Faker

Versioning

  • Ruby 2.5.3
  • Rails 5.2.6

Authors

About

Backend Engine for Quick Command web application

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published