4398 decouple contacts and companies creation from messages import (#4590)
* emit event * create queue and listener * filter participants with role 'from' * create job * Add job to job module * Refactoring * Refactor contact creation in CreateCompanyAndContactService * update job * wip * add getByHandlesWithoutPersonIdAndWorkspaceMemberId to calendar event attendee repository * refactoring * refactoring * Revert "refactoring" This reverts commit e5434f0b871e45447227aa8d55ba5af381c3ff1c. * fix nest imports * add await * fix contact creation condition * emit contact creation event after calendar-full-sync * add await * add missing transactionManager * calendar event attendees personId update is working * messageParticipant and calendarEventAttendee update is working as intended * rename module * fix lodash import * add test * update package.json
This commit is contained in:
@ -7,7 +7,10 @@ import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/work
|
||||
import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record';
|
||||
import { CalendarEventAttendeeObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-event-attendee.object-metadata';
|
||||
import { getFlattenedValuesAndValuesStringForBatchRawQuery } from 'src/modules/calendar/utils/getFlattenedValuesAndValuesStringForBatchRawQuery.util';
|
||||
import { CalendarEventAttendee } from 'src/modules/calendar/types/calendar-event';
|
||||
import {
|
||||
CalendarEventAttendee,
|
||||
CalendarEventAttendeeWithId,
|
||||
} from 'src/modules/calendar/types/calendar-event';
|
||||
|
||||
@Injectable()
|
||||
export class CalendarEventAttendeeRepository {
|
||||
@ -172,4 +175,29 @@ export class CalendarEventAttendeeRepository {
|
||||
transactionManager,
|
||||
);
|
||||
}
|
||||
|
||||
public async getWithoutPersonIdAndWorkspaceMemberId(
|
||||
workspaceId: string,
|
||||
transactionManager?: EntityManager,
|
||||
): Promise<CalendarEventAttendeeWithId[]> {
|
||||
if (!workspaceId) {
|
||||
throw new Error('WorkspaceId is required');
|
||||
}
|
||||
|
||||
const dataSourceSchema =
|
||||
this.workspaceDataSourceService.getSchemaName(workspaceId);
|
||||
|
||||
const calendarEventAttendees: CalendarEventAttendeeWithId[] =
|
||||
await this.workspaceDataSourceService.executeRawQuery(
|
||||
`SELECT "calendarEventAttendee".*
|
||||
FROM ${dataSourceSchema}."calendarEventAttendee" AS "calendarEventAttendee"
|
||||
WHERE "calendarEventAttendee"."personId" IS NULL
|
||||
AND "calendarEventAttendee"."workspaceMemberId" IS NULL`,
|
||||
[],
|
||||
workspaceId,
|
||||
transactionManager,
|
||||
);
|
||||
|
||||
return calendarEventAttendees;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module';
|
||||
import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module';
|
||||
import { CalendarEventAttendeeService } from 'src/modules/calendar/services/calendar-event-attendee/calendar-event-attendee.service';
|
||||
import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
WorkspaceDataSourceModule,
|
||||
ObjectMetadataRepositoryModule.forFeature([PersonObjectMetadata]),
|
||||
],
|
||||
providers: [CalendarEventAttendeeService],
|
||||
exports: [CalendarEventAttendeeService],
|
||||
})
|
||||
export class CalendarEventAttendeeModule {}
|
||||
@ -0,0 +1,65 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { EntityManager } from 'typeorm';
|
||||
|
||||
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
|
||||
import { PersonRepository } from 'src/modules/person/repositories/person.repository';
|
||||
import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata';
|
||||
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
||||
import { getFlattenedValuesAndValuesStringForBatchRawQuery } from 'src/modules/calendar/utils/getFlattenedValuesAndValuesStringForBatchRawQuery.util';
|
||||
import { CalendarEventAttendeeWithId } from 'src/modules/calendar/types/calendar-event';
|
||||
|
||||
@Injectable()
|
||||
export class CalendarEventAttendeeService {
|
||||
constructor(
|
||||
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
|
||||
@InjectObjectMetadataRepository(PersonObjectMetadata)
|
||||
private readonly personRepository: PersonRepository,
|
||||
) {}
|
||||
|
||||
public async updateCalendarEventAttendeesAfterContactCreation(
|
||||
attendees: CalendarEventAttendeeWithId[],
|
||||
workspaceId: string,
|
||||
transactionManager?: EntityManager,
|
||||
): Promise<void> {
|
||||
if (!attendees) return;
|
||||
|
||||
const dataSourceSchema =
|
||||
this.workspaceDataSourceService.getSchemaName(workspaceId);
|
||||
|
||||
const handles = attendees.map((attendee) => attendee.handle);
|
||||
|
||||
const attendeePersonIds = await this.personRepository.getByEmails(
|
||||
handles,
|
||||
workspaceId,
|
||||
transactionManager,
|
||||
);
|
||||
|
||||
const calendarEventAttendeesToUpdate = attendees.map((attendee) => ({
|
||||
id: attendee.id,
|
||||
personId: attendeePersonIds.find(
|
||||
(e: { id: string; email: string }) => e.email === attendee.handle,
|
||||
)?.id,
|
||||
}));
|
||||
|
||||
if (calendarEventAttendeesToUpdate.length === 0) return;
|
||||
|
||||
const { flattenedValues, valuesString } =
|
||||
getFlattenedValuesAndValuesStringForBatchRawQuery(
|
||||
calendarEventAttendeesToUpdate,
|
||||
{
|
||||
id: 'uuid',
|
||||
personId: 'uuid',
|
||||
},
|
||||
);
|
||||
|
||||
await this.workspaceDataSourceService.executeRawQuery(
|
||||
`UPDATE ${dataSourceSchema}."calendarEventAttendee" AS "calendarEventAttendee" SET "personId" = "data"."personId"
|
||||
FROM (VALUES ${valuesString}) AS "data"("id", "personId")
|
||||
WHERE "calendarEventAttendee"."id" = "data"."id"`,
|
||||
flattenedValues,
|
||||
workspaceId,
|
||||
transactionManager,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
import { Inject, Injectable, Logger } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
@ -53,6 +54,7 @@ export class GoogleCalendarFullSyncService {
|
||||
@InjectRepository(FeatureFlagEntity, 'core')
|
||||
private readonly featureFlagRepository: Repository<FeatureFlagEntity>,
|
||||
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
|
||||
private readonly eventEmitter: EventEmitter2,
|
||||
) {}
|
||||
|
||||
public async startGoogleCalendarFullSync(
|
||||
@ -294,6 +296,16 @@ export class GoogleCalendarFullSyncService {
|
||||
}ms.`,
|
||||
);
|
||||
});
|
||||
|
||||
if (calendarChannel.isContactAutoCreationEnabled) {
|
||||
const contactsToCreate = attendeesToSave;
|
||||
|
||||
this.eventEmitter.emit(`createContacts`, {
|
||||
workspaceId,
|
||||
connectedAccountHandle: connectedAccount.handle,
|
||||
contactsToCreate,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.error(
|
||||
`Error during google calendar full-sync for workspace ${workspaceId} and account ${connectedAccountId}: ${error.message}`,
|
||||
|
||||
@ -29,3 +29,7 @@ export type CalendarEventWithAttendees = CalendarEvent & {
|
||||
externalId: string;
|
||||
attendees: CalendarEventAttendee[];
|
||||
};
|
||||
|
||||
export type CalendarEventAttendeeWithId = CalendarEventAttendee & {
|
||||
id: string;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user