Merge pull request #1055 from chaotixkilla/feat-custom-info-requests-as-manual-triggers

Add custom info request manual trigger behavior
This commit is contained in:
Rafael Taranto 2022-01-19 14:37:58 +00:00 committed by GitHub
commit d5b7b088cd
11 changed files with 167 additions and 88 deletions

View file

@ -1,3 +1,4 @@
const authentication = require('../modules/userManagement')
const queries = require('../../services/customInfoRequests')
const DataLoader = require('dataloader')
@ -21,7 +22,10 @@ const resolvers = {
insertCustomInfoRequest: (...[, { customRequest }]) => queries.addCustomInfoRequest(customRequest),
removeCustomInfoRequest: (...[, { id }]) => queries.removeCustomInfoRequest(id),
editCustomInfoRequest: (...[, { id, customRequest }]) => queries.editCustomInfoRequest(id, customRequest),
setAuthorizedCustomRequest: (...[, { customerId, infoRequestId, isAuthorized }]) => queries.setAuthorizedCustomRequest(customerId, infoRequestId, isAuthorized),
setAuthorizedCustomRequest: (...[, { customerId, infoRequestId, override }, context]) => {
const token = authentication.getToken(context)
return queries.setAuthorizedCustomRequest(customerId, infoRequestId, override, token)
},
setCustomerCustomInfoRequest: (...[, { customerId, infoRequestId, data }]) => queries.setCustomerData(customerId, infoRequestId, data)
}
}

View file

