Skip to content

Commit

Permalink
bal 1776 fix transaction type based rule (#2251)
Browse files Browse the repository at this point in the history
  • Loading branch information
liorzam committed Mar 27, 2024
1 parent 28906c9 commit 30323c6
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 14 deletions.
23 changes: 17 additions & 6 deletions services/workflows-service/src/alert/alert.service.intg.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,19 +260,33 @@ describe('AlertService', () => {

it('When the sum of refunds amount is greater than 5000, an alert should be created', async () => {
// Arrange
const business1Transactions = await baseTransactionFactory.amount(100).count(51).create({
const business1Transactions = await baseTransactionFactory.amount(1000).count(11).create({
transactionType: TransactionRecordType.refund,
});
const business2Transactions = await baseTransactionFactory.amount(100).count(49).create({

await baseTransactionFactory.amount(10).count(12).create({
transactionType: TransactionRecordType.refund,
});

await baseTransactionFactory.amount(5001).count(13).create({
transactionType: TransactionRecordType.chargeback,
});

// Act
await alertService.checkAllAlerts();

// Assert
const alerts = await prismaService.alert.findMany();
expect(alerts).toHaveLength(1);

expect(alerts[0] as any).toMatchObject({
executionDetails: { executionRow: { transactionCount: '11' } },
});

expect(alerts[0] as any).toMatchObject({
executionDetails: { executionRow: { totalAmount: 1000 * 11 } },
});

expect(alerts[0]?.alertDefinitionId).toEqual(alertDefinition.id);
expect(alerts[0]?.counterpartyId).toEqual(
business1Transactions[0]?.counterpartyOriginatorId,
Expand All @@ -281,10 +295,7 @@ describe('AlertService', () => {

it('When the sum of refunds amount is less than 5000, no alert should be created', async () => {
// Arrange
const business1Transactions = await baseTransactionFactory.amount(100).count(49).create({
transactionType: TransactionRecordType.refund,
});
const business2Transactions = await baseTransactionFactory.amount(100).count(49).create({
await baseTransactionFactory.amount(100).count(49).create({
transactionType: TransactionRecordType.refund,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
import { AggregateType } from './consts';
import { Prisma } from '@prisma/client';
import { AppLoggerService } from '@/common/app-logger/app-logger.service';
import { isEmpty } from 'lodash';

@Injectable()
export class DataAnalyticsService {
Expand Down Expand Up @@ -54,6 +55,7 @@ export class DataAnalyticsService {
amountThreshold,
amountBetween,
direction,
transactionType = [],
excludedCounterparty = {
counterpartyBeneficiaryIds: [],
counterpartyOriginatorIds: [],
Expand All @@ -80,6 +82,12 @@ export class DataAnalyticsService {
)}'`,
];

if (!isEmpty(transactionType)) {
conditions.push(
Prisma.sql`tr."transactionType"::text IN (${Prisma.join(transactionType, ',')})`,
);
}

if (direction) {
conditions.push(Prisma.sql`"transactionDirection"::text = ${direction}`);
}
Expand Down Expand Up @@ -154,8 +162,7 @@ export class DataAnalyticsService {
break;
case AggregateType.SUM:
havingClause = `${AggregateType.SUM}(tr."transactionBaseAmount")`;
query = Prisma.sql`SELECT ${selectClause}, SUM(tr."transactionBaseAmount") AS "totalAmount", COUNT(id) AS "transactionCount" FROM "TransactionRecord" tr
WHERE ${whereClause} GROUP BY ${groupByClause} HAVING ${Prisma.raw(
query = Prisma.sql`SELECT ${selectClause}, SUM(tr."transactionBaseAmount") AS "totalAmount", COUNT(id) AS "transactionCount" FROM "TransactionRecord" tr WHERE ${whereClause} GROUP BY ${groupByClause} HAVING ${Prisma.raw(
havingClause,
)} > ${amountThreshold}`;
break;
Expand Down Expand Up @@ -274,10 +281,7 @@ export class DataAnalyticsService {
Prisma.sql`tr."projectId" = '${projectId}'`,
Prisma.sql`tr."businessId" IS NOT NULL`,
// TODO: should we use equation instead of IN clause?
Prisma.sql`tr."transactionType" IN (${Prisma.join(
transactionType.map(type => `'${type}'::"TransactionRecordType"`),
',',
)})`,
Prisma.sql`tr."transactionType"::text IN (${Prisma.join(transactionType, ',')})`,
Prisma.sql`"transactionDate" >= CURRENT_DATE - INTERVAL '${Prisma.raw(
`${timeAmount} ${timeUnit}`,
)}'`,
Expand Down
1 change: 1 addition & 0 deletions services/workflows-service/src/data-analytics/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export type TransactionsAgainstDynamicRulesType = {
havingAggregate?: TAggregations;
amountBetween?: { min: number; max: number };
timeAmount?: number;
transactionType?: TransactionRecordType[];
timeUnit?: 'minutes' | 'hours' | 'days' | 'weeks' | 'months' | 'years';
direction?: TransactionDirection;
excludedCounterparty?: TExcludedCounterparty;
Expand Down
16 changes: 14 additions & 2 deletions services/workflows-service/src/test/db-setup.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
import { PostgreSqlContainer } from 'testcontainers';

import console from 'console';
import { TestGlobal } from '@/test/test-global';
import { execSync } from 'child_process';

const DATABASE_NAME = 'test';

module.exports = async () => {
if (process.env.SKIP_DB_SETUP_TEARDOWN) return;

const container = await new PostgreSqlContainer('sibedge/postgres-plv8:15.3-3.1.7')
.withDatabase('test')
.withDatabase(DATABASE_NAME)
.withExposedPorts({ host: 5444, container: 5432 })
.withHealthCheck({
test: ['CMD', 'pg_isready -d test_postgress -U test_user -p 5432'],
interval: 10000, // 10 seconds
startPeriod: 5000, // 5 seconds
retries: 5,
})
.start();

process.env.TEST_DATABASE_SCHEMA_NAME = container.getDatabase();
process.env.DB_URL = container.getConnectionUri();
console.log('\nStarting database container on: ' + container.getConnectionUri());

console.log('\nStarting database container on: ' + process.env.DB_URL);

runPrismaMigrations();

Expand Down

0 comments on commit 30323c6

Please sign in to comment.