Skip to content

Commit fb5ae73

Browse files
feat(posthog): send events for workflow runtime data changes to posth… (#3258)
1 parent 202c2da commit fb5ae73

File tree

15 files changed

+151
-60
lines changed

15 files changed

+151
-60
lines changed

apps/kyb-app/src/pages/CollectionFlow/versions/v2/components/organisms/CollectionFlowUI/CollectionFlowUI.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,8 @@ export const CollectionFlowUI: FunctionComponent<ICollectionFlowUIProps> = ({
218218

219219
if (isLoadingRevisionFields) {
220220
return (
221-
<div className="flex items-center justify-center min-h-[200px]">
222-
<div className="animate-spin rounded-full h-12 w-12 border-4 border-primary border-t-transparent" />
221+
<div className="flex min-h-[200px] items-center justify-center">
222+
<div className="border-primary h-12 w-12 animate-spin rounded-full border-4 border-t-transparent" />
223223
</div>
224224
);
225225
}

renovate.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
{
22
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
3-
"extends": [
4-
"config:recommended"
5-
]
3+
"extends": ["config:recommended"]
64
}

services/workflows-service/src/auth/workflow-token/workflow-token.service.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,16 @@ export class WorkflowTokenService {
4242
);
4343

4444
let collectionFlow;
45-
try {
46-
const [uiDefinition, customer] = await Promise.all([
47-
this.uiDefinitionService.getByWorkflowDefinitionId(
48-
workflowDefinitionId,
49-
UiDefinitionContext.collection_flow,
50-
[projectId],
51-
),
52-
this.customerService.getByProjectId(projectId),
53-
]);
45+
const [uiDefinition, customer] = await Promise.all([
46+
this.uiDefinitionService.getByWorkflowDefinitionId(
47+
workflowDefinitionId,
48+
UiDefinitionContext.collection_flow,
49+
[projectId],
50+
),
51+
this.customerService.getByProjectId(projectId),
52+
]);
5453

54+
try {
5555
collectionFlow = buildCollectionFlowState({
5656
apiUrl: env.APP_API_URL,
5757
steps: uiDefinition?.definition
@@ -80,6 +80,7 @@ export class WorkflowTokenService {
8080
}
8181

8282
await this.workflowRuntimeDataRepository.updateStateById(
83+
customer,
8384
workflowRuntimeDataId,
8485
{
8586
data: {

services/workflows-service/src/collection-flow/controllers/collection-flow.no-user.controller.intg.test.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { INestApplication } from '@nestjs/common';
22
import { EventEmitter2 } from '@nestjs/event-emitter';
33
import { Test, TestingModule } from '@nestjs/testing';
4-
import { Project, WorkflowRuntimeDataToken } from '@prisma/client';
4+
import { Customer, Project, WorkflowRuntimeDataToken } from '@prisma/client';
55
import { noop } from 'lodash';
66
import request from 'supertest';
77
import { ClsModule } from 'nestjs-cls';
@@ -50,8 +50,6 @@ import { CollectionFlowStateService } from '../services/collection-flow-state.se
5050
import { AssessmentsService } from '@/assessments/assessments.service';
5151
import { UnifiedApiClient } from '@/common/utils/unified-api-client/unified-api-client';
5252
import { KycService } from '@/kyc/kyc.service';
53-
import { HttpService } from '@nestjs/axios';
54-
import { ConfigService } from '@nestjs/config';
5553

5654
describe('CollectionFlowSignupController', () => {
5755
let app: INestApplication;
@@ -65,6 +63,7 @@ describe('CollectionFlowSignupController', () => {
6563

6664
let project: Project;
6765
let workflowRuntimeDataToken: WorkflowRuntimeDataToken;
66+
let customer: Customer;
6867

6968
beforeAll(async () => {
7069
const module: TestingModule = await Test.createTestingModule({
@@ -83,7 +82,7 @@ describe('CollectionFlowSignupController', () => {
8382
{ provide: UserService, useValue: noop },
8483
{ provide: EventEmitter2, useValue: noop },
8584
{ provide: AppLoggerService, useValue: { log: noop } },
86-
{ provide: AnalyticsService, useValue: { log: noop } },
85+
{ provide: AnalyticsService, useValue: { trackSafe: noop } },
8786
{ provide: WorkflowEventEmitterService, useValue: { emit: noop } },
8887
WorkflowService,
8988
EndUserService,
@@ -134,7 +133,7 @@ describe('CollectionFlowSignupController', () => {
134133
beforeEach(async () => {
135134
await cleanupDatabase();
136135

137-
const customer = await customerRepository.create({
136+
customer = await customerRepository.create({
138137
data: {
139138
name: 'signup-test-customer',
140139
displayName: 'Signup Test Customer',
@@ -163,7 +162,7 @@ describe('CollectionFlowSignupController', () => {
163162
},
164163
});
165164

166-
const { id: workflowRuntimeDataId } = await workflowRuntimeDataRepository.create({
165+
const { id: workflowRuntimeDataId } = await workflowRuntimeDataRepository.create(customer, {
167166
data: {
168167
workflowDefinitionId: workflowDefinition.id,
169168
projectId: project.id,

services/workflows-service/src/collection-flow/services/collection-flow.service.intg.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ const deps: Provider[] = [
5656
},
5757
{
5858
provide: AnalyticsService,
59-
useValue: noop,
59+
useValue: { trackSafe: noop },
6060
},
6161
{
6262
provide: EndUserService,
@@ -246,7 +246,7 @@ describe('CollectionFlowService', () => {
246246
},
247247
});
248248

249-
const workflowRuntimeData = await workflowRuntimeDataRepository.create({
249+
const workflowRuntimeData = await workflowRuntimeDataRepository.create(customer, {
250250
data: {
251251
workflowDefinitionId: workflowDefinition.id,
252252
workflowDefinitionVersion: workflowDefinition.version,

services/workflows-service/src/collection-flow/services/collection-flow.service.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,12 +229,12 @@ export class CollectionFlowService {
229229
}
230230

231231
async createEntitiesIfNeeded(
232-
entities: {
232+
entities: Array<{
233233
firstName: string;
234234
lastName: string;
235235
email: string;
236236
ballerineEntityId?: string;
237-
}[],
237+
}>,
238238
projectId: string,
239239
transaction: Prisma.TransactionClient,
240240
) {

services/workflows-service/src/common/analytics-logger/analytics.service.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export const EventNamesMap = {
1212
CUSTOMER_CREATED: 'customer.created',
1313
USER_CREATED: 'user.created',
1414
BUSINESS_REPORT_REQUESTED: 'business_report.requested',
15+
CASE_CHANGED: 'case.changed',
1516
} as const;
1617

1718
type AnalyticsEvents = {
@@ -26,6 +27,14 @@ type AnalyticsEvents = {
2627
businessId: string;
2728
customerId: string;
2829
};
30+
[EventNamesMap.CASE_CHANGED]: {
31+
workflowRuntimeDataId: string;
32+
endUserId: string | null;
33+
businessId: string | null;
34+
projectId: string;
35+
actorUserId: string | null;
36+
actorEndUserId: string | null;
37+
};
2938
};
3039

3140
type TrackParams<Event extends keyof AnalyticsEvents> = {

services/workflows-service/src/common/utils/idv/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,14 +130,14 @@ export const handleIndividualVerificationDocuments = async ({
130130
kycDocumentImages: Array<{ context?: string; content: string }>;
131131
person: Pick<TIndividualVerificationData['person'], 'idNumber'>;
132132
}) => {
133-
const documentPages: {
133+
const documentPages: Array<{
134134
uri: string;
135135
provider: string;
136136
type: string | undefined;
137137
metadata: {
138138
side: string | undefined;
139139
};
140-
}[] = [];
140+
}> = [];
141141

142142
for (const kycDocumentImage of kycDocumentImages) {
143143
const tmpFile = tmp.fileSync({ keep: false }).name;

services/workflows-service/src/common/utils/parse-csv/parse-csv.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,12 @@ export const parseCsv = async <TSchema extends ZodSchema>(
2323
fileContent = fs.readFileSync(processEntity.filePath);
2424
filenameWithExtension = processEntity.filePath;
2525
}
26+
2627
const isCsv = filenameWithExtension.toLowerCase().endsWith('.csv');
2728

2829
return new Promise((resolve, reject) => {
2930
const results: z.output<TSchema> = [];
30-
const errors: { message: string }[] = [];
31+
const errors: Array<{ message: string }> = [];
3132

3233
if (!isCsv) {
3334
errors.push({
@@ -67,9 +68,11 @@ export const parseCsv = async <TSchema extends ZodSchema>(
6768
results.push(validatedRecord);
6869
} catch (error) {
6970
const lineNumber = index + 2;
71+
7072
if (!(error instanceof ZodError)) {
7173
throw error;
7274
}
75+
7376
logger.error('Validation error:', { error, record });
7477
const rowErrors = error.errors.map(zodIssue => ({
7578
message: `Line ${lineNumber} - ${zodIssue.message}`,

services/workflows-service/src/user/user.controller.internal.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ export class UserControllerInternal {
116116
try {
117117
// Check if user exists
118118
const existingUser = await this.userService.getByIdUnscoped(id, {});
119+
119120
if (!existingUser) {
120121
throw new NotFoundException(`User with ID ${id} not found`);
121122
}
@@ -141,6 +142,7 @@ export class UserControllerInternal {
141142
if (error instanceof NotFoundException) {
142143
throw error;
143144
}
145+
144146
throw new BadRequestException('Failed to update user');
145147
}
146148
}
@@ -155,6 +157,7 @@ export class UserControllerInternal {
155157
try {
156158
// Check if user exists
157159
const existingUser = await this.userService.getByIdUnscoped(id, {});
160+
158161
if (!existingUser) {
159162
throw new NotFoundException(`User with ID ${id} not found`);
160163
}
@@ -169,6 +172,7 @@ export class UserControllerInternal {
169172
if (error instanceof NotFoundException) {
170173
throw error;
171174
}
175+
172176
throw new BadRequestException('Failed to delete user');
173177
}
174178
}
@@ -183,6 +187,7 @@ export class UserControllerInternal {
183187
try {
184188
// Check if user exists
185189
const existingUser = await this.userService.getByIdUnscoped(id, {});
190+
186191
if (!existingUser) {
187192
throw new NotFoundException(`User with ID ${id} not found`);
188193
}
@@ -208,6 +213,7 @@ export class UserControllerInternal {
208213
if (error instanceof NotFoundException) {
209214
throw error;
210215
}
216+
211217
throw new BadRequestException('Failed to block user');
212218
}
213219
}
@@ -222,6 +228,7 @@ export class UserControllerInternal {
222228
try {
223229
// Check if user exists
224230
const existingUser = await this.userService.getByIdUnscoped(id, {});
231+
225232
if (!existingUser) {
226233
throw new NotFoundException(`User with ID ${id} not found`);
227234
}
@@ -247,6 +254,7 @@ export class UserControllerInternal {
247254
if (error instanceof NotFoundException) {
248255
throw error;
249256
}
257+
250258
throw new BadRequestException('Failed to unblock user');
251259
}
252260
}

0 commit comments

Comments
 (0)