Challenge Overview
Project Overview
The Solar Retina is a software platform that provides real-time intelligence of total “behind-the-meter” solar PV (Photovoltaics) generation on the distribution system. Using crowdsourced solar generation data from actual PVs on the distribution grid, we provide superior distributed solar generation analysis
Challenge Overview
In this challenge you are building a web admin portal to import and maintain Solar Retina system data.
Challenge Requirements
You are addressing the following in this challenge :
-
The web application will be built using Ruby on Rails framework.
-
The frontend UI should use UI bootstrap.
-
Database will be MySQL.
-
The scope of the web application in this challenge is divided into three main areas :
-
User and Role-Based service
-
Location/Location Data CRUD service, controller, and pages
-
Location/Location Data importer service, controller, and pages
-
Required Pages and Backend logic
-
Login Page
-
Paths (each endpoint will be handled by Login Controller method):
-
GET /login - to render login page
-
‘redirect’ query string is optional
-
-
POST /login - to submit the login form
-
body will include username/password
-
-
-
it will display a form with username/password.
-
there won’t be links to forgot password, signup .. etc.
-
Login controller should support ‘redirect’ parameter in login URL.
-
-
Navigation - After successful login there should be a unified navigation bar displayed in all pages with following elements :
-
Locations
-
Users
-
Importer
-
-
Locations page (landing page)
-
Paths (each endpoint will be handled by Locations Controller method) :
-
GET /locations - renders the locations page
-
filtering query string parameters are optional
-
-
POST /locations - create new location record
-
Body contains location resource fields/values
-
-
PUT /locations/{id} - update existing location
-
Body contains location resource fields/values
-
-
DELETE /locations - delete existing location
-
Body contains IDs of locations to be deleted
-
-
-
The page displays a table of Locations
-
Ability to filter table by any field.
-
Pagination should be used.
-
Clicking on a location entry will open ‘Location Data’ page
-
Two action buttons per table row :
-
edit
-
delete
-
-
Page will have an expandable form to add new location
-
There should be an option to delete multiple entries at a time.
-
-
Location Data Page
-
Paths (each endpoint will be handled by LocationData Controller method): :
-
GET /locations/{id} - render locations data page
-
{id} represents the ID of the location
-
-
POST /locations/data - add new location data
-
body contains the location data resource fields/values and the location ID to associate with
-
-
PUT /locations/data/{id} - update existing location data
-
{id} is the location id
-
body contains the location data resource fields/values
-
-
DELETE /locations/{id}/data - delete location data
-
body contains ids of location ids to delete
-
-
-
Display table of data related to the selected location id (from locations page)
-
Pagination should be used in the table.
-
Two action buttons per table row :
-
edit
-
delete
-
-
Page will have expandable form to add new location data
-
There should be an option to delete multiple entries at a time.
-
-
Users page
-
Paths (each endpoint will be handled by Users Controller method):
-
GET /users - render users page
-
filtering parameters query strings (optional)
-
-
POST /users - create new user
-
contains User/UserRole resource fields/values
-
-
PUT /users/{id} - update existing user
-
{id} represents user id
-
body contains the user resource fields/values
-
-
DELETE /users - delete users
-
body contains the user ids to be deleted
-
-
-
Page display table of users
-
Table can be filtered by username
-
pagination should be supported in the table
-
an expandable form to add new user (with password)
-
two actions per row :
-
edit
-
delete
-
-
there should be option to remove multiple users at a time
-
-
Importer page
-
Paths (each endpoint will be handled by Importer Controller method):
-
GET /importer - render importer page
-
POST /importer - upload zip file and submit an import job
-
body contains the zip file to be uploaded
-
-
GET /importer/status - endpoint used to update the table list
-
-
The page allows the user to upload a .zip file of data
-
There will be a form to upload a zip file
-
page should display progress bar of the uploading status
-
-
It will display table of past executed imports and their statuses
-
table can have following columns :
-
job id
-
file name
-
upload time
-
status
-
message - used to display failed job’s reasons
-
-
-
The backend logic :
-
Provide progress percentage of the uploading status
-
Unpack the .zip file
-
Read in the metadata.csv file
-
If the locationId exists in the location table, update the values
-
If the locationId doesn’t exist in the location table, create new location record and insert related location data.
-
For all locationIds that exist in location table, but not in the metadata file, remove the record in the location table and cascade-delete entries from the locationData table.
-
-
Read each subsequent csv data file
-
The filename is the locationId
-
The file values are the locationData values.
-
-
-
Resources (Models)
Note: The object model below is an outline. Please follow standard naming conventions within Ruby/ActiveRecord and be consistent.
Build the object models :
-
Location
-
id (incrementing DB id)
-
uniqueId (maps to column 1 in metadata.csv)
-
name
-
address (optional)
-
maximumOutput (maps to column 2 in metadata.csv)
-
lat (maps to column 3 in metadata.csv)
-
long (maps to column 4 in metadata.csv)
-
-
LocationData
-
id
-
location_id (foreignKey to Location.id)
-
dateTime (column 1 in ###.csv is minutes since Jan 1st 2014. Multiply by 60 and add 1388534400 on import to convert to unix epoch.)
-
instantaneousPower (watts) (column 2 in ###.csv)
-
-
User
-
id
-
username
-
password (encrypted)
-
email
-
firstName
-
lastName
-
-
Role
-
id
-
name
-
description
-
parent
-
-
UserRole
-
user_id
-
role_id
-
-
Import
-
id
-
status
-
zip file name/path
-
upload date
-
user_id (id of the user who imported the zip file)
-
These resources defined above do not necessarily represent a valid ruby on rails resource definition, you will follow ruby on rails standard for defining resources and relationships between them.
User Authentication, Authorization, and Managment
-
Use a flexible open source authentication solution that supports the following (devise is an option)
-
We will have single ‘admin’ role.
General Notes
-
Sample data is provided in the challenge forums.
-
All screens must be responsive (desktop and mobile).
-
Default User : Create a script to insert a new user with ‘admin’ role.
-
username : admin
-
password : admin
-
-
Build : Use Rake for build
-
All sensitive, environment dependent information should be configurable.
Folder Structure
We will follow Ruby on Rails recommended folder structure :
-
app/ - Contains the controllers, models, views, helpers, mailers and assets for your application. You'll focus on this folder for the remainder of this guide.
-
bin/ - Contains the rails script that starts your app and can contain other scripts you use to setup, deploy or run your application.
-
config/ - Configure your application's routes, database, and more. This is covered in more detail in Configuring Rails Applications.
-
config.ru - Rack configuration for Rack based servers used to start the application.
-
db/ - Contains your current database schema, as well as the database migrations.
-
Gemfile and Gemfile.lock - These files allow you to specify what gem dependencies are needed for your Rails application. These files are used by the Bundler gem. For more information about Bundler, see the Bundler website.
-
lib/ - Extended modules for your application.
-
log/ - Application log files.
-
public/ - The only folder seen by the world as-is. Contains static files and compiled assets.
-
Rakefile - This file locates and loads tasks that can be run from the command line. The task definitions are defined throughout the components of Rails. Rather than changing Rakefile, you should add your own tasks by adding files to the lib/tasks directory of your application.
-
README.rdoc - This is a brief instruction manual for your application. You should edit this file to tell others what your application does, how to set it up, and so on.
-
test/ Unit tests, fixtures, and other test apparatus. These are covered in Testing Rails Applications.
-
tmp/ Temporary files (like cache, pid, and session files).
-
vendor/ A place for all third-party code. In a typical Rails application this includes vendored gems.
Abstracting
Please make sure to create mixin to include the common code/functionality.
Documentation
Because other programmers will be working with your code, and incorporating it into their projects, all functions must be documented in detail in the code (TomDoc preferred - use Yard TomDoc for HTML output).
Coding Standard
Follow coding standards listed here:
https://github.com/copycopter/style-guide
Readme
Provide a detailed readme file using Markdown language with following information :
-
Overview
-
Setup Prerequisites
-
How to set up (locally)
-
Verification steps
Please note, we're judging this competition not just on the code, but also on the quality of the documentation, and ease of use.
Final Submission Guidelines
Deliverables
-
All source code that implemented the requirements.
-
README file.