feat: Customer transactions fetching with dataloader library

This commit is contained in:
Cesar 2020-12-01 14:32:21 +00:00 committed by Josh Harvey
parent d5f3763e91
commit 0ec49159e4
4 changed files with 65 additions and 3 deletions

View file

@ -3,6 +3,7 @@ const { parseAsync } = require('json2csv')
const { GraphQLDateTime } = require('graphql-iso-date') const { GraphQLDateTime } = require('graphql-iso-date')
const { GraphQLJSON, GraphQLJSONObject } = require('graphql-type-json') const { GraphQLJSON, GraphQLJSONObject } = require('graphql-type-json')
const got = require('got') const got = require('got')
const DataLoader = require('dataloader')
const machineLoader = require('../../machine-loader') const machineLoader = require('../../machine-loader')
const customers = require('../../customers') const customers = require('../../customers')
@ -265,6 +266,8 @@ const typeDefs = gql`
} }
` `
const transactionsLoader = new DataLoader(ids => transactions.getCustomerTransactionsBatch(ids))
const notify = () => got.post('http://localhost:3030/dbChange') const notify = () => got.post('http://localhost:3030/dbChange')
.catch(e => console.error('Error: lamassu-server not responding')) .catch(e => console.error('Error: lamassu-server not responding'))
@ -273,7 +276,7 @@ const resolvers = {
JSONObject: GraphQLJSONObject, JSONObject: GraphQLJSONObject,
Date: GraphQLDateTime, Date: GraphQLDateTime,
Customer: { Customer: {
transactions: parent => transactions.getCustomerTransactions(parent.id) transactions: parent => transactionsLoader.load(parent.id)
}, },
Query: { Query: {
countries: () => countries, countries: () => countries,

View file

@ -67,7 +67,6 @@ function batch (from = new Date(0).toISOString(), until = new Date().toISOString
function getCustomerTransactions (customerId) { function getCustomerTransactions (customerId) {
const packager = _.flow(it => { const packager = _.flow(it => {
console.log()
return it return it
}, _.flatten, _.orderBy(_.property('created'), ['desc']), _.map(camelize), addNames) }, _.flatten, _.orderBy(_.property('created'), ['desc']), _.map(camelize), addNames)
@ -110,6 +109,60 @@ function getCustomerTransactions (customerId) {
.then(packager) .then(packager)
} }
async function getCustomerTransactionsBatch(ids) {
const packager = _.flow(it => {
return it
}, _.flatten, _.orderBy(_.property('created'), ['desc']), _.map(camelize), addNames)
const cashInSql = `select 'cashIn' as tx_class, txs.*,
c.phone as customer_phone,
c.id_card_data_number as customer_id_card_data_number,
c.id_card_data_expiration as customer_id_card_data_expiration,
c.id_card_data as customer_id_card_data,
c.name as customer_name,
c.front_camera_path as customer_front_camera_path,
c.id_card_photo_path as customer_id_card_photo_path,
((not txs.send_confirmed) and (txs.created <= now() - interval $2)) as expired
from cash_in_txs as txs
left outer join customers c on txs.customer_id = c.id
where c.id::text LIKE ANY($1)
order by created desc limit $3`
const cashOutSql = `select 'cashOut' as tx_class,
txs.*,
actions.tx_hash,
c.phone as customer_phone,
c.id_card_data_number as customer_id_card_data_number,
c.id_card_data_expiration as customer_id_card_data_expiration,
c.id_card_data as customer_id_card_data,
c.name as customer_name,
c.front_camera_path as customer_front_camera_path,
c.id_card_photo_path as customer_id_card_photo_path,
(extract(epoch from (now() - greatest(txs.created, txs.confirmed_at))) * 1000) >= $3 as expired
from cash_out_txs txs
inner join cash_out_actions actions on txs.id = actions.tx_id
and actions.action = 'provisionAddress'
left outer join customers c on txs.customer_id = c.id
where c.id::text LIKE ANY ($1)
order by created desc limit $2`
const cashIns = await db.any(cashInSql, [ids, cashInTx.PENDING_INTERVAL, NUM_RESULTS])
const cashOuts = await db.any(cashOutSql, [ids, NUM_RESULTS, REDEEMABLE_AGE])
const transactions = await packager([...cashIns, ...cashOuts])
const transactionMap = {}
transactions.forEach(transaction => {
if(!transactionMap[transaction.customerId]) {
transactionMap[transaction.customerId] = [transaction]
}
else {
transactionMap[transaction.customerId].push(transaction)
}
})
return ids.map(id => transactionMap[id])
}
function single (txId) { function single (txId) {
const packager = _.flow(_.compact, _.map(camelize), addNames) const packager = _.flow(_.compact, _.map(camelize), addNames)
@ -156,4 +209,4 @@ function cancel (txId) {
.then(() => single(txId)) .then(() => single(txId))
} }
module.exports = { batch, getCustomerTransactions, single, cancel } module.exports = { batch, getCustomerTransactions, single, cancel, getCustomerTransactionsBatch }

5
package-lock.json generated
View file

@ -3390,6 +3390,11 @@
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz",
"integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==" "integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ=="
}, },
"dataloader": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dataloader/-/dataloader-2.0.0.tgz",
"integrity": "sha512-YzhyDAwA4TaQIhM5go+vCLmU0UikghC/t9DTQYZR2M/UvZ1MdOhPezSDZcjj9uqQJOMqjLcpWtyW2iNINdlatQ=="
},
"date-fns": { "date-fns": {
"version": "2.16.1", "version": "2.16.1",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.16.1.tgz", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.16.1.tgz",

View file

@ -23,6 +23,7 @@
"console-log-level": "^1.4.0", "console-log-level": "^1.4.0",
"cookie-parser": "^1.4.3", "cookie-parser": "^1.4.3",
"cors": "^2.8.5", "cors": "^2.8.5",
"dataloader": "^2.0.0",
"ethereumjs-tx": "^1.3.3", "ethereumjs-tx": "^1.3.3",
"ethereumjs-util": "^5.2.0", "ethereumjs-util": "^5.2.0",
"ethereumjs-wallet": "^0.6.3", "ethereumjs-wallet": "^0.6.3",