Challenge Overview

Project Overview

The SolarAgs mobile app is the user front end of a process that automates, customizes, and optimizes the residential solar experience for homeowners. It provide and forum for homeowners to educate themselves about the merits of solar energy, and investigate complete system designs for their home without needing to call installers. For the installer, it provides a high-quality lead generation tool - the homeowner has already been through the design cycle, has seen photos of his/her house with solar installed, and has seen the financial analysis. As such, the app weeds out the window shoppers from the serious buyers.

With SolarAgs application, the user captures a photo of the house from the exterior of their home, answers a series of questions to determine goals and objective of their interest to “go solar” as well as economic considerations.

This data is transmitted to a back-end which uses cloud-computing methods to automate, customize, and optimize a Photovoltaics (PV) solution for the app user’s own home.

The overall product has two parts: A front-end Android application which resides on the smartphone and a Node.js REST API back-end which is hosted in a cloud server.

The Android application is responsible for providing a functioning camera, GPS and compass data, and the entire user experience. After one or more images and data have been sent from the front-end to the back-end, the backend processes the data through a series of algorithms.

Lastly, the back-end returns one or more images and data to the smartphone app, for presentation to the user.

Challenge Task Overview

In this challenge we are building part of the backend - a Node.js REST API.

Functionality Requirements

Technology Stack

  1. The rest api application will be an express.js web application.

  2. Facebook Node.js SDK can be one of the recommended ones by facebook to be used for login.

  3. Dropbox Node.js Module to interact with dropbox for photo hosting, and manipulating submissions data.

  4. MongoDB as database and Mongoose ORM module to interact with the DB - we will use latest stable version.

Login/Authorization endpoint

Users of the android application can login via Facebook or use the app as guests, in either cases, we need a token to keep track of submitted applications by either type of users (logged-in and guest), and that requires an API endpoint to register new user.

The API Login endpoint details :

  1. endpoint signature is ‘POST /login’

  2. request body parameters :

    1. facebook access token parameter (if available)

    2. type parameter : support two values (‘facebook’, ‘guest’)

  3. It accepts input parameters as json format

  4. It returns output as json object

For Facebook Login, the flow will be as follow :

  1. Login via Facebook on Android app and obtain the Facebook Access Token

  2. Pass the Facebook Access Token and Refresh Token to the Signup REST API endpoint with ‘type’ parameter of value ‘facebook’.

  3. API endpoint backend will perform the following logic :

    1. check the given Facebook Access Token to make sure it is valid by making a graph call to the /me endpoint or via other functionality provided the Facebook nodejs SDK module.

    2. Parse the response to get user id and email, and cross-reference this with existing users to see if it’s a new or old one.

    3. Create a random token, create a new User record in DB and store the random token (api_access_token) along with the obtained user id/email/access-token/refresh-token then send the api_access_token (in addition to any other needed info) back to the android app.

      • If backend needed the fb_access_token for getting more info, say retrieving the list of your user’s friends, we can do so by retrieving it from the DB.

    4. For every call hereafter, send the api_access_token to authenticate it.

For guest users, the flow will be like this :

  1. Make call to the Signup REST API endpoint with ‘type’ parameter of value ‘guest’

  2. API endpoint backend will :

    1. Create random token, create new User record in DB and store the random token (api_access_token) and send it back to the android app.

    2. For every call hereafter, send the api_access_token to authenticate it.

The reason here we are tracking guest user so we can associate it with submitted application, and use it to lookup the processed results and send it back to the android application.

Authorization Middleware

You also need to add a middleware to verify the api_access_token for all API calls except the  /login endpoint.

Job Object endpoints

User will provide technical and economic data and upload one or more photos. The data will be stored to DropBox and processed by SolarAgs backend. Storing to dropbox will be transparent to the user. The user will not be able to learn or realize that dropbox was used.

We need a CRUD operations to create, update, retrieve, and delete a Job (represents House Data) Objects.

Here a sequence diagram of the workflow of a Job :

https://drive.google.com/open?id=0B8huYiP6g3MLYUZweUp6STFYeUU&authuser=0

Provided in challenge forums a wireframe with basic explanation about the flow (PRD - SolarAgs v0.01.docx) showing the data we need to collect. Refer to it to get better understanding of what we are building.