@ -32,7 +32,9 @@ const typeDef = gql`
type CustomRequestData {
customerId: ID
infoRequestId: ID
approved: Boolean
override: String
overrideAt: Date
overrideBy: ID
customerData: JSON
customInfoRequest: CustomInfoRequest
}
@ -47,7 +49,7 @@ const typeDef = gql`
insertCustomInfoRequest(customRequest: CustomRequestInput!): CustomInfoRequest @auth
removeCustomInfoRequest(id: ID!): CustomInfoRequest @auth
editCustomInfoRequest(id: ID!, customRequest: CustomRequestInput!): CustomInfoRequest @auth
setAuthorizedCustomRequest(customerId: ID!, infoRequestId: ID!, isAuthorized: Boolean!): Boolean @auth
setAuthorizedCustomRequest(customerId: ID!, infoRequestId: ID!, override: String!): Boolean @auth
setCustomerCustomInfoRequest(customerId: ID!, infoRequestId: ID!, data: JSON!): Boolean @auth
}
`

View file

@ -35,8 +35,10 @@ const getAllCustomInfoRequestsForCustomer = (customerId) => {
return db.any(sql, [customerId]).then(res => res.map(item => ({
customerId: item.customer_id,
infoRequestId: item.info_request_id,
approved: item.approved,
customerData: item.customer_data
customerData: item.customer_data,
override: item.override,
overrideAt: item.override_at,
overrideBy: item.override_by
})))
}
@ -46,8 +48,10 @@ const getCustomInfoRequestForCustomer = (customerId, infoRequestId) => {
return {
customerId: item.customer_id,
infoRequestId: item.info_request_id,
approved: item.approved,
customerData: item.customer_data
customerData: item.customer_data,
override: item.override,
overrideAt: item.override_at,
overrideBy: item.override_by
}
})
}
@ -61,8 +65,10 @@ const batchGetAllCustomInfoRequestsForCustomer = (customerIds) => {
return items.map(item => ({
customerId: item.customer_id,
infoRequestId: item.info_request_id,
approved: item.approved,
customerData: item.customer_data
customerData: item.customer_data,
override: item.override,
overrideAt: item.override_at,
overrideBy: item.override_by
}))
})
})
@ -93,9 +99,9 @@ const batchGetCustomInfoRequest = (infoRequestIds) => {
})
}
const setAuthorizedCustomRequest = (customerId, infoRequestId, isAuthorized) => {
const sql = `UPDATE customers_custom_info_requests SET approved = $1 WHERE customer_id = $2 AND info_request_id = $3`
return db.none(sql, [isAuthorized, customerId, infoRequestId]).then(() => true)
const setAuthorizedCustomRequest = (customerId, infoRequestId, override, token) => {
const sql = `UPDATE customers_custom_info_requests SET override = $1, override_by = $2, override_at = now() WHERE customer_id = $3 AND info_request_id = $4`
return db.none(sql, [override, token, customerId, infoRequestId]).then(() => true)
}
const setCustomerData = (customerId, infoRequestId, data) => {
@ -103,7 +109,7 @@ const setCustomerData = (customerId, infoRequestId, data) => {
INSERT INTO customers_custom_info_requests (customer_id, info_request_id, customer_data)
VALUES ($1, $2, $3)
ON CONFLICT (customer_id, info_request_id)
DO UPDATE SET customer_data = $3, approved = null`
DO UPDATE SET customer_data = $3`
return db.none(sql, [customerId, infoRequestId, data])
}

View file

@ -1,4 +1,5 @@
const _ = require('lodash/fp')
const { getCustomInfoRequests } = require('./new-admin/services/customInfoRequests')
const namespaces = {
WALLETS: 'wallets',
@ -107,6 +108,8 @@ const getGlobalNotifications = config => getNotifications(null, null, config)
const getTriggers = _.get('triggers')
const getTriggersAutomation = config => {
return getCustomInfoRequests(true)
.then(infoRequests => {
const defaultAutomation = _.get('triggersConfig_automation')(config)
const requirements = {
sanctions: defaultAutomation,
@ -116,6 +119,10 @@ const getTriggersAutomation = config => {
usSsn: defaultAutomation
}
_.forEach(it => {
requirements[it.id] = defaultAutomation
}, infoRequests)
const overrides = _.get('triggersConfig_overrides')(config)
const requirementsOverrides = _.reduce((acc, override) => {
@ -123,6 +130,7 @@ const getTriggersAutomation = config => {
}, {}, overrides)
return _.assign(requirements, requirementsOverrides)
})
}
const splitGetFirst = _.compose(_.head, _.split('_'))

View file

@ -73,7 +73,7 @@ function poll (req, res, next) {
const pi = plugins(settings, deviceId)
const hasLightning = checkHasLightning(settings)
const triggersAutomation = configManager.getTriggersAutomation(settings.config)
const triggersAutomationPromise = configManager.getTriggersAutomation(settings.config)
const triggersPromise = buildTriggers(configManager.getTriggers(settings.config))
const operatorInfo = configManager.getOperatorInfo(settings.config)
@ -84,8 +84,8 @@ function poll (req, res, next) {
state.pids[operatorId] = { [deviceId]: { pid, ts: Date.now() } }
return Promise.all([pi.pollQueries(serialNumber, deviceTime, req.query, machineVersion, machineModel), triggersPromise])
.then(([results, triggers]) => {
return Promise.all([pi.pollQueries(serialNumber, deviceTime, req.query, machineVersion, machineModel), triggersPromise, triggersAutomationPromise])
.then(([results, triggers, triggersAutomation]) => {
const cassettes = results.cassettes
const reboot = pid && state.reboots?.[operatorId]?.[deviceId] === pid

View file

@ -0,0 +1,16 @@
var db = require('./db')
exports.up = function (next) {
var sql = [
`ALTER TABLE customers_custom_info_requests DROP COLUMN approved`,
`ALTER TABLE customers_custom_info_requests ADD COLUMN override verification_type NOT NULL DEFAULT 'automatic'`,
`ALTER TABLE customers_custom_info_requests ADD COLUMN override_by UUID REFERENCES users(id)`,
`ALTER TABLE customers_custom_info_requests ADD COLUMN override_at TIMESTAMPTZ`
]
db.multi(sql, next)
}
exports.down = function (next) {
next()
}

View file

@ -241,7 +241,6 @@ const CustomerData = ({
]
R.forEach(it => {
console.log('it', it)
customRequirements.push({
fields: [
{
@ -253,12 +252,13 @@ const CustomerData = ({
],
title: it.customInfoRequest.customRequest.name,
titleIcon: <CardIcon className={classes.cardIcon} />,
state: R.path(['override'])(it),
authorize: () =>
authorizeCustomRequest({
variables: {
customerId: it.customerId,
infoRequestId: it.customInfoRequest.id,
isAuthorized: true
override: OVERRIDE_AUTHORIZED
}
}),
reject: () =>
@ -266,7 +266,7 @@ const CustomerData = ({
variables: {
customerId: it.customerId,
infoRequestId: it.customInfoRequest.id,
isAuthorized: false
override: OVERRIDE_REJECTED
}
}),
save: values => {

View file

@ -98,7 +98,9 @@ const GET_CUSTOMER = gql`
}
customInfoRequests {
customerId
approved
override
overrideBy
overrideAt
customerData
customInfoRequest {
id
@ -183,12 +185,12 @@ const SET_AUTHORIZED_REQUEST = gql`
mutation setAuthorizedCustomRequest(
$customerId: ID!
$infoRequestId: ID!
$isAuthorized: Boolean!
$override: String!
) {
setAuthorizedCustomRequest(
customerId: $customerId
infoRequestId: $infoRequestId
isAuthorized: $isAuthorized
override: $override
)
}
`

View file

@ -53,12 +53,12 @@ const SET_AUTHORIZED_REQUEST = gql`
mutation setAuthorizedCustomRequest(
$customerId: ID!
$infoRequestId: ID!
$isAuthorized: Boolean!
$override: String!
) {
setAuthorizedCustomRequest(
customerId: $customerId
infoRequestId: $infoRequestId
isAuthorized: $isAuthorized
override: $override
)
}
`

View file

@ -28,13 +28,34 @@ const GET_INFO = gql`
}
`
const GET_CUSTOM_REQUESTS = gql`
query customInfoRequests {
customInfoRequests {
id
customRequest
enabled
}
}
`
const AdvancedTriggersSettings = memo(() => {
const SCREEN_KEY = namespaces.TRIGGERS
const [error, setError] = useState(null)
const [isEditingDefault, setEditingDefault] = useState(false)
const [isEditingOverrides, setEditingOverrides] = useState(false)
const { data } = useQuery(GET_INFO)
const { data, loading: configLoading } = useQuery(GET_INFO)
const { data: customInfoReqData, loading: customInfoLoading } = useQuery(
GET_CUSTOM_REQUESTS
)
const customInfoRequests =
R.path(['customInfoRequests'])(customInfoReqData) ?? []
const enabledCustomInfoRequests = R.filter(R.propEq('enabled', true))(
customInfoRequests
)
const loading = configLoading || customInfoLoading
const [saveConfig] = useMutation(SAVE_CONFIG, {
refetchQueries: () => ['getData'],
@ -67,6 +88,7 @@ const AdvancedTriggersSettings = memo(() => {
const onEditingOverrides = (it, editing) => setEditingOverrides(editing)
return (
!loading && (
<>
<Section>
<EditableTable
@ -95,15 +117,19 @@ const AdvancedTriggersSettings = memo(() => {
enableCreate
initialValues={overridesDefaults}
save={saveOverrides}
validationSchema={getOverridesSchema(requirementsOverrides)}
validationSchema={getOverridesSchema(
requirementsOverrides,
enabledCustomInfoRequests
)}
data={requirementsOverrides}
elements={getOverrides()}
elements={getOverrides(enabledCustomInfoRequests)}
setEditing={onEditingOverrides}
forceDisable={isEditingDefault}
/>
</Section>
</>
)
)
})
export default AdvancedTriggersSettings

View file

@ -4,18 +4,29 @@ import * as Yup from 'yup'
import Autocomplete from 'src/components/inputs/formik/Autocomplete.js'
import { getView } from 'src/pages/Triggers/helper'
const advancedRequirementOptions = [
const buildAdvancedRequirementOptions = customInfoRequests => {
const base = [
{ display: 'Sanctions', code: 'sanctions' },
{ display: 'ID card image', code: 'idCardPhoto' },
{ display: 'ID data', code: 'idCardData' },
{ display: 'Customer camera', code: 'facephoto' },
{ display: 'US SSN', code: 'usSsn' }
]
]
const displayRequirement = code => {
const custom = R.map(it => ({
display: it.customRequest.name,
code: it.id
}))(customInfoRequests)
return R.concat(base, custom)
}
const displayRequirement = (code, customInfoRequests) => {
return R.prop(
'display',
R.find(R.propEq('code', code))(advancedRequirementOptions)
R.find(R.propEq('code', code))(
buildAdvancedRequirementOptions(customInfoRequests)
)
)
}
@ -29,7 +40,7 @@ const defaultSchema = Yup.object().shape({
.required()
})
const getOverridesSchema = values => {
const getOverridesSchema = (values, customInfoRequests) => {
return Yup.object().shape({
id: Yup.string()
.label('Requirement')
@ -40,7 +51,8 @@ const getOverridesSchema = values => {
if (R.find(R.propEq('requirement', requirement))(values)) {
return this.createError({
message: `Requirement ${displayRequirement(
requirement
requirement,
customInfoRequests
)} already overriden`
})
}
@ -84,17 +96,20 @@ const getDefaultSettings = () => {
]
}
const getOverrides = () => {
const getOverrides = customInfoRequests => {
return [
{
name: 'requirement',
header: 'Requirement',
width: 196,
size: 'sm',
view: getView(advancedRequirementOptions, 'display'),
view: getView(
buildAdvancedRequirementOptions(customInfoRequests),
'display'
),
input: Autocomplete,
inputProps: {
options: advancedRequirementOptions,
options: buildAdvancedRequirementOptions(customInfoRequests),
labelProp: 'display',
valueProp: 'code'
}