MixTape Manager is a CLI tool that makes changes to a collection of playlists consisting of users and songs.
- Install
Ruby 2.6.4
(may work with earlier versions) - Install bundler
- Clone this repository
- Navigate to the root of the repo
- Run
bundle install
- Give permissions to run mixtape:
chmod +x bin/mixtape
- I have provided default files for the input and changes under the
data/
directory. - The output file can be found in the
export/
directory - Run from the command line:
where
bin/mixtape mixtape.json changes_file.json output_file.json
changes_file.json
is a set of changes you want to apply to the original file,mixtape.json
. The output file will be written toexport/output_file.json
.
This sample app currently supports the three requested functions from the exercise:
- Adds an existing song to an existing playlist
- Add a new playlist for an existing user where the playlist includes at least one existing song
- Removes an existing playlist
The changes take the form of a .json
file. Take care in how the data is structured as it determines which of the three supported features is invoked. Please look at the provided changes.json
file and the following examples. Note that each data structure is a child of "playlist": {}
and "id"
refers to the playlist's id.
- Adding a song to a playlist must take this form:
{ "id" : "1", "song_ids" : [ "5", "27", "30" ] }
- Adding a new playlist to a user must take this form:
{ "user_id" : "2", "song_ids" : [ "40", "22", "25" ] }
- Removing a playlist must take this form:
{ "id" : "3", "user_id" : null }
- Written in
Ruby
- Using
Thor
gem Rspec
+Aruba
for testing (pending)
- I wrote the app in such a way that it supports a single user on a local machine and it only supports a handful of features.
- This resulted in many design decisions in the codebase that could down the road make it harder to add new features.
- A lot of the code can be DRY'ed up. For example, I wrote a crude imitation of
ActiveRecord
to handle the pseudo-creation ofplaylists
,songs
andusers
in-memory. A lot of this code is repeated across the classes and this can be cleaned up by creating a class that bundles together shared functionality. I could've went ahead withActiveRecord
but I felt it was too much overhead to deal with for such a small use case. - This app only supports text files but we could expand to all types of inputs and outputs by adding adapters for databases or different file types.
- There is a lot of logic contained in
cli.rb
that can be extracted out to other methods or services.
- At present, this app has a poor usability outside of tech-savvy individuals who would know how to run this CLI tool.
- Not only that, the input and outputs are limited to text files and is restricted to local use only.
- The CLI can only process and produce one file at a time.
- We could scale for usage by hosting this CLI tool in the cloud for example, behind an API. It would then be able to handle multiple requests.
- Once "online", we'll have more options to scale
- Say we were to provide this tool as an API that is accessible by the Internet...
- We can increase performance by scaling horizontally, bumping the number of available servers that run the API and put this behind a Load Balancer to handle traffic.
- We can separate out the writing vs reading into their own standalone services; each with their own resources perhaps.
- We can only hold so much in-memory data. We can turn the original input source file into a datastore and then the output can be written to this datastore.
- If the changes file is extremely large, we can make accomodate for this by streaming the changes file or loading each change into an event-queue. A separate worker then can consume each change.
- If the data is stored in a database, we can create indexes for attributes that are often looked up. e.g. users, songs and playlists
- We can cache the data so it can be retrieved quicker. Changes to playlists can invalidate and update caches as we see fit.
- I had fun working on this project!
- It got me interested in using
thor
as a tool to build CLIs. I was more familiar with built-in tools likerake
tasks forRails
or just usingOptionParser
for very simple one-file ruby CLI tools. - I need to add unit tests for the various models in the app
- I would like to add a persistence layer to this tool, like a database, to store the data for later use.
- There's coupling between
Playlist
andSong
that I would like to fix. Perhaps a join-table of sorts. - My
changes.json
file is very picky with how each of the requested features are formatted. If we were to add more features for the project, I would need to change how the app interprets the changes. Perhaps have named actions like "update" or "destroy", much like a CRUD app. Then we can treat the changes file li - I would like to add more error handling. I've added a handful of the obvious ones but I certainly did not cover all edge cases.
@ddh
This program is available as open source under the terms of the MIT License.