The intend of this repo is to address the problem (assignment) described in The Problem section below.
The source code is based on the Rails API Boilerplate. Although, it includes more gems that is required for this project, it has a great workflow handling of the HTTP request, see a diagram at How to Works? section. The intend is to not crowd the controller or models with business logic. This boilerplate is also a great starting point to expand the application with more features and functionalities later.
Some requirements which were not mentioned in the assignment are addressed below. The code can be easily refactored if the requirements changes.
- Use UUID for record IDs in order to avoid vulnerability attacks
- A cage has a unique tag name and a non-unique location
- A cage cannot be deleted when it contains dinosaurs, i.e. not empty.
- A cage max capacity cannot be changed, it can only be set on create
- The max capacity of a cage is set to 100 for validation purposes. It's a constant variable and can easily make it configurable if it needs to
- The max capacity lowest value is 1
- A dinosaur name is unique
- A newly created dinosaur will not be in a cage yet. It has to be moved and assigned to a cage so that the cage
before_addcallback checks are triggered:check_max_capacity?,check_power_status_on_add?, andcheck_same_species? - A dinosaur is not allowed to move to the same cage that it's already contained in, avoiding the possibility of duplicate records
- Ruby v3.1.2
- PostgreSQL
- Redis
-
Install GEM dependencies:
bundle install
-
Create database
rails db:create
Note:
- Connect to the
jurassic_park_developmentdatabase and ensure that you have thepgcryptoextension installed-
This is how you check, do:
select * from pg_proc where proname like 'gen_random_%';
-
If the return is 0 rows, this means both functions:
gen_random_bytesandgen_random_uuid, are not defined then you probably had an error with the extension creation, just drop it and recreate:DROP EXTENSION pgcrypto; CREATE EXTENSION pgcrypto;
-
- Connect to the
-
Run migration scripts
rails db:migrate
-
Run seed migration script to populate the OAuth table:
rails db:seed
-
Run unit tests
rails test [--verbose] -
Run the server
./bin/dev
-
Connect to Swagger UI
https://localhost:3000
-
If you are setting up again, when you already have previous databases:
rails db:reset
resetis equivalent ofrails db:drop & rails db:setup.
- Show resource APIs:
v1/cages/{id}andv1/dinosaurs/{id}were skipped because it keeps failing with this errorActionController::RoutingError: No route matches [POST]when indeed the routes clearly show they are GET requests, see http://localhost:3000/rails/info/routes, when it's running.
When running in a concurrent environment, these changes need to be made:
- For long running processes and to prevent blocking, queue them as background jobs with Sidekiq which is already included as part of the boilerplate template.
- Configure the Puma web server that is already installed with this application. Puma uses threads to handle requests concurrently and pass them to the Rails application.
a. Set the
ENV['WEB_CONCURRENCY']environment variable to the number of child processes, default is1,2if there is enough memory. b. Set theENV['RAILS_MAX_THREADS']environment variable to the number of worker threads, default is5. For reference, see Deploying Rails Applications with the Puma Web Server in Heroku
It's 1993 and you're the lead software developer for the new Jurassic Park! Park operations needs a system to keep track of the different cages around the park and the different dinosaurs in each one. You'll need to develop a JSON formatted RESTful API to allow the builders to create new cages. It will also allow doctors and scientists the ability to edit/retrieve the statuses of dinosaurs and cages.
Please attempt to implement the following business requirements:
- All requests should respond with the correct HTTP status codes and a response, if necessary, representing either the success or error conditions.
- Data should be persisted using some flavor of SQL.
- Each dinosaur must have a name.
- Each dinosaur is considered an herbivore or a carnivore, depending on its species.
- Carnivores can only be in a cage with other dinosaurs of the same species.
- Each dinosaur must have a species (See enumerated list below, feel free to add others).
- Herbivores cannot be in the same cage as carnivores.
- Use Carnivore dinosaurs like Tyrannosaurus, Velociraptor, Spinosaurus and Megalosaurus.
- Use Herbivores like Brachiosaurus, Stegosaurus, Ankylosaurus and Triceratops.
- Cages have a maximum capacity for how many dinosaurs it can hold. Cages know how many dinosaurs are contained.
- Cages have a power status of ACTIVE or DOWN.
- Cages cannot be powered off if they contain dinosaurs.
- Dinosaurs cannot be moved into a cage that is powered down.
- Must be able to query a listing of dinosaurs in a specific cage.
- When querying dinosaurs or cages they should be filterable on their attributes (Cages on their power status and dinosaurs on species).
- Automated tests that ensure the business logic implemented is correct.
Today is free admission. Enjoy the park and have a wonderful experience! Hope to see you back!!