Refactor customers API

* Use lodash camelize
* Modify enhanceOverrideFields (fp)
* Fix for sql timestamp
* Fetch all existing users at once in populateOverrideUsernames
* Modify populateOverrideUsernames (fp)
* Break format function into computeStatus, camelize
This commit is contained in:
goga-m 2017-10-02 16:44:33 +03:00 committed by Josh Harvey
parent e907f8a70a
commit c77bb53f8f
2 changed files with 65 additions and 34 deletions

View file

@ -1,14 +1,16 @@
const db = require('./db')
const uuid = require('uuid') const uuid = require('uuid')
const Pgp = require('pg-promise')()
const _ = require('lodash/fp') const _ = require('lodash/fp')
const db = require('./db')
const BN = require('./bn') const BN = require('./bn')
const anonymous = require('../lib/constants').anonymousCustomer const anonymous = require('../lib/constants').anonymousCustomer
const NUM_RESULTS = 20 const camelize = _.mapKeys(_.camelCase)
const camelize = require('camelize')
const Pgp = require('pg-promise')()
const complianceOverrides = require('./compliance_overrides') const complianceOverrides = require('./compliance_overrides')
const users = require('./users') const users = require('./users')
const NUM_RESULTS = 20
function add (customer) { function add (customer) {
const sql = 'insert into customers (id, phone, phone_at) values ($1, $2, now()) returning *' const sql = 'insert into customers (id, phone, phone_at) values ($1, $2, now()) returning *'
return db.one(sql, [uuid.v4(), customer.phone]) return db.one(sql, [uuid.v4(), customer.phone])
@ -44,13 +46,17 @@ function update (id, data, userToken) {
' where id=$1 returning *' ' where id=$1 returning *'
return db.one(sql, [id]) return db.one(sql, [id])
.then(addComplianceOverrides(id, updateData, userToken)) .then(addComplianceOverrides(id, updateData, userToken))
.then(format) .then(populateOverrideUsernames)
.then(computeStatus)
.then(camelize)
} }
function getById (id, userToken) { function getById (id, userToken) {
const sql = 'select * from customers where id=$1' const sql = 'select * from customers where id=$1'
return db.oneOrNone(sql, [id]) return db.oneOrNone(sql, [id])
.then(format) .then(populateOverrideUsernames)
.then(computeStatus)
.then(camelize)
} }
function getDailyVolume (id) { function getDailyVolume (id) {
@ -97,15 +103,15 @@ function getComplianceTypes () {
* @returns {object} fields enhanced with *_by and *_at fields * @returns {object} fields enhanced with *_by and *_at fields
*/ */
function enhanceOverrideFields (fields, userToken) { function enhanceOverrideFields (fields, userToken) {
if (!userToken) return fields if (!userToken) return _.extend(fields, {})
// Populate with computedFields (user who overrode and overriden timestamps date) // Populate with computedFields (user who overrode and overriden timestamps date)
_.each(field => { return _.reduce(_.assign, {}, _.map((type) => {
if (fields[field + '_override']) { return (fields[type + '_override']) ? {
fields[field + '_override_by'] = userToken [type + '_override']: fields[type + '_override'],
fields[field + '_override_at'] = new Date().toISOString() [type + '_override_by']: userToken,
} [type + '_override_at']: 'now()^'
}, getComplianceTypes()) } : {}
return fields }, getComplianceTypes()))
} }
/** /**
@ -137,19 +143,22 @@ function addComplianceOverrides (id, customer, userToken) {
// Save all the updated override fields // Save all the updated override fields
return Promise.all(_.map(complianceOverrides.add, _.compact(overrides))) return Promise.all(_.map(complianceOverrides.add, _.compact(overrides)))
.then(() => customer)
} }
/** /**
* Format and populate fields * Compute status field
* for customer record
* *
* @name format * Status field indicates the last
* compliance user has verified
*
* @name computeStatus
* @function * @function
* *
* @param {object} Customer object * @param {object} Customer object
* @returns {object} Customer camelized & populated with computed fields * @returns {object} Customer populated with status field
*/ */
function format (customer) { function computeStatus (customer) {
if (!customer) return null if (!customer) return null
/** /**
* Populate with status field * Populate with status field
@ -168,14 +177,15 @@ function format (customer) {
label: 'ID card image', label: 'ID card image',
value: customer.id_card_image_at value: customer.id_card_image_at
}]) }])
customer.status = status.label
return populateOverrideUsernames(customer) return _.extend(customer, {
.then(camelize) status: status.label
})
} }
/** /**
* Populate the customer object with user names * Populate the customer object with user names
* for override fields * for override fields ( fields ending with _override_by )
* *
* @name populateOverrideUsernames * @name populateOverrideUsernames
* @function * @function
@ -184,15 +194,24 @@ function format (customer) {
* @returns {promise} Customer with populated *by_name fields * @returns {promise} Customer with populated *by_name fields
*/ */
function populateOverrideUsernames (customer) { function populateOverrideUsernames (customer) {
return Promise.all(_.map(field => { const fieldsToUpdate = _.map(field => {
return users.get(customer[field + '_override_by']) return {
.then(user => { token: customer[field + '_override_by'],
// just add the name to the customer object field: field + '_override_by_name'
customer[field + '_override_by_name'] = (user) ? user.name : null }
return null }, getComplianceTypes())
}) const queryTokens = _.map('token', fieldsToUpdate)
}, getComplianceTypes()))
.then(() => customer) return users.getByIds(queryTokens)
.then(usersList => {
return _.map(userField => {
const user = _.find({token: userField.token}, usersList)
return {
[userField.field]: user ? user.name : null
}
}, fieldsToUpdate)
})
.then(_.reduce(_.extend, customer))
} }
/** /**
@ -209,7 +228,11 @@ function batch () {
where id != $1 where id != $1
order by created desc limit $2` order by created desc limit $2`
return db.any(sql, [ anonymous.uuid, NUM_RESULTS ]) return db.any(sql, [ anonymous.uuid, NUM_RESULTS ])
.then(customers => Promise.all(_.map(format, customers))) .then(customers => Promise.all(_.map(customer => {
return populateOverrideUsernames(customer)
.then(computeStatus)
.then(camelize)
}, customers)))
} }
module.exports = { add, get, batch, getById, update } module.exports = { add, get, batch, getById, update }

View file

@ -1,3 +1,6 @@
const _ = require('lodash/fp')
const pgp = require('pg-promise')()
const db = require('./db') const db = require('./db')
function get (token) { function get (token) {
@ -5,4 +8,9 @@ function get (token) {
return db.oneOrNone(sql, [token]) return db.oneOrNone(sql, [token])
} }
module.exports = { get } function getByIds (tokens) {
const sql = 'select * from user_tokens where token in ($1^)'
const tokensClause = _.map(pgp.as.text, tokens).join(',')
return db.any(sql, [tokensClause])
}
module.exports = { get, getByIds }