Figure 1: Simplified 2 Sided Market Concept
This is a 2 sided marketplace project using HTML5 / CSS3 / Ruby 2.4 and Rails 5.0.2 framework. Other tools such as Ubuntu Environment / Github / Trello Board / DB Designer / Adobe Illustrator and AutoCad.
The project started out with some research and investigation on what is about a 2 sided marketplace. Some of the best known tech industry disruptor such as Uber and Airbnb are studied since these platforms are considered as a 2 sided marketplace. In short, these platforms are built to benefits both the operator and consumer. The operator could maximise use of their assets to get better returns by cutting off traditional agencies. As for the consumer, they could get similar services at much lower cost.
Figure 2: 2 Sided Marketplace Disruptors and Traditional Services
After gathering some insights, a viable 2 sided marketplace is worth to be examined. The marketplace would allow Advertiser to use private cars to advertise. In return, the driver would get paid for driving the advertisement on the road with their own private car. Some problems are identified and possible solutions to each problem are provided. Please refer to following for details.
Problems | Solutions |
---|---|
Expensive to advertise on billboards, television, radio broadcast channels | Provide more affordable advertising alternative |
Short period of advertisement time-frame permitted on existing channels | Provide longer period of advertising campaign due to lower cost |
Difficult to know if general public would know the existence of my business online web-page if there is already one | More people would be able to visit your business web-page due to wide area message delivery technique (i.e. car travel further and to many places) |
Unable to pinpoint desirable advertisement location/vicinity | Allow advertiser to choose where their branding and messages should go and enable better audience/demographic targeting |
Frustrated by not being able to capture the impression data generated from other advertisement channels | Advertiser could capture impression data generated by driver's mileage and thus impression count using GPS and traffic algorithms combination |
Table 1 : Current Problems and Possible Solutions to Each Problem
Subsequently, target markets are also identified. The application is mostly suited for small and medium businesses, business startups, and private drivers.
Users | Remarks |
---|---|
Small and Medium Businesses | Small and medium businesses from different sectors who wants to advertise |
Business Startups | Any Business Startup from different sectors |
Private Driver | Any private driver who owns a car |
Table 2 : Target Markets
From above, the primary of this application is to enable advertiser to find/locate private drivers to advertise for them. Just Imagine, "What if business could have their brand on every private car?"
Before starting the application architect design, some user stories are generated to ensure all entities are captured for the database design. Please refer to following table for details.
Advertiser / Business | Private Driver |
---|---|
As a business owner, I would like to have my brand to be known by general public | As a driver, I would like to have someone to cover my fuel cost for doing my routine driving |
As a business owner, I would like to advertise business message in an affordable and effective way | As a driver, I would like to reduce my maintenance cost on car servicing |
As a business owner, I would like to have my business contact and web address to be seen on road | As a driver, I would like to earn some extra pocket money or rewards by using my car |
As a business owner, I would like to have my brand to be noticed around a few suburbs | As a driver, I would like to support my local area businesses by helping them to get noticed |
As a business owner, I would like to have my brand to be recognized in public area without spending significant amount of money | As a driver, I would like to deliver advertisement messages for the brand that I love |
As a startup entrepreneur, I would like to start advertising my business messages before formally launching my company | As a driver, I really hope someone could help me indirectly to reduce my yearly registration and insurance cost |
As a business owner, I would like to use additional advertising channel to deliver my brand and messages out to the public |
Table 3 : User Stories
Six different entity models or tables are setup to contain all the required attributes for this application. This included User, Profile, Vehicle, Vehicle Photos, Advert and Order. The User model will be limited to one Profile, One Vehicle, many Adverts and has many Orders. In other words, each of the Profile, Vehicle, Advert and Order model belongs to the User.
Figure 3: Entity Relationship Diagram
The Vehicle model has many VehiclePhotos which is setup as a separate model because the Vehicle is allowed to have many photo_ids which belongs to its Vehicle. The Advert Model has a separate table setup because the User is allowed to have many advert_ids. An Order table also is setup. The Order belongs to User and has one vehicle.
Figure 4: Application Architecture Approach
Before getting into wireframes design, web application architecture and some flowcharts are mapped out just to visualise what web pages are needed in the application for information feeding. Once, the flowcharts are determined, wireframes design is the next step in the application building process. The following figure illustrate how the flowchart works together with the web architecture.
Figure 5: Application Flowchart
The wireframe started out with desktop layout design due to bootstrap CSS components that allow the content to show in mobile screen seamlessly once the classes are properly utilised in the HTML tags. Please refer to following for some wireframes layout in both desktop and mobile versions.
Figure 6: Wireframes Design for Static Pages
Figure 7: Wireframes Design for Web Application Pages
The application started with incorporating bootstrap 3.3.7 vendor files into Rails assets folder. This ensures that the static pages are utilising Bootstrap styling. A customer.css.scss file is also stored in assets/stylesheets folder. This file mainly contains the custom styling for static pages. In order to enable the bootstrap and custom styling files, both “require css/bootstrap” and “ require custom” needs to be declared in the application.css file above the “require_tree .” declaration. All images displayed in the static pages are stored in the assets/images folder. The static pages are handled by spotted_pages_controller and specific routes [i.e. “root ‘spotted_pages#home” and get ‘faq’, to: ‘spotted_pages#faq’]
For the User model, Devise gem is installed to activate. It has all both in-built attributes such as email and password for user to sign up and login. There is no customisation performed on the Devise User model. For efficiency, the devise-bootstrapped gem is installed to style all User Devise pages in the views/devise directory after all devise views are generated. With this accomplished, additional sign‑in, sign‑up and sign‑out links are inserted in to the navigation bar for user access. For example, the navigation would have a “Hi, User” link in the navigation bar as a way to inform the user that he/she is already signed in and can navigate straight into their personal profile show page.
The next step is to generate scaffolding for Profile model using rails command, rails generate scaffold Profile user:references first_name last_name avatar address mobile_number. The intention to have a Profile table is to ensure registered user directed straight into completing their profile before deciding whether to become an advertiser or a driver. In order to achieve this, the in-built Devise method [i.e. “after_sign_in_path_for(resource)”] is inserted into application_controller. Inside the method, If Else statement is implemented to properly direct the user the correct show page. If the user has not completed its profile, the user is always directed to the create profile page after signing in. But, if the user has already completed its profile, the user is always directed to its own profile page after signing in.
As mentioned, the Profile model belongs to the User Model. Thus, it is important that an association is set in the profiles_controller.rb file. This association would be setup under the create action [i.e. “@profile.user_id = current_user.id”], and @ profile.save is to ensure the user’s profile is saved after being created. At this point, CarrierWave/MiniMagick/RMagick gem are installed to allow user to upload their personal avatar in the profile building process. The user is only allow to upload one single avatar and remove/replace it whenever is necessary. This create new profile and show profile views are not heavily style as the main priority is to get the functionality to work.
Once the user has completed their profile, the user would have a choice to either become an advertiser or a driver. If the user chooses to become a driver, a page to build new vehicle details page would be shown to the user. Before this page is available, a scaffold command to generate Vehicle needs to be performed [i.e. “rails generate scaffold Vehicle user:references car_make car_model car_color car_rego”]. The driver would be required to fill in all information and have an option to add many vehicle photo if he/she wanted to. Another scaffold command to generate Photos needs to be performed [i.e. “rails generate scaffold Photos vehicle:references image”] for the user to upload their vehicle photos.
At this point, some association needs to be set in both vehicles_controller.rb and photos_controller.rb files. In the vehicles_controller.rb file, the association setup under the create method would be “@vehicle.user_id = current_user.id” and “@vehicle.save” is to ensure the driver’s vehicle is saved after being created. As for the photos_controller.rb file, the association setup would be under the new method with “@photos.vehicle_id = vehicle.id” and “vehicle.id = Vehicle.find(params[:vehicle])” so that the photos uploaded linked back to its respective vehicle_id. The vehicle photo upload feature is accomplished through Carrierwave gem.
Once all necessary vehicle details are inserted by the driver, it would then be shown when the driver click on the vehicle details show page link [i.e. “vehicle_path(current_user.vehicle.id)”] in their driver’s profile show page. In this application, the driver is only allowed to build a vehicle details because an assumption is made that the user only owns a vehicle in general. This is the reason behind why a User has_one Vehicle. Now, the next step for the driver to follow is to wait for an advertiser to order its vehicle before starting to drive.
Whereas, if the user have chooses to become an advertiser, a page to create new advertisement. Before this page is available, a scaffold command to generate Advert needs to be performed [i.e. “rails generate scaffold Advert user:references business_name business_number advert_title advert_description advert_duration advert_location advert_sticker_location payout_per_mile”]. The advertiser would be required to fill in all information including the advertisement image upload feature provided by CarrierWave gem. The advertiser is also allowed to create multiple advertisements under its business profile which could be viewed by clicking on the show advertisement link [i.e “advert_path(current_user.adverts.ids)”].
In the advertisement show page of each advertiser, a link to order vehicle is provide only if an advertisement exist. The reason is that the vehicle order would need to have the required information such as advert_period and pay_per_mile values which is needed for the application to receive an amount payment from the advertiser. Some association needs to be made after scaffolding to generate Order model [i.e “rails generate scaffold Order user:references vehicle:references stripe_id”]. An order needs to verify the correct advert_id and vehicle_id. Therefore, @ vehicle = Vehicle.find(params[:vehicle] / @ advert = Vehicle.find(params[:advert]) / @ order.vehicle_id = vehicle.id / @ amount = @ advert.pay_amount needs to be declared under the new action.
In this application, assumptions are made for calculating the payable amount. A month of campaign duration is equivalent to 30 days and a driver is expected to drive a maximum of 5 miles each day. At this stage of the application, the advertiser is only allowed to make a vehicle order instead of multiple orders. Thus, a pay_amount method is declared in the Advert model (i.e. advert.rb file). This allows Stripe transaction to capture the @ amount payable from the Advertiser towards the application service provider. The payment would then be made to the drivers on weekly / fortnightly / monthly basis provided that the driver had met the advertiser campaign requirement. The Stripe transaction is not possible without installing the Stripe gem and creating a private environment for the API keys.
So far, the application would still need to have several more features, development testing and CSS styling before it can reach a minimum viable product. The features that would be added in the coming future are as followed;
- Multi-image upload for vehicle
- Search function for advertiser to search available vehicle
- Multi-vehicle order
- Order status of the vehicle
- Proper Stripe functionality
- Mailer to ensure registered user receive confirmation and information for both incoming/outgoing orders and payments
- Driver milage tracking and advertisement impression data monitoring
In summary, this application is still in MAP (Most Anticipating Product) phase and more works needs to done to achieve MVP. It is realised that good planning at the start had helped to achieve better application building process although not all specifications of the project are met.