-
Notifications
You must be signed in to change notification settings - Fork 0
Design
This page describes the basic design and technical details of Support Hero. Feel free to look into the code for more details and comments. Before proceeding further, please go through the details in the Usage and Setup sections.
The main aim of the project is to provide a way for a small team to easily manage their on-duty schedule. It depends on the fact that the team members will collaborate and communicate about their schedule among themselves and primarily use the tool to record their final decisions.
Since this is a one-person, part-time project, the main aim is to conserve effort to quickly have the functionality available for use. With this focus, the command-line client was first developed as it makes it easier to quickly expose functionality. Also, it helps in directly talking to the Database in early-stages of development which minimizes the time from design to final implementation.
Once the basic features were in place, a server API was developed so the client can be used from anywhere as long as it knows the right server to communicate with. The server is enabled for Heroku deploy for ease of deployment.
With this focus, having a working version with essential features was prioritized over other critical components like authentication, having a web interface and better user profile, administration capabilities.
Support Hero is designed to perform better for small shops, say 10-20 members (with simple schedule management needs) though there are no explicit limitations on that but also there are no guarantees that it will work well for large teams.
Support Hero does very few "smart" things and it depends on the team-mates for figuring out details like scheduling fairness. With this approach, the scheduling is based on a given preset order which is repeated as needed and so the onus is on the teammates on how they want the preset to be. Similarly, when a users cannot do a particular shift and marks it as off-duty, Support Hero simply swaps it with another user's day. It is meant for exceptional situations when two teammates could not figure out a swap in advance. It also does not support multiple users having the same off-day. Similarly, Support Hero is currently not heavy on input validation or error handling.
The Rails server is configured to use Postgres as its backend database. The server manages the following information:
- Schedule - which is a mapping between calendar days and user assigned to each day
- OrderEntry - the starting order specified as an order list of usernames which is used as the preset template to repeat while generating the schedule
- User - just usernames
- ScheduledTillDate - remembers the last date till which the schedule was generated. This information is used when extending the existing schedule.
The Postgres database is automatically setup during Heroku deploy and the database migration is run manually to setup the tables.
The schedule is generated by rolling out the preset OrderEntry information over the calendar days, while skipping holidays and weekends so that no one is on-duty on those days.
Unless the schedule is explicitly generated with the make-schedule command, the schedule is generated lazily, only when it is needed to be displayed or when it is accessed for other actions like swapping.
The OrderEntry preset can be changed any time. Once changed, make-schedule command can be used to generate the new-schedule starting from the specified date. Whenever the schedule is generated/extended, it is based on this preset template.
The Server uses Rails controllers to expose its functionality through API end-points and uses JSON as the data-exchange format, as JSON is widely supported and is easy to process and debug.
The Client hero.rb is a Ruby script which is basically a thin-wrapper around the server API end-points. It exposes the end-points as command-line commands. For example:
The command support-hero wraps and exposes the /schedules/support_hero API end-point which is used to get the user who is on-duty today.
The Client primarily does three things around the API:
- Command-line argument processing
- Basic input validation
- Output formatting for display.
The Client consists of two layers: The main script which specifies what command-lines commands and their switches are and the commands processing which does the validation, API interaction and output display.
To avoid having the specify the server URL for every use, the Client gets the server URL from the API_URL environment variable.
The project is a skeletal rails app with the standard layout automatically generated by Rails.
The client code is in the files bin/hero.rb and app/command_processor.rb and the bin/install_hero.sh shell script, the rest is server-side code with many auto-generated stub files.
lib/date_utils.rb - This customizes the existing Date class to provide the following methods: us_holiday_names which lists the US holiday names for the given date, ca_holiday? returns true if it is a valid holiday in California, weekend? returns true if the given date is weekend and the next_schedule_day finds the next available date from the given date which is a valid day for scheduling (not a weekend and not a CA holiday)
Most of the logic driving the features are encapsulated in the models handling that information. For example. the Schedule mode has all the logic related to schedules, OrderEntry knows how to handle preset starting order etc.,
-
scheduled_till_date.rb- Used to know till which date the schedule was generated. -
schedule.rb- The core logic behind the features,generatewrites out the schedule to the DB,extendcallsgeneratemultiple times until it fills up the schedule between the givenfromandtodates. When methods likelist,support_heroaccess the schedule, it is possible that the schedule has not yet been rolled out for that time period and so they callextendinternally to roll out the schedule from the starting order before returning the schedule details. Thus, the schedule is generated lazily when needed. -
order_entry.rb- has therefreshmethod which fully removes the existing present and replaces it with the newly given starting order preset.
app/controllers/ has the implementation for the API end-points and are thin-wrappers around the methods doing the actual work which are in the models.
bin/hero.rb only specifies the command listing and description. The specification for the Client's interface and leaves the actual processing of the commands to app/command_processor.rb which then talks to the server for information or performing actions like swaps.
Slop is used for specifying the command-line interface and for processing the command-line arguments. Holidays module is used for skipping over holidays (with customization for California) and rest-client module is used by the client for communicating with the server.