Skip to content

Commit

Permalink
#17 - Added support for modifying the database structure from the code
Browse files Browse the repository at this point in the history
#17 - Added driver table
#17 - Added driver_car table
#17 - Added driver_ride table
#17 - Created initial prototype for sending sms
#17 - Moved some mysql configurations

#30 - Added support for modifying the database structure from the code
#30 - Refactored code to create and list rides.
#30 - Added missing tests.
#30 - Moved backend sources.
#30 - Implemented express application for running locally.
#30 - Reestructured backend code to use ES6 classes
  • Loading branch information
douglascvas committed Sep 4, 2018
1 parent 63662c1 commit 1128ade
Show file tree
Hide file tree
Showing 70 changed files with 3,125 additions and 3,852 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# hills-carpal

[![CircleCI](https://circleci.com/gh/RHoKAustralia/hills-carpal.svg?style=svg)](https://circleci.com/gh/RHoKAustralia/hills-carpal)

# Frontend



File renamed without changes.
1,304 changes: 1,304 additions & 0 deletions backend/package-lock.json

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions backend/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "carpal",
"version": "1.0.0",
"scripts": {
"test": "mocha './src/test/**/*.test.js'",
"start": "node src/test/expressApis.js",
"refresh-db": "node ./src/main/database/index.js",
"refresh-test-db": "node ./src/test/database/refreshDatabase.js"
},
"dependencies": {
"body-parser": "^1.18.3",
"express": "^4.16.3",
"jsonschema": "^1.2.4",
"jsonwebtoken": "^8.1.0",
"moment": "^2.22.2",
"mysql": "^2.15.0",
"randomstring": "^1.1.5",
"request": "^2.87.0",
"uuid": "^3.2.1"
},
"devDependencies": {
"aws-sdk": "^2.250.1",
"chai": "^4.1.2",
"chai-exclude": "^1.0.9",
"mocha": "^5.2.0"
}
}
File renamed without changes.
38 changes: 19 additions & 19 deletions infrastructure/services/public_key → backend/public_key
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDATCCAemgAwIBAgIJRppYVkre6ervMA0GCSqGSIb3DQEBCwUAMB4xHDAaBgNV
BAMTE2NhcnBhbC5hdS5hdXRoMC5jb20wHhcNMTgwNjAyMDMyOTA5WhcNMzIwMjA5
MDMyOTA5WjAeMRwwGgYDVQQDExNjYXJwYWwuYXUuYXV0aDAuY29tMIIBIjANBgkq
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqvdMuabJiGr2ntuurtTZB/Mu6GNVyBQN
tnDWjktZIkPKqDiIyl2xxbufIpIw4qEQjOUlJDg4YSi8K9T/mCv+wRes65cjQcw2
x0TNlZtdZ6vG8luWVWLvNE+DjqmsdMIgiLNirdKzNL3Ku2VvuFFvwcBAmXsqORT8
LcLOE2etTqdPuBdC0sGzAMncf+3J+BxLoZNCpxJUsh1vbw6mz6/TJjGmmBzOC70o
LyXX9K+OevsW0bLkZeOJZAsGxDWDJ8B31TOarzvko66IlGukUSmmcg/PPiWdBjp5
IHdjjSjKVdApVrZmltjR7glh3RswVrvqEKGa7dH62928alo2yi0zRwIDAQABo0Iw
QDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTqR7LijtYwkBuqB8txw+TDugz+
6TAOBgNVHQ8BAf8EBAMCAoQwDQYJKoZIhvcNAQELBQADggEBAC9tL9V5NOs1OFkg
wEzRynYByZZpij2YHhZmnJxuIhdHKBf2+/AXcq4zN78y97D6lfdXVueJrB5OSm3R
6yhffgY7JSURIE96LfEjoh63Y7Viy1Pdk4A9aYWvpoAjlnIb+s3vg+13ChH4b5p5
m4w3hOU8jJV2VoGooiTAWeHJsUYUPsMLneVKV7wv8Wl7sgLvO+xeRKpa+Sc71Cym
dLGt3NP+EP9zhFRPxpaCIW3rsMnEgSIuekFmVqzv7exMy+srY2V3p0uqiCHdjDQo
ZoumDRlverqMTWICzZsCRRpT4XcM4NlUMLw+zkQtymmDJGIBkZ7pxF+OfQXLRCHr
bOPxM6M=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDATCCAemgAwIBAgIJRppYVkre6ervMA0GCSqGSIb3DQEBCwUAMB4xHDAaBgNV
BAMTE2NhcnBhbC5hdS5hdXRoMC5jb20wHhcNMTgwNjAyMDMyOTA5WhcNMzIwMjA5
MDMyOTA5WjAeMRwwGgYDVQQDExNjYXJwYWwuYXUuYXV0aDAuY29tMIIBIjANBgkq
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqvdMuabJiGr2ntuurtTZB/Mu6GNVyBQN
tnDWjktZIkPKqDiIyl2xxbufIpIw4qEQjOUlJDg4YSi8K9T/mCv+wRes65cjQcw2
x0TNlZtdZ6vG8luWVWLvNE+DjqmsdMIgiLNirdKzNL3Ku2VvuFFvwcBAmXsqORT8
LcLOE2etTqdPuBdC0sGzAMncf+3J+BxLoZNCpxJUsh1vbw6mz6/TJjGmmBzOC70o
LyXX9K+OevsW0bLkZeOJZAsGxDWDJ8B31TOarzvko66IlGukUSmmcg/PPiWdBjp5
IHdjjSjKVdApVrZmltjR7glh3RswVrvqEKGa7dH62928alo2yi0zRwIDAQABo0Iw
QDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTqR7LijtYwkBuqB8txw+TDugz+
6TAOBgNVHQ8BAf8EBAMCAoQwDQYJKoZIhvcNAQELBQADggEBAC9tL9V5NOs1OFkg
wEzRynYByZZpij2YHhZmnJxuIhdHKBf2+/AXcq4zN78y97D6lfdXVueJrB5OSm3R
6yhffgY7JSURIE96LfEjoh63Y7Viy1Pdk4A9aYWvpoAjlnIb+s3vg+13ChH4b5p5
m4w3hOU8jJV2VoGooiTAWeHJsUYUPsMLneVKV7wv8Wl7sgLvO+xeRKpa+Sc71Cym
dLGt3NP+EP9zhFRPxpaCIW3rsMnEgSIuekFmVqzv7exMy+srY2V3p0uqiCHdjDQo
ZoumDRlverqMTWICzZsCRRpT4XcM4NlUMLw+zkQtymmDJGIBkZ7pxF+OfQXLRCHr
bOPxM6M=
-----END CERTIFICATE-----
54 changes: 54 additions & 0 deletions backend/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
## Initial Setup

### Database
The project holds sql scripts that can be used to incrementally apply changes to the database.
You can therefore also use this scripts to initialize your local database.
To run it:
```
npm run refresh-db
```
By default it will try to connect to a local mysql database with username `root` and password `admin`. If you want to change those configurations you can set as environment variable, for instance:
```
MYSQL_USER=myuser MYSQL_PW=myPassword MYSQL_HOST=myHost MYSQL_PORT=3316 MYSQL_DB=myDB npm run refresh-db
```

### Running the application locally

The application was designed to work with AWS lambdas. Although an *expressJs* layer was added to be able to run the application locally. To start it:

```
npm start
```
**or** to be able to debug it:
```
node ./backend/src/test/expressApis.js
```

**Attention**: The application and tests make use of the database, therefore make sure that you have your environment variables set to configure them to run against the right mysql instance.


### Running the tests
In the `backend/` directory run:

```
npm test
```

### Deploying with serverless
Run the following in the ./infrastructure/services directory to create the API Gateway config and lambdas:
```
npm install
npm install serverless -g
serverless deploy
```

### API Gateway Custom Domain
Services are published on api.carpal.org.au.

This is achieved using:
1. An SSL certificate in North Virginia for the domain
2. A configuration in API Gateway for the custom domain as below:
![image](api-gateway-custom-doman.png)
3. A Route53 entry for api.carpal.org.au is ALIAS'd (like a hidden CNAME) to the above Target Domain Name.

Ref: https://docs.aws.amazon.com/console/apigateway/custom-domains
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ provider:
timeout: 30
environment:
AUTH0_CLIENT_ID: ${file(./props.json):AUTH0_CLIENT_ID}
MYSQL_HOST: carpal.cttgjqpjknhf.ap-southeast-2.rds.amazonaws.com
MYSQL_PW: ${file(./secrets.json):MYSQL_PW}
MYSQL_PORT: ${file(./secrets.json):MYSQL_PORT}
MYSQL_USER: carpaladmin
DOMAIN: carpal.org.au
AUTH0_CLIENT_PUBLIC_KEY: ${file(./public_key)}

vpc:
Expand Down Expand Up @@ -86,6 +89,11 @@ functions:
path: map
method: get
cors: true
notify:
handler: notify
events:
- schedule: rate(2 hours)
- schedule: cron(0 12 * * ? *)
resources:
Resources:
GatewayResponse:
Expand Down
File renamed without changes.
File renamed without changes.
16 changes: 16 additions & 0 deletions backend/src/main/controller/awsLambdaApis.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const CreateRideService = require('../rides/CreateRideService');
const ListRidesService = require('../rides/ListRidesService');
const FindOneRideService = require('../rides/FindOneRideService');
const DatabaseManager = require('../database/DatabaseManager');
const AwsLambdaRideApis = require('../rides/aws/AwsLambdaRideApis');
const databaseManager = new DatabaseManager();

const createRideService = new CreateRideService(databaseManager);
const listRidesService = new ListRidesService(databaseManager);
const findOneRideService = new FindOneRideService(databaseManager);

const rides = new AwsLambdaRideApis(createRideService, listRidesService, findOneRideService);

module.exports = {
rides: rides
};
92 changes: 92 additions & 0 deletions backend/src/main/database/DatabaseManager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
const mysql = require('mysql');

class DatabaseManager {

constructor(databaseConfig) {
this.databaseConfig = databaseConfig || {
host: process.env.MYSQL_HOST || 'localhost',
port: process.env.MYSQL_PORT || 3306,
user: process.env.MYSQL_USER || 'root',
password: process.env.MYSQL_PW || 'admin',
database: process.env.MYSQL_DB || 'carpal',
multipleStatements: true
};
}

createConnection() {
return mysql.createConnection(this.databaseConfig);
}

query(queryString, connection) {
let closeConnection = false;
if (!connection) {
connection = this.createConnection();
closeConnection = true;
}

return new Promise((resolve, reject) => {
connection.query(queryString, (error, results, fields) => {
if (closeConnection) {
let closePromise = this.closeConnection(connection);
return closePromise.finally(() => {
if (error) {
return reject(error);
}
resolve(results);
});
}
if (error) {
console.log("Error executing", queryString, error);
return reject(error);
}
return resolve(results);
});
});
}

closeConnection(connection) {
return new Promise((resolve, reject) => {
connection.end(function (error) {
if (error) {
return reject(error);
}
resolve();
});
});
}

beginTransaction(connection) {
return new Promise((resolve, reject) => {
connection.beginTransaction(function (error) {
if (error) {
return reject(error);
}
resolve();
});
});
}

rollback(connection) {
return new Promise((resolve, reject) => {
connection.rollback(function (error) {
if (error) {
return reject(error);
}
resolve();
});
});
}

commit(connection) {
return new Promise((resolve, reject) => {
connection.commit(function (error) {
if (error) {
return reject(error);
}
resolve();
});
});
}
}

module.exports = DatabaseManager;
30 changes: 30 additions & 0 deletions backend/src/main/database/RefreshDatabase.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const fs = require('fs');
const path = require('path');

const changeSet = [
'2018-08-04-1-create-database.sql',
'2018-08-04-2-create-location-table.sql',
'2018-08-04-3-create-rides-table.sql',
'2018-08-04-4-create-driver-table.sql',
'2018-08-04-5-create-driver_car-table.sql',
'2018-08-04-6-create-driver_ride-table.sql'
];

class RefreshDatabase {
constructor(databaseManager) {
this.databaseManager = databaseManager;
}

async executeAll() {
for (let fileName of changeSet) {
await this.execute(fileName);
}
}

async execute(fileName) {
let sql = fs.readFileSync(path.resolve(__dirname, './changes/' + fileName)).toString().trim();
return this.databaseManager.query(sql);
}
}

module.exports = RefreshDatabase;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CREATE DATABASE IF NOT EXISTS carpal;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CREATE TABLE IF NOT EXISTS carpal.location (
id INT(11),
location GEOMETRY NOT NULL,
suburb TEXT,
placeName TEXT,
postCode VARCHAR(10)
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
CREATE TABLE IF NOT EXISTS carpal.rides (
id INT(11) AUTO_INCREMENT PRIMARY KEY,
client VARCHAR(255),
facilitatorEmail VARCHAR(255),
pickupTimeAndDateInUTC DATETIME,
locationFrom POINT,
locationTo POINT,
fbLink VARCHAR(255),
driverGender VARCHAR(10),
carType VARCHAR(255),
status ENUM('OPEN','CONFIRMED','ENDED','CANCELLED') DEFAULT 'OPEN',
deleted TINYINT(4),
suburbFrom VARCHAR(255),
placeNameFrom VARCHAR(255),
postCodeFrom VARCHAR(10),
suburbTo VARCHAR(255),
placeNameTo VARCHAR(255),
postCodeTo VARCHAR(10),
description VARCHAR(1024)
);

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CREATE TABLE IF NOT EXISTS carpal.driver (
id INT(11) PRIMARY KEY,
name VARCHAR(255),
phoneNumber VARCHAR(20),
facebookUrl VARCHAR(255)
);

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CREATE TABLE IF NOT EXISTS carpal.driver_car (
id INT(11) PRIMARY KEY,
driver_id INT(11),
carModel VARCHAR(255),
color VARCHAR(255),
licensePlateNumber VARCHAR(255),
FOREIGN KEY (driver_id) REFERENCES driver(id)
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CREATE TABLE IF NOT EXISTS carpal.driver_ride (
id INT(11) PRIMARY KEY,
driver_id INT(11),
ride_id INT(11),
confirmed TINYINT(1),
notified24h TINYINT(1),
notified5m TINYINT(1),
FOREIGN KEY (driver_id) REFERENCES driver(id),
FOREIGN KEY (ride_id) REFERENCES rides(id)
);
11 changes: 11 additions & 0 deletions backend/src/main/database/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const DatabaseManager = require("./DatabaseManager");
const RefreshDatabase = require("./RefreshDatabase");
const refreshDatabase = new RefreshDatabase(new DatabaseManager());

process.on('unhandledRejection', error => {
console.log('unhandledRejection', error);
});


refreshDatabase.executeAll(refreshDatabase)
.catch(e => console.log(e));
Loading

0 comments on commit 1128ade

Please sign in to comment.