Skip to content

An internal SPA for the purpose of setting and reading prices in terms of each product in the online shop with microservice approach.

Notifications You must be signed in to change notification settings

DanielLin9406/fullstack-priceDashboard

Repository files navigation

Price Dashboard

Build Status

This project was originally desinged as an internal tool for a company I was at and for the purpose of setting and reading product's price. Initially, it contains only front-end code since I had collaborated other member in backend team. After I had left the company, I refactored my front-end code and re-built it to a complete full-stack project with container technique. It also has a basic CI pipeline right now.

Set a new promotion and view a particular promotion. preview1

Details price in terms of different user preview2

Features

  • The state is always up-to-date with backend even when create/update/delete operation has been triggered.
  • Allow user to auto sign in if browser has been permitted to store his/her password.
  • Power visual for understanding which promotion is on live and what is next promotion.
  • You can easily calculate a product price for a user who could has any combination of company's early product before.

Web Service Features

Tech perspective:

  • Take advantage of the power of Webpack for packaging web service in dev and prod. environment instead of directly using CRA.
  • Separte layout, route and page as component for more flexibility.
  • Auto sign in with Credential Management API.
  • Separate Redux's mapStateToProps and mapDispatchToProps from every component in order to make it easy to understand.
  • Implement React's design pattern such as compound, render-props and context api to build reuseable and clear component.
  • Use nginx as static file server in production environment.

User/Promotions/Prices/Upgrade-rules Service Features

Tech perspective:

  • Best practice of Node/Express with ES6 syntax(e.g. self-contained components as file structure).
  • Thanks to Redis, no extra DB query command is executed when post/update/delete router has been called and still can return a full list of promotion.
  • Every route has implemented Redis as cache server to reduce DB's query operation.
  • Use NGINX as a reverse proxy.

Prerequisite

This section is necessary no matter which way to start/build this project.

  • Node v10.16
  • npm v6.9

Web Services

# ./services/web/.env

GOOGLE_CLIENT_ID=<Google OAuth 2 Client Id>
API_HOST_PRICES=http://localhost
API_HOST_PROMOTIONS=http://localhost
API_HOST_UPGRADERULES=http://localhost
API_PORT_PRICES=5000
API_PORT_PROMOTIONS=5001
API_PORT_UPGRADERULES=5002
API_VER_PRICES=v1
API_VER_PROMOTIONS=v1
API_VER_UPGRADERULES=v1

User Services

# ./services/user/.env

PORT=4999
# Same as the client id in web service
CLIENT_ID=<Google OAuth 2 Client Id>
CLIENT_SECRET=<Google OAuth 2.0 client Secret>
REDIRECT_URI=http://localhost:8080/auth/callback

Prices,Promotions,Upgrade-Rules Services

# ./services/prices/.env
# ./services/promotions/.env
# ./services/upgrade-rules/.env

PORT=5000(promotions) | 5001(prices)| 5002(upgrade-rules)
DATABASE_URL_PROD=<MongoDB Altas URL>
DATABASE_URL_DEV=<MongoDB Altas URL>
REDIS_HOST_DEV=127.0.0.1
REDIS_HOST_PROD=127.0.0.1
REDIS_PORT_DEV=6379
REDIS_PORT_PROD=6379
AUTH_HOST_DEV=localhost
AUTH_HOST_PROD=localhost
AUTH_PORT_DEV=4999
AUTH_PORT_PROD=4999
AUTH_VER_DEV=v1
AUTH_VER_PROD=v1

Start Project by Default Environment Setting

You have two ways to start this project:

# Method 1. In project root (Highly Recommonded)
docker-compose -f docker-compose-dev.yml up

# Method 2. In project root
See below details

Method 1: docker-compose

This method is easy. Open browser and go to http://localhost:3050. You can see the dashboard.

Method 2: npm script

If you want to do it with purely npm command, there are more additional setup:

  1. Install Redis.
# Use homebrew on MacOSX
brew install redis
  1. Install Dependence of each service
# ./
# ./services/web
# ./services/promotions
# ./services/prices
# ./services/upgrade-rules
# ./services/user

npm i
  1. Start Redis
redis-server
  1. Start Project
# ./ @project root
npm start
  1. Check result

Open browser and go to http://localhost:8080.

More Slient Start Script

# with JSON Mock server (only get data is available )
npm run start:jsonserver

# with other server on same localhost but port
# Need to start server first
npm run start:dev

Build Project and Run Production version

You also have two ways to run production version:

# Method 1. In project root (Highly Recommonded)
docker-compose -f docker-compose-stage.yml up

# Method 2. In project root
(TODO)See below details

Method 1: docker-compose

This method is easy. Open browser and go to http://localhost:3060. You can see the dashboard.

Method 2: npm script

  1. Run Production Bbuild
# ./ @project root
# Use Babel to complie import syntax to require
npm run build
  1. Run Production Server
# ./ @project root
# Use Babel to complie import syntax to require
npm run prod
  1. Check result

Open browser and go to http://localhost:8080.

More Client Build Script

# ./services/web
# with other localhost API server in different port
npm run build:dev

# stage as API server
npm run build:stage

# production as API server
npm run build:prod

TechStacks

Web

  • Webpack 4 custom scaffold
  • Babel 7
  • React 16 with render props, compound pattern
  • Redux with Module pattern
  • Redux-thunk
  • React-Router 4
  • React Hot loader
  • React-Loadable for async loading page
  • Redux with module pattern
  • (TODO) Server side rendering (SSR)
  • (TODO) Jest+puppeteer for component unit test
  • (TODO) Google Analytics and use Google Optimize
  • Husky+Lint-stage
  • ESlint+Prettier
  • Json-server
  • Sensitive data handler: dotenv
  • Google OAuth 2.0

Promotions, Price, Upgrade-Rules and User

  • Babel node for compiling ES6 syntax
  • Express.js
  • Restful API
  • (TODO) Mocha+Chi for API unit test
  • Mongoose
  • MongoDB Altas
  • Redis for DB caching
  • Sensitive data handler: dotenv
  • API authorization between services

Dev-Ops

  • Docker
  • Docker-compose
  • Nginx as reverse-proxy
  • Nginx as static file server in production
  • Bash 5 for development
  • Travis plays as CI role
    • Delegate gcloud to handle kubectl command
  • Leverage Terraform to create ECS and EKS.

Cloud - Service Structure on AWS for multi-docker

  • AWS Elastic Beanstalk (EB)
  • AWS Elastic Container Service (ECS)
  • (TODO)AWS Elastic Cache (EC) for Caching instead of Redis

Cloud - Service Structure on AWS for Kubernetes

  • (TODO) AWS Elastic Container Service for Kubernetes (EKS)

History

  • origin/initial-version: this is the first version which contains only front-end side code
  • origin/basic: Add client and server to become full-stack project
  • origin/basic-refractor-setpricerule: Checkout from origin/basic and refractor a huge amout of the front-end code that becomes componentization.
  • origin/master: complete full-stack project with dev-ops pipeline.

License

MIT

TODO

  1. Check React performance with an idea provided by this article

  2. Implemtn GA and Google Optimizie

  3. Check Node practice to match a Node.js best practice guide

  4. Replace one or several services from Node to Python or GoLang for study purpose.