Skip to content

Commit

Permalink
Merge 1fb6d7a into 628fc55
Browse files Browse the repository at this point in the history
  • Loading branch information
chidimo committed May 17, 2019
2 parents 628fc55 + 1fb6d7a commit 244b638
Show file tree
Hide file tree
Showing 7 changed files with 301 additions and 303 deletions.
102 changes: 31 additions & 71 deletions controllers/LoansController.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import { body, validationResult } from 'express-validator/check';
import { sanitizeBody } from 'express-validator/filter';

import loans from '../utils/sample.loans';
import repayments from '../utils/sample.repayments';

const LoansController = {

get_all_loans: (req, res) => {
const { status, repaid } = req.query;
const boolean_repaid = (req.query.repaid === 'true');
Expand Down Expand Up @@ -33,48 +29,25 @@ const LoansController = {
else res.status(200).json({ data });
},

create_loan: [
body('tenor')
.isInt({ min: 1 })
.withMessage('Tenor cannot be less than 1')
.isInt({ max: 12 })
.withMessage('Tenor cannot be greater than 12'),
body('amount')
.isFloat({ min: 50000 })
.withMessage('Amount cannot be less than 50,000')
.isFloat({ max: 1000000 })
.withMessage('Amount cannot be greater than 1,000,000'),

sanitizeBody('tenor').toInt(),
sanitizeBody('amount').toFloat(),

(req, res) => {

// don't validate email since we'll read it from logged in user
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() });
}
create_loan: (req, res) => {
const { email, amount, tenor } = req.body;
const interest = 0.05 * amount;
const paymentInstallment = (amount + interest) / tenor;
const balance = amount - 0;

const { email, amount, tenor } = req.body;
const interest = 0.05 * amount;
const paymentInstallment = (amount + interest) / tenor;
const balance = amount - 0;

res.status(201).json({
data: {
loanId: '',
status: 'pending',
email,
amount,
tenor,
interest,
paymentInstallment,
balance
}
});
}
],
res.status(201).json({
data: {
loanId: '',
status: 'pending',
email,
amount,
tenor,
interest,
paymentInstallment,
balance
}
});
},

approve_loan: (req, res) => {
const { id } = req.params;
Expand All @@ -96,33 +69,20 @@ const LoansController = {
res.status(200).json({ data });
},

post_repayment: [
body('amount')
.isInt()
.withMessage('Repayment amount must be a number'),

sanitizeBody('amount').toFloat(),
(req, res) => {

const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() });
}

const { id } = req.params;
const { amount } = req.body;
const repay = {
id: '',
createdOn: new Date(),
loanId: id,
amount,
};
post_repayment: (req, res) => {
const { id } = req.params;
const { amount } = req.body;
const repay = {
id: '',
createdOn: new Date(),
loanId: id,
amount,
};
// update loan balance
const loan = loans.find(loan => (loan.id === id));
loan.balance = loan.balance + amount;
res.status(201).json({ data: repay });
}
],
const loan = loans.find(loan => (loan.id === id));
loan.balance = loan.balance + amount;
res.status(201).json({ data: repay });
},
};

export default LoansController;
11 changes: 11 additions & 0 deletions middleware/validate_error_or_next.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { validationResult } from 'express-validator/check';

const validate_error_or_next = (req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() });
}
return next();
};

export default validate_error_or_next;
41 changes: 6 additions & 35 deletions middleware/validators.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { body, validationResult } from 'express-validator/check';
import { body } from 'express-validator/check';
import { sanitizeBody } from 'express-validator/filter';

// import { dev_logger } from '../utils/loggers';
import validate_error_or_next from './validate_error_or_next';

const ParamterValidators = {
emailValidator: [
Expand All @@ -10,14 +9,7 @@ const ParamterValidators = {
.withMessage('Please provide a valid email address')
.normalizeEmail(),
sanitizeBody('email').trim().escape(),

(req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() });
}
return next();
}
validate_error_or_next
],

passwordValidator: [
Expand All @@ -30,14 +22,7 @@ const ParamterValidators = {
.isAlphanumeric().withMessage('Password must be alphanumeric'),
sanitizeBody('password').trim().escape(),
sanitizeBody('confirm_password').trim().escape(),

(req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() });
}
return next();
}
validate_error_or_next
],

confirmPasswordValidator: [
Expand All @@ -50,14 +35,7 @@ const ParamterValidators = {
}
else return value;
}),

