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:
Weiko
2024-03-15 18:37:09 +01:00
committed by GitHub
parent afb9b3e375
commit 2c09096edd
523 changed files with 1386 additions and 1856 deletions

View File

@ -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]`,
);
}
}
}

View File

@ -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}`,
);
}
}
}

View File

@ -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,
);
}
}