![Build Status](https://codebuild.us-east-1.amazonaws.com/badges?uuid=eyJlbmNyeXB0ZWREYXRhIjoiYmdJenNsQ2VONW5DTTcvWXJ2SG9GVTdWb1VEVXZ2OEVRZDV5MjhGUm9mcG9iUkhmU0tzbjRwa3BPdjNkY2pDeWFTMy9aMDhTVjJYOFlKOWpTeUdZdTdRPSIsIml2UGFyYW1ldGVyU3BlYyI6IkxaRmE2eFE4aUdYZ1RGOSsiLCJtYXRlcmlhbFNldFNlcmlhbCI6MX0%3D&branch=master)  

# Getting started

Our API requires the following environment variables to be stored in a **.env** file in the root directory. Contact a team member for sane defaults.

## Environmental Variables
* `SESSION_SECRET`: String for hashing passwords
* `SERVICE_SECRET`: String for hashing passwords
* `SALE_FACTORY_ADDRESS`: Address of the deployed Token Sale Factory Contract
* `PURCHASE_FACTORY_ADDRESS`: Address of the deployed Token Purchase Factory Contract
* `INFURA_PROJECT_ID`: API Key for the Infura Blockchain connection
* `S3_BUCKET`: Name of the S3 buckets for documents
* `S3_ENDPOINT`: For prod, this should be set to `img.meridio.co`, for all other environments should be set to `img-dev.meridio.co`
* `AWS_ACCESS_KEY_ID`: AWS Key ID for S3 bucket
* `AWS_SECRET_ACCESS_KEY`: AWS Key for S3 bucket
* `MAILGUN_API_KEY`: API for email sending
* `STREAM_API_KEY`: Stream Key for notifications
* `STREAM_API_SECRET`: Stream Secret
* `STREAM_API_APP_ID`: Stream App ID
* `ON_BOARDING_SECRET`: hashing for registration tokens
* `EMAIL_VERIFICATION_SECRET`: hashing email verification tokens
* `POSTGRES_HOST`: Hostname of your PostgresDB
* `POSTGRES_USER`: Username
* `POSTGRES_PW`: Password pw
* `POSTGRES_DB`: DB name
* `REDIS_PORT`: (optional) Port to connect to Redis, defaults to `6379`
* `REDIS_HOST`: (optional) Hostname of your Redis, defaults to `127.0.0.1`
* `REDIS_PASSWORD`: (optional) Password to connect to Redis, defaults to `NULL`
* `SENTRY_KEY`: (optional) Currently only reports uncaught errors
* `BLOCKCHAIN_ENV`: Currently supporting rinkeby, ropsten, mainnet, ganache
  
## Development Only
* `USER_EMAIL`: If you'd like to prepopulate your user's wallet address, enter in your email address here.
* `USER_ADDRESS_HASH`: If `USER_EMAIL` is found, this address hash will be added as a wallet for that user.
* `BLOCKCHAIN_SERVICE`: local blockchain service
* `SEQUELIZE_TIMEOUT`: (optional) SQL statement timeout (ms) override (default: 5000)
* `SEQUELIZE_LOGGING`: (optional) SQL logging options override (0 or 1, default 0, no sql logging);
* `HTTP_LOGGING`: (optional) Add apache style http logging via [Morgan](https://www.npmjs.com/package/morgan) - always on in development environments (0 or 1 when deployed, default 0, no http logging);


# Running the Full Stack Application
### Method 1: Docker Containers

To bring up the entire Meridio Application locally, run the following command:
```bash
npm run containers:full
```

This command uses relative paths, so you must also checkout the [frontend](https://github.com/MeridioRE/meridio-frontend) and [blockchain service](https://github.com/MeridioRE/meridio-blockchain-service) repositories as well.


# Running the API Stand Alone
### Method 1: Docker Containers

The first time you run the application you must first build the images  with the following command:
```bash
docker-compose build
```

Subsequent launches only require docker-compose up command.
```bash
docker-compose up
```

### Method 2: Host Operating System 
To run the application locally without docker, execute the following command:
```bash
npm run api-dev
```

# Development
### Development in Containers (with hot reload)
To simulate our production environment we use containers in development as well, reloading the application every time changes are detected in the the `api/` directory.

```bash
npm run containers:watch
```

# Testing
### Testing in Docker (with hot reload)
Similarly to the application hot reloading in the previous section, the following command will automatically rerun the test suite when it detects code changes.

```bash
npm run test:containers:watch
```

### Single Test Run in Docker 
To simulate a single run through the test suite use the following command. 
```bash
npm run test:containers
```

### Testing Locally
To test locally run the following command:
```bash
npm run test
```

# Libraries Used
* [Bull](https://github.com/OptimalBits/bull) - is a redis based queue for Node. It allows to create and manage job queues as the primary method of communication with the Blockchain Service.
* [Factory-girl](https://github.com/aexmachina/factory-girl) - For any given test, we need some data about which to make an assertion after performing some operation. This library is a fixture replacement with a [Sequelize](http://docs.sequelizejs.com/) interface. Please note using this package can introduce a DB dependency.
* [Finale](https://github.com/tommybananas/finale) - makes it easy to create flexible REST endpoints and controllers from Sequelize models in our Express app.
* [Mailgun](https://documentation.mailgun.com/en/latest/) - Email API for sending transactional emails from within our application.
* [Mocha with Chai](https://www.chaijs.com/) - is a feature-rich JavaScript test framework running on Node.js and in the browser, making asynchronous testing simple/ Mocha tests run serially, allowing for flexible and accurate reporting, while mapping uncaught exceptions to the correct test cases. 
* [Raven](https://github.com/getsentry/sentry-javascript/) - is an open source package from [Sentry](https://sentry.io) that helps developers monitor and fix crashes in real time.
* [Sequelize](http://docs.sequelizejs.com/)- is a promise-based ORM for Node.js v4 and up. It supports the dialects PostgreSQL, MySQL, SQLite and MSSQL and features solid transaction support, relations, read replication and more.
* [Sinon](https://sinonjs.org/) - is a standalone test spies, stubs and mocks for JavaScript. 
* [Stream](https://getstream.io/docs/) - allows us to build scalable news feeds & activity streams. This is currently utilized during our in-app notifications.

# Miscellaneous

### Postman
We use postman for teams for testing our API directly. For access to our library of prewritten tests, use the following [link](https://meridio.postman.co/collections/1512158-bef84538-5ca3-42e7-a524-afd48cb83311?workspace=61cd5349-e617-4009-8d04-05779d417cb0).

### Launch Exchange/Dai/Token Contracts locally

* Launch [Ganache](http://truffleframework.com/ganache/)
* `truffle compile`
* `truffle migrate --network development --reset`

## [API Documentation](https://uat-api.meridio.co/api/docs/)
## [DB Documentation](https://app.quickdatabasediagrams.com/#/schema/jfY1sYGzPEaOh10GSERkQg)