Notes about the endpoints :

  1. Set Job :

    1. Signature ‘POST /Job/{id}?’

    2. {id} is optional

    3. The endpoint create or update an existing Job.

    4. It accepts input as "multipart/form-data" as this API accepts images data at the same time as set of key/value pairs (represents the data to be stored and sent to Dropbox for further processing), refer to (job-request.json file for more details about data we send to Dropbox), attributes are :

      • First Name

      • Last Name

      • Age

      • Address

        • Street Address

        • City

        • State

        • Postal Code

        • Mail Stop

        • Country

      • Phone Number - array of type/number pairs :

        • Type

        • Number

      • Gender

      • Login type = {Facebook, Guest, Local Account, Google (future feature)}

      • Email

      • Longitude

      • Latitude

      • Annual Energy Payment (in $)

      • Monthly Energy Payment (in $)

      • Date

      • Time

      • Orientation

      • State

      • Cardinal Direction

      • Door width (in inch)

    5. The images data are required.

    6. Proper validation for input parameters must be added.

    7. Associate a ‘status’ field with the Job record, it can be one of the following :

      • Submitted : indicates the record are submitted to SolarAgs backend

      • Processed : indicates the record returned from SolarAgs backend

      • Completed : indicates the record processed and user completed the process of selecting the Design and Confirmed it.

    8. The endpoint will run logic depending on the status of the record :

      • If record is new perform the following :

        • Create new Job record in database with status ‘Draft’.

        • Create new folder under ‘Inbox’ dropbox folder with name “Job-{id}” where {id} is the Job record id in previous step.

        • Store uploaded images in the “Job-{id} folder.

        • Store submitted information in ‘job-request.json file (refer to sample file provided in challenge forums).

        • Update Job record status to ‘Submitted’.

      • For existing Job if status is ‘Submitted’ then return error with message that record is being processed and cannot be updated.

      • For existing Job if status is ‘Processed’ then it is expected user will do design review and verify the selection,

        • The passed in parameter will be the selected result entry, the ‘selected_result’ will store reference to selected design.

        • Set Job status to ‘completed’.

      • If record status is ‘Completed’ then return error with message that record completed and no further update can be done.

    9. For existing jobs, only user associated with the job can update it.

    10. On successful create/update, the Job object should be returned as json object in the response with status code = 200.

  2. Retrieve Job :

    1. Signature ‘GET /Job/{id}’

    2. {id} represents the Job primary identifier

    3. It returns entity associated with the passed user access token.

    4. It returns the object if found. Otherwise, returns 404 error with friendly message.

    5. On successful execution,the Job object should be returned as json object in the response.

      • The json object will contain the job-response data, the images should be web accessible URLs.

  3. Retrieve All Job :

    1. Signature ‘GET /Jobs’

    2. It returns entities associated with the passed user access token.

    3. On successful execution, It returns array of Job objects in json format in the response. Empty array if no result found.

      • Each object in the array should contain the job-response data and result images.

  4. Delete Job

    1. Signature ‘Delete /Job/{id}

    2. Verify the object exists. If not, return 404 error code with proper message.

    3. It should validate the job related to the passed user access token, otherwise, it should deny the action.

    4. Delete the record from database.

    5. Delete the Dropbox Job-{id} folder from dropbox (Inbox and Outbox)

    6. On successful submission, returns ‘Result : Success’ json in the response.

SolarAgs Status Job Scheduler

  • We need to keep - periodically - checking the jobs in the database with a status of submitted. We can build a Job Scheduler or may be easier to use ‘SetInterval’ and make the interval time configurable with default value to be ‘5’ minutes.

  • The results of the backend processing will be placed under “Job-{id}” in “Outbox” folder in Dropbox.  

  • When result is found update Job record :

    • If result is ‘success’, then set status to ‘Processed’.

    • Otherwise, set status to ‘Failed’ and store the reason in ‘message’ field.

Note that an optimal solution would be to fire the ‘setInterval’ or job scheduler only when at least one Job record is submitted.

Objects Definition

We have two objects to maintain in database :

  • User record

    • ID (Primary)

    • api_access_token (required)

    • facebook_auth (optional)

      • access_token (required)

      • refresh_token (required)

    • email (optional)

    • first_name (optional)

    • last_name (optional)

    • type (required) : ‘facebook’, ‘guest’

  • Job record

    • ID (Primary)

    • user_id : reference User#ID

    • selected_design (nullable)

      • Hold the selected design id (corresponds to designNum of selected design in the job-response.json).

    • status (required) : ‘Draft’, ‘Submitted’, ‘Processed’, ‘Completed’, ‘Failed’

    • message (optional) : stores the fail reason.

You are welcome to improve the model structure.

Dropbox Configuration and Folder Structure

Dropbox credentials should be stored in configuration, configuration will read it from environment variables.

  1. We are providing the Dropbox credentials in challenge forums, you will use it for testing.

  2. We are also providing a sample image you can use for testing.

The following two folders will exist in the Dropbox folder, request and response should follow same exact structure :

  • Inbox (for storing submitting jobs, we write to this folder)

    • job-{id}

      • job-request.json (json file)

      • img01.jpg

  • Outbox (for storing jobs result, we will only read from this folder)

    • job-{id}

      • job-response.json (json file)

      • design01.jpg

      • design02.jpg

Provided in challenge forums sample for job-request.json and job-response.json.

PostMan API File

  • Create postman json file listing all calls and sample data.

  • Provide description for endpoints (recent postman version support endpoint descriptions)

  • Get Started with Postman : http://www.getpostman.com/

Hosting

The target hosting platform is Amazon EC2 AWS. OS is Latest Ubuntu LTS.

Documentation

Provide a detailed README documentation for how to setup and configure the application locally and on aws.

Configurations

You are expected to use environment variables to store sensitive information and environment-specific configurations.    

Folder Structure and Configuration

Follow this folder structure :

  • config/     

    • config.js    

  • app.js

  • controllers/

  • models/

  • services/

  • helpers/

  • README.md

  • env-sample (don't include .env in your submission)

  • .. other files if needed

For configuration, we expect routes and other sensitive config will be configured in config/config.js, we prefer if you use node-config module for that. but We will leave it up to you to use the proper approach.



Final Submission Guidelines

Deliverable

  • All source code files and scripts that address the above requirements.

  • Test samples

  • Detailed readme file as outlined above.

ELIGIBLE EVENTS:

2015 topcoder Open

REVIEW STYLE:

Final Review:

Community Review Board

Approval:

User Sign-Off

SHARE:

ID: 30049016