Skip to content

Commit c5d2898

Browse files
V0.30.0 (#960)
2 parents 1b2a0a0 + b24a3b3 commit c5d2898

File tree

20 files changed

+174
-77
lines changed

20 files changed

+174
-77
lines changed

.github/workflows/test-build.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@ jobs:
2424
# Steps represent a sequence of tasks that will be executed as part of the job
2525
steps:
2626
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
27-
- uses: actions/checkout@v2
27+
- uses: actions/checkout@v4
2828
- name: Setup kernel for react native, increase watchers
2929
run: echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
3030
- uses: actions/setup-node@v2
3131
with:
3232
node-version: '20.13.1'
3333

3434
- name: Cache pnpm modules
35-
uses: actions/cache@v2
35+
uses: actions/cache@v4
3636
with:
3737
path: ~/.pnpm-store
3838
key: ${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}

apps/api/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@impler/api",
3-
"version": "0.29.0",
3+
"version": "0.30.0",
44
"author": "implerhq",
55
"license": "MIT",
66
"private": true,
@@ -16,6 +16,9 @@
1616
"lint": "eslint src",
1717
"lint:fix": "pnpm lint -- --fix",
1818
"migration": "cross-env NODE_ENV=local MIGRATION=true ts-node --require tsconfig-paths/register --transpileOnly",
19+
"migration:prod": "cross-env NODE_ENV=prod MIGRATION=true ts-node --require tsconfig-paths/register --transpileOnly",
20+
"migration:dev": "cross-env NODE_ENV=dev MIGRATION=true ts-node --require tsconfig-paths/register --transpileOnly",
21+
"migration:test": "cross-env NODE_ENV=test MIGRATION=true ts-node --require tsconfig-paths/register --transpileOnly",
1922
"test": "cross-env TZ=UTC NODE_ENV=test E2E_RUNNER=true mocha --timeout 10000 --require ts-node/register --exit"
2023
},
2124
"dependencies": {

apps/api/src/app/column/dtos/column-request.dto.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import { Type } from 'class-transformer';
1515

1616
import { ValidationTypesEnum } from '@impler/client';
1717
import { IsValidRegex } from '@shared/framework/is-valid-regex.validator';
18-
import { IsGreaterThan } from '@shared/framework/is-greator-than.validator';
1918
import { IsNumberOrString } from '@shared/framework/number-or-string.validator';
2019
import { ColumnDelimiterEnum, ColumnTypesEnum, Defaults } from '@impler/shared';
2120

@@ -48,9 +47,6 @@ export class ValidationDto {
4847
})
4948
@IsNumber()
5049
@IsOptional()
51-
@IsGreaterThan('min', {
52-
message: 'max must be greater than min',
53-
})
5450
max?: number;
5551