(req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() });
}
return next();
}
validate_error_or_next
],

updateProfileValidator: [
Expand All @@ -79,14 +57,7 @@ const ParamterValidators = {
sanitizeBody('phone').trim().escape(),
sanitizeBody('home').trim().escape(),
sanitizeBody('office').trim().escape(),

(req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() });
}
return next();
}
validate_error_or_next
]
};

Expand Down
38 changes: 38 additions & 0 deletions middleware/validators.loans.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { body } from 'express-validator/check';
import { sanitizeBody } from 'express-validator/filter';
import { test_logger } from '../utils/loggers';

import validate_error_or_next from './validate_error_or_next';

const LoansValidators = {
validateAmount: [
body('amount')
.isFloat({ min: 50000 })
.withMessage('Amount cannot be less than 50,000')
.isFloat({ max: 1000000 })
.withMessage('Amount cannot be greater than 1,000,000'),
sanitizeBody('amount').toFloat(),
validate_error_or_next
],

validateRepayAmount: [
body('amount')
.isFloat()
.withMessage('Repayment amount must be a number'),
sanitizeBody('amount').toFloat(),
validate_error_or_next
],

validateTenor: [
body('tenor')
.isInt({ min: 1 })
.withMessage('Tenor cannot be less than 1')
.isInt({ max: 12 })
.withMessage('Tenor cannot be greater than 12'),
sanitizeBody('tenor').toInt(),
validate_error_or_next

],
};

export default LoansValidators;
10 changes: 8 additions & 2 deletions routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import LoansController from '../controllers/LoansController';

import AuthenticationMiddleware from '../middleware/authentication';
import ParamterValidators from '../middleware/validators.js';
import LoansValidators from '../middleware/validators.loans';

const router = express.Router();

Expand Down Expand Up @@ -38,12 +39,17 @@ router.get(
'/loans?status=approved&repaid=false', LoansController.get_all_loans);
router.get(
'/loans?status=approved&repaid=true', LoansController.get_all_loans);
router.post('/loans', LoansController.create_loan);
router.post('/loans',
LoansValidators.validateAmount,
LoansValidators.validateTenor,
LoansController.create_loan);
router.patch('/loans/:id/approve', LoansController.approve_loan);
router.patch('/loans/:id/reject', LoansController.reject_loan);
router.get(
'/loans/:id/repayments', LoansController.loan_repayment_history
);
router.post('/loans/:id/repayment', LoansController.post_repayment);
router.post('/loans/:id/repayment',
LoansValidators.validateRepayAmount,
LoansController.post_repayment);

export default router;
48 changes: 22 additions & 26 deletions settings.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,34 @@
import dotenv from 'dotenv';
import { test_logger } from './utils/loggers';
import { dev_logger } from './utils/loggers';

dotenv.config();

const Settings = {
dbSettings: () => {
const activeEnvironment = process.env.NODE_ENV.trim();
const settings = {
development: {
databaseName: 'quick_credit',
dbHost: process.env.PGHOST.trim(),
dbUser: process.env.PGUSER.trim(),
dbPort: process.env.PGPORT,
dbPassword: process.env.PGPASSWORD.trim(),
},
production: {
databaseName: 'quick_credit',
dbHost: process.env.PGHOST.trim(),
dbUser: process.env.PGUSER.trim(),
dbPort: process.env.PGPORT,
dbPassword: process.env.PGPASSWORD.trim(),
},
test: {
databaseName: 'testdb',
dbHost: process.env.PGHOST.trim(),
dbUser: process.env.PGUSER.trim(),
dbPort: process.env.PGPORT,
dbPassword: process.env.PGPASSWORD.trim(),
}
let databaseName;
switch (process.env.NODE_ENV.trim()) {
case 'development':
databaseName = 'quick_credit';
break;
case 'test':
databaseName = 'testdb';
break;
case 'production':
databaseName = 'quick_credit';
break;
}

const db_settings = {
databaseName,
dbHost: process.env.PGHOST.trim(),
dbUser: process.env.PGUSER.trim(),
dbPort: process.env.PGPORT,
dbPassword: process.env.PGPASSWORD.trim(),
};
return settings[activeEnvironment];
return db_settings;
},
jwtSecret: process.env.JWT_SECRET,
};

test_logger(Settings);
dev_logger(Settings);
export default Settings;
Loading

0 comments on commit 244b638

Please sign in to comment.