Giter Site home page Giter Site logo

gilded_rose's Introduction

gilded_rose

Setup

System Requirements

  • nodejs is installed (I said >=8.0 because that's what I've developed on, though I'm sure an earlier version will cut it)
  • Probably any OS with a terminal and POSIX-compliant shell

Startup

Setup should be as easy as:

git clone https://github.com/jaredhm/gilded_rose.git && cd gilded_rose
npm install
npm start

This ought to install all the required dependencies locally and then run the application. Once this is done, you ought to see the following printed to your terminal:

Booking app listening on port 3000!

A high-level overview

This application presents an API which allows guests to get and secure bookings at an inn. Queries to the /bookings routes take guest and storage constraints. A greedy booking algorithm is used to assign beds at the inn to guests based on how many pieces of luggage each guest holds and how many shared luggage slots are available in each of the rooms. The entirety of the inn is modeled using native NodeJS objects stored in-memory. There are objects for representing rooms, beds, luggage slots, guests, the booking schedule, etc.

Using the API

Querying for a booking

To query for a room assignment which will satisfy guest and luggage constraints, do

 GET /booking/guests/:numGuest/luggage/:storageNeeded

Where both numGuests and storageNeeded are integers. For example:

curl -XGET -w '\nCode:%{http_code}' localhost:3000/booking/guests/2/luggage/3
{
   "error" : "",
   "booking" : {
      "gold" : 0,
      "rooms" : {
         "Foo" : {
            "beds" : [
               {
                  "openLuggageSlots" : 0,
                  "guest" : {
                     "luggage" : 1
                  },
                  "name" : "A"
               }
            ]
         },
         "Baz" : {
            "beds" : [
               {
                  "name" : "A",
                  "guest" : {
                     "luggage" : 2
                  },
                  "openLuggageSlots" : 0
               }
            ]
         }
      }
   }
}
Code: 200

When the booking can't be satisfied, the API will respond as followings:

curl -XGET -w '\nCode: %{http_code}' localhost:3000/booking/guests/2/luggage/4
{
   "error" : "Could not accomodate booking"
}
Code: 404

Making a booking

When the client wishes to make a booking for a set of luggage and guest constraints, do

POST /booking/guests/:numGuest/luggage/:storageNeeded

Again, both numGuests and storageNeeded are integers here. An example query:

curl -XPOST -w '\nCode: %{http_code}' localhost:3000/booking/guests/2/luggage/3
{
   "error" : "",
   "booking" : {
      "rooms" : {
         "Foo" : {
            "beds" : [
               {
                  "name" : "A",
                  "guest" : {
                     "luggage" : 1
                  },
                  "openLuggageSlots" : 0
               }
            ]
         },
         "Baz" : {
            "beds" : [
               {
                  "name" : "A",
                  "openLuggageSlots" : 0,
                  "guest" : {
                     "luggage" : 2
                  }
               }
            ]
         }
      },
      "gold" : 21
   }
}
Code: 200

When the booking can't be satisfied, the API will respond as followings:

curl -XPOST -w '\nCode: %{http_code}' localhost:3000/booking/guests/2/luggage/4
{
   "error" : "Could not accomodate booking"
}
Code: 404

Querying for current Bookings:

The API may be queried for schedule of currently-occupied beds. Do this with

GET /schedule

An example query would be:

curl -XGET -w '\nCode:%{http_code}' localhost:3000/schedule
{
   "schedule" : [
      {
         "checkout" : "2018-02-20T08:00:00-05:00",
         "bed" : {
            "name" : "A",
            "guest" : {
               "luggage" : 1
            },
            "openLuggageSlots" : 0
         }
      },
      {
         "checkout" : "2018-02-20T08:00:00-05:00",
         "bed" : {
            "openLuggageSlots" : 0,
            "name" : "A",
            "guest" : {
               "luggage" : 2
            }
         }
      }
   ],
   "error" : ""
}
Code: 200

Extending the application

Adding more rooms would be trivial, I think. The algorithms here are general enough that you'd only ever run into trouble extending the size of the inn when the complexity of the booking function catches up.

Adding more business logic constraints would probably be a bit of a lift. Currently, the code is laid out pretty well, but the logic is baked into the model and the booking libraries. I've not implemented any framework supporting arbitrary booking constraints; number of guests and storage space are the only factors which the API attempts to statisfy.

As for adding more gnomes to the cleaning crew, sadly I was not able to satisfy this constraint, so I don't know if I can really say how the application would've handled such a configuration. Had that portion been implemented, I would've liked to see optimazation of cleaning slots via maybe a sliding window algorithm.

Time spent and future changes

I'd estimate that I've spent 8 to 10 hours altogether on this project so far.

Had I more time, there are several things that I'd like to see finished:

  • Scheduling and cleaning functionality actually implemented. Unfortunately, due to time constraints, I didn't get around to meeting this requirement

  • I a web setting this totally should've be done using a database as persistence, rather than using in-memory objects. Currently, this application runs the risk of race conditions, and data doesn't persist beyond the life of the applications. However, modeling data using node objects made implementing business logic much, much quicker. The silver lining is that now I have a pretty sensible schema for a DB.

  • Better documentation. This would mean a number of things:

    • Had I the time, I would first implement the API using swagger so that I could properly specify the inputs and outputs of the API schema and use it to generate documentation, skeleton code, and API-level test templates.
    • Additionally, like to see something like JSDoc used for all function headers. This would allow me to generate documentation in all sorts of pretty formats.
  • I think I mentioned this somewhere in the code, but allowing for start-time configuration of the inn would be much more sustainable. Currently everything is hard-coded in the Inn object's constructor. I figured as long as this application didn't use a DB, though, that was something that could be left on the cutting room floor.

  • Automated tests. There's a section about this below. I just think testing is super important, and I didn't get to do it.

Testing

Generally, this isn't something that I allow to slip as a developer, but due to time constraints automated testing got cut.

In the future, I would implement unit and integration tests (probably using something like mocha) in order to test that functional interfaces do not change (without appropriate updates to the tests and dependent code), and that various objects continue to talk to each other in expected ways.

Additionally, using a library like supertest or a tool like postman, I'd want to see API-level E2E tests implemented to ensure that application-level interfaces stay correct and backwards-compatible.

If I were really feeling ambitious, I'd also encourage consumers of the API to implement consumer-based contract tests with pact.

Online resources used

  • The moment docs - For interracting with the moment APIs
  • The express docs - For standing up routes, and interracting with request/response objects
  • The priorityqueuejs docs - For using the implementation of the priority queue library I used
  • The Mozilla JS docs - For all things node. E.g. syntax stuff, standard runtime libraries, etc.
  • StackOverflow, to troubleshoot a medley of problems. Documenting them all here would be overkill, as much of the documentation for various idioms used is embedded within the code
  • The project spec, of course

Third party tools/frameworks used

I kept dependencies to a minimum, I think. All that's needed is:

  • express - provides a nice, easy way to create a node API fast

    Chosen because I've used it before, and because of how quickly and easily you can stand up routes, and because of the request/response APIs it provides. The documentation is also pretty nice.

  • moment - really convenient set of functionality for working with dates and times

    This one I'd never heard of before today. But one look at the docs and I was sold; this library is neat and tidy and really powerful. Not to mention it introduces zero extra deps into your project

  • priorityqueuejs - implementation of a priority queue giving you callback-driven sorting. Used for optimal (I think) booking algorithm

    Again, I'd never used this. To be perfectly honest, I googled 'nodejs priority queue' and chose one which seemed to be used pretty well by the community. Really just didn't want to crack the algorithms book and reinvent the wheel.

gilded_rose's People

Contributors

jaredhm avatar

Watchers

James Cloos avatar  avatar

gilded_rose's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.