5652
@ApiPropertyOptional({
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* Migration Script:
3+
* - Finds uploads stuck in 'PROCESSING' status
4+
* - Republishes them to the END_IMPORT queue to restart processing
5+
*/
6+
7+
import '../../config';
8+
import { AppModule } from '../../app.module';
9+
import { NestFactory } from '@nestjs/core';
10+
import { UploadStatusEnum, QueuesEnum } from '@impler/shared';
11+
import { UploadRepository, TemplateRepository } from '@impler/dal';
12+
import { QueueService } from '@shared/services/queue.service';
13+
14+
async function run() {
15+
console.log('Starting migration: reprocessing uploads in PROCESSING state');
16+
17+
const app = await NestFactory.create(AppModule, { logger: false });
18+
19+
try {
20+
const uploadRepository = app.get(UploadRepository);
21+
const templateRepository = app.get(TemplateRepository);
22+
const queueService = app.get(QueueService);
23+
24+
const processingUploads = await uploadRepository.find({
25+
status: UploadStatusEnum.PROCESSING,
26+
});
27+
28+
if (!processingUploads.length) {
29+
console.log('No uploads found in PROCESSING state.');
30+
31+
return;
32+
}
33+
34+
console.log(`Found ${processingUploads.length} uploads. Republishing to queue.`);
35+
36+
for (const upload of processingUploads) {
37+
const template = await templateRepository.findOne({ _id: upload._templateId });
38+
39+
if (template?.destination) {
40+
queueService.publishToQueue(QueuesEnum.END_IMPORT, {
41+
uploadId: upload._id,
42+
uploadedFileId: upload._uploadedFileId,
43+
destination: template.destination,
44+
});
45+
46+
console.log(`Send upload ${upload._id} to destination ${template.destination}`);
47+
} else {
48+
console.warn(`No destination found for upload ${upload._id}`);
49+
}
50+
}
51+
52+
console.log('Migration completed.');
53+
} catch (error) {
54+
console.error('Migration failed:', error);
55+
} finally {
56+
await app.close();
57+
process.exit(0);
58+
}
59+
}
60+
61+
run();

apps/queue-manager/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@impler/queue-manager",
3-
"version": "0.29.0",
3+
"version": "0.30.0",
44
"author": "implerhq",
55
"license": "MIT",
66
"private": true,

apps/queue-manager/src/consumers/base.consumer.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export abstract class BaseConsumer {
6060
return baseResponse;
6161
} catch (error) {
6262
baseResponse.status = StatusEnum.FAILED;
63+
console.log(error);
6364
if (axios.isAxiosError(error)) {
6465
if (error.response) {
6566
const formattedError = error.toJSON() as any;

apps/queue-manager/src/consumers/send-import-job-data.consumer.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ export class SendImportJobDataConsumer extends BaseConsumer {
173173
multiSelectHeadings,
174174
extra: userJob.extra,
175175
name: templateData.name,
176+
projectId: templateData._projectId,
176177
_templateId: userJob._templateId,
177178
authHeaderValue: userJob.authHeaderValue,
178179
callbackUrl: webhookDestination?.callbackUrl,

apps/queue-manager/src/consumers/send-webhook-data.consumer.ts

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
WebhookLogRepository,
2121
WebhookDestinationRepository,
2222
FailedWebhookRetryRequestsRepository,
23+
EnvironmentRepository,
2324
} from '@impler/dal';
2425

2526
import { BaseConsumer } from './base.consumer';
@@ -40,6 +41,7 @@ export class SendWebhookDataConsumer extends BaseConsumer {
4041
private emailService: EmailService = getEmailServiceClass();
4142
private failedWebhookRetryRequestsRepository: FailedWebhookRetryRequestsRepository =
4243
new FailedWebhookRetryRequestsRepository();
44+
private environmentRepository: EnvironmentRepository = new EnvironmentRepository();
4345

4446
async message(message: { content: string }) {
4547
const data = JSON.parse(message.content) as SendWebhookData;
@@ -91,9 +93,9 @@ export class SendWebhookDataConsumer extends BaseConsumer {
9193

9294
await this.makeResponseEntry({
9395
data: response,
96+
projectId: cachedData.projectId,
9497
importName: cachedData.name,
9598
url: cachedData.callbackUrl,
96-
userEmail: cachedData.email,
9799
retryInterval: cachedData.retryInterval,
98100
retryCount: cachedData.retryCount,
99101
allData,
@@ -207,6 +209,7 @@ export class SendWebhookDataConsumer extends BaseConsumer {
207209

208210
return {
209211
_templateId: uploadata._templateId,
212+
projectId: templateData._projectId,
210213
callbackUrl: webhookDestination?.callbackUrl,
211214
chunkSize: webhookDestination?.chunkSize,
212215
name: templateData.name,
@@ -230,22 +233,26 @@ export class SendWebhookDataConsumer extends BaseConsumer {
230233
private async makeResponseEntry({
231234
data,
232235
importName,
236+
projectId,
233237
url,
234238
allData,
235-
userEmail,
236239
retryInterval,
237240
retryCount,
238241
}: {
239242
data: Partial<WebhookLogEntity>;
240243
importName: string;
244+
projectId: string;
241245
url: string;
242-
userEmail: string;
243246
retryCount?: number;
244247
retryInterval?: number;
245248
allData: Record<string, any>;
246249
}) {
247250
const webhookLog = await this.webhookLogRepository.create(data);
248251
if (data.status === StatusEnum.FAILED) {
252+
const environment = await this.environmentRepository.getProjectTeamMembers(projectId);
253+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
254+
// @ts-ignore
255+
const teamMemberEmails = environment.map((teamMember) => teamMember._userId.email);
249256
const emailContents = this.emailService.getEmailContent({
250257
type: 'ERROR_SENDING_WEBHOOK_DATA',
251258
data: {
@@ -256,13 +263,14 @@ export class SendWebhookDataConsumer extends BaseConsumer {
256263
importId: data._uploadId,
257264
},
258265
});
259-
260-
await this.emailService.sendEmail({
261-
to: userEmail,
262-
subject: `${EMAIL_SUBJECT.ERROR_SENDING_WEBHOOK_DATA} ${importName}`,
263-
html: emailContents,
264-
from: process.env.ALERT_EMAIL_FROM,
265-
senderName: process.env.EMAIL_FROM_NAME,
266+
teamMemberEmails.forEach(async (email) => {
267+
await this.emailService.sendEmail({
268+
to: email,
269+
subject: `${EMAIL_SUBJECT.ERROR_SENDING_WEBHOOK_DATA} ${importName}`,
270+
html: emailContents,
271+
from: process.env.ALERT_EMAIL_FROM,
272+
senderName: process.env.EMAIL_FROM_NAME,
273+
});
266274
});
267275

268276
if (retryCount && retryInterval) {

apps/web/components/ConfirmationModal/ConfirmationModal.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
import React from 'react';
2-
import Lottie from 'lottie-react';
2+
import dynamic from 'next/dynamic';
33
import { modals } from '@mantine/modals';
44
import { colors, CONSTANTS } from '@config';
55
import { Stack, Text } from '@mantine/core';
66

7+
import { Button } from '@ui/button';
78
import FailedAnimationData from './failed-animation-data.json';
89
import SuccessAnimationData from './success-animation-data.json';
9-
import { Button } from '@ui/button';
1010

1111
interface ConfirmationModalProps {
1212
status: string;
1313
}
1414

15+
const Lottie = dynamic(() => import('lottie-react'), { ssr: false });
16+
1517
export const ConfirmationModal = ({ status }: ConfirmationModalProps) => {
1618
const title =
1719
status === CONSTANTS.PAYMENT_SUCCCESS_CODE

apps/web/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@impler/web",
3-
"version": "0.29.0",
3+
"version": "0.30.0",
44
"author": "implerhq",
55
"license": "MIT",
66
"private": true,

0 commit comments

Comments
 (0)