Refactor backend folder structure (#4505)
* Refactor backend folder structure Co-authored-by: Charles Bochet <charles@twenty.com> * fix tests * fix * move yoga hooks --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -0,0 +1,93 @@
|
||||
import { Inject, Injectable, Logger } from '@nestjs/common';
|
||||
|
||||
import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface';
|
||||
import { ObjectMetadataInterface } from 'src/engine-metadata/field-metadata/interfaces/object-metadata.interface';
|
||||
|
||||
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
||||
import { ObjectMetadataService } from 'src/engine-metadata/object-metadata/object-metadata.service';
|
||||
import { DataSourceService } from 'src/engine-metadata/data-source/data-source.service';
|
||||
import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service';
|
||||
import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants';
|
||||
import {
|
||||
CallWebhookJob,
|
||||
CallWebhookJobData,
|
||||
} from 'src/engine/api/graphql/workspace-query-runner/jobs/call-webhook.job';
|
||||
|
||||
export enum CallWebhookJobsJobOperation {
|
||||
create = 'create',
|
||||
update = 'update',
|
||||
delete = 'delete',
|
||||
}
|
||||
|
||||
export type CallWebhookJobsJobData = {
|
||||
workspaceId: string;
|
||||
objectMetadataItem: ObjectMetadataInterface;
|
||||
record: any;
|
||||
operation: CallWebhookJobsJobOperation;
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
export class CallWebhookJobsJob
|
||||
implements MessageQueueJob<CallWebhookJobsJobData>
|
||||
{
|
||||
private readonly logger = new Logger(CallWebhookJobsJob.name);
|
||||
|
||||
constructor(
|
||||
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
|
||||
private readonly objectMetadataService: ObjectMetadataService,
|
||||
private readonly dataSourceService: DataSourceService,
|
||||
@Inject(MessageQueue.webhookQueue)
|
||||
private readonly messageQueueService: MessageQueueService,
|
||||
) {}
|
||||
|
||||
async handle(data: CallWebhookJobsJobData): Promise<void> {
|
||||
const dataSourceMetadata =
|
||||
await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceIdOrFail(
|
||||
data.workspaceId,
|
||||
);
|
||||
const workspaceDataSource =
|
||||
await this.workspaceDataSourceService.connectToWorkspaceDataSource(
|
||||
data.workspaceId,
|
||||
);
|
||||
const nameSingular = data.objectMetadataItem.nameSingular;
|
||||
const operation = data.operation;
|
||||
const eventType = `${operation}.${nameSingular}`;
|
||||
const webhooks: { id: string; targetUrl: string }[] =
|
||||
await workspaceDataSource?.query(
|
||||
`
|
||||
SELECT * FROM ${dataSourceMetadata.schema}."webhook"
|
||||
WHERE operation LIKE '%${eventType}%'
|
||||
OR operation LIKE '%*.${nameSingular}%'
|
||||
OR operation LIKE '%${operation}.*%'
|
||||
OR operation LIKE '%*.*%'
|
||||
`,
|
||||
);
|
||||
|
||||
webhooks.forEach((webhook) => {
|
||||
this.messageQueueService.add<CallWebhookJobData>(
|
||||
CallWebhookJob.name,
|
||||
{
|
||||
targetUrl: webhook.targetUrl,
|
||||
eventType,
|
||||
objectMetadata: {
|
||||
id: data.objectMetadataItem.id,
|
||||
nameSingular: data.objectMetadataItem.nameSingular,
|
||||
},
|
||||
workspaceId: data.workspaceId,
|
||||
webhookId: webhook.id,
|
||||
eventDate: new Date(),
|
||||
record: data.record,
|
||||
},
|
||||
{ retryLimit: 3 },
|
||||
);
|
||||
});
|
||||
|
||||
if (webhooks.length) {
|
||||
this.logger.log(
|
||||
`CallWebhookJobsJob on eventType '${eventType}' called on webhooks ids [\n"${webhooks
|
||||
.map((webhook) => webhook.id)
|
||||
.join('",\n"')}"\n]`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { HttpService } from '@nestjs/axios';
|
||||
|
||||
import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface';
|
||||
|
||||
export type CallWebhookJobData = {
|
||||
targetUrl: string;
|
||||
eventType: string;
|
||||
objectMetadata: { id: string; nameSingular: string };
|
||||
workspaceId: string;
|
||||
webhookId: string;
|
||||
eventDate: Date;
|
||||
record: any;
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
export class CallWebhookJob implements MessageQueueJob<CallWebhookJobData> {
|
||||
private readonly logger = new Logger(CallWebhookJob.name);
|
||||
|
||||
constructor(private readonly httpService: HttpService) {}
|
||||
|
||||
async handle(data: CallWebhookJobData): Promise<void> {
|
||||
try {
|
||||
await this.httpService.axiosRef.post(data.targetUrl, data);
|
||||
this.logger.log(
|
||||
`CallWebhookJob successfully called on targetUrl '${data.targetUrl}'`,
|
||||
);
|
||||
} catch (err) {
|
||||
this.logger.error(
|
||||
`Error calling webhook on targetUrl '${data.targetUrl}': ${err}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface';
|
||||
|
||||
import { RecordPositionBackfillService } from 'src/engine/api/graphql/workspace-query-runner/services/record-position-backfill-service';
|
||||
|
||||
export type RecordPositionBackfillJobData = {
|
||||
workspaceId: string;
|
||||
objectMetadata: { nameSingular: string; isCustom: boolean };
|
||||
recordId: string;
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
export class RecordPositionBackfillJob
|
||||
implements MessageQueueJob<RecordPositionBackfillJobData>
|
||||
{
|
||||
constructor(
|
||||
private readonly recordPositionBackfillService: RecordPositionBackfillService,
|
||||
) {}
|
||||
|
||||
async handle(data: RecordPositionBackfillJobData): Promise<void> {
|
||||
this.recordPositionBackfillService.backfill(
|
||||
data.workspaceId,
|
||||
data.objectMetadata,
|
||||
data.recordId,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user