[permissions] Add permissions check layer in entityManager (#11818)
First and main step of https://github.com/twentyhq/core-team-issues/issues/747 We are implementing a permission check layer in our custom WorkspaceEntityManager by overriding all the db-executing methods (this PR only overrides some as a POC, the rest will be done in the next PR). Our custom repositories call entity managers under the hood to interact with the db so this solves the repositories case too. This is still behind the feature flag IsPermissionsV2Enabled. In the next PR - finish overriding all the methods required in WorkspaceEntityManager - add tests
This commit is contained in:
@ -1,7 +1,5 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { EntityManager } from 'typeorm';
|
||||
|
||||
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
||||
import { BlocklistWorkspaceEntity } from 'src/modules/blocklist/standard-objects/blocklist.workspace-entity';
|
||||
|
||||
@ -14,7 +12,6 @@ export class BlocklistRepository {
|
||||
public async getById(
|
||||
id: string,
|
||||
workspaceId: string,
|
||||
transactionManager?: EntityManager,
|
||||
): Promise<BlocklistWorkspaceEntity | null> {
|
||||
const dataSourceSchema =
|
||||
this.workspaceDataSourceService.getSchemaName(workspaceId);
|
||||
@ -24,7 +21,6 @@ export class BlocklistRepository {
|
||||
`SELECT * FROM ${dataSourceSchema}."blocklist" WHERE "id" = $1`,
|
||||
[id],
|
||||
workspaceId,
|
||||
transactionManager,
|
||||
);
|
||||
|
||||
if (!blocklistItems || blocklistItems.length === 0) {
|
||||
@ -37,7 +33,6 @@ export class BlocklistRepository {
|
||||
public async getByWorkspaceMemberId(
|
||||
workspaceMemberId: string,
|
||||
workspaceId: string,
|
||||
transactionManager?: EntityManager,
|
||||
): Promise<BlocklistWorkspaceEntity[]> {
|
||||
const dataSourceSchema =
|
||||
this.workspaceDataSourceService.getSchemaName(workspaceId);
|
||||
@ -46,7 +41,6 @@ export class BlocklistRepository {
|
||||
`SELECT * FROM ${dataSourceSchema}."blocklist" WHERE "workspaceMemberId" = $1`,
|
||||
[workspaceMemberId],
|
||||
workspaceId,
|
||||
transactionManager,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import { InjectMessageQueue } from 'src/engine/core-modules/message-queue/decora
|
||||
import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants';
|
||||
import { MessageQueueService } from 'src/engine/core-modules/message-queue/services/message-queue.service';
|
||||
import { FieldActorSource } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
|
||||
import { WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
|
||||
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||
import { injectIdsInCalendarEvents } from 'src/modules/calendar/calendar-event-import-manager/utils/inject-ids-in-calendar-events.util';
|
||||
import { CalendarEventParticipantService } from 'src/modules/calendar/calendar-event-participant-manager/services/calendar-event-participant.service';
|
||||
@ -113,71 +114,73 @@ export class CalendarSaveEventsService {
|
||||
|
||||
const workspaceDataSource = await this.twentyORMManager.getDatasource();
|
||||
|
||||
await workspaceDataSource?.transaction(async (transactionManager) => {
|
||||
await calendarEventRepository.save(
|
||||
eventsToSave.map(
|
||||
(calendarEvent) =>
|
||||
({
|
||||
id: calendarEvent.id,
|
||||
iCalUID: calendarEvent.iCalUID,
|
||||
title: calendarEvent.title,
|
||||
description: calendarEvent.description,
|
||||
startsAt: calendarEvent.startsAt,
|
||||
endsAt: calendarEvent.endsAt,
|
||||
location: calendarEvent.location,
|
||||
isFullDay: calendarEvent.isFullDay,
|
||||
isCanceled: calendarEvent.isCanceled,
|
||||
conferenceSolution: calendarEvent.conferenceSolution,
|
||||
conferenceLink: {
|
||||
primaryLinkLabel: calendarEvent.conferenceLinkLabel,
|
||||
primaryLinkUrl: calendarEvent.conferenceLinkUrl,
|
||||
},
|
||||
externalCreatedAt: calendarEvent.externalCreatedAt,
|
||||
externalUpdatedAt: calendarEvent.externalUpdatedAt,
|
||||
}) satisfies DeepPartial<CalendarEventWorkspaceEntity>,
|
||||
),
|
||||
{},
|
||||
transactionManager,
|
||||
);
|
||||
await workspaceDataSource?.transaction(
|
||||
async (transactionManager: WorkspaceEntityManager) => {
|
||||
await calendarEventRepository.save(
|
||||
eventsToSave.map(
|
||||
(calendarEvent) =>
|
||||
({
|
||||
id: calendarEvent.id,
|
||||
iCalUID: calendarEvent.iCalUID,
|
||||
title: calendarEvent.title,
|
||||
description: calendarEvent.description,
|
||||
startsAt: calendarEvent.startsAt,
|
||||
endsAt: calendarEvent.endsAt,
|
||||
location: calendarEvent.location,
|
||||
isFullDay: calendarEvent.isFullDay,
|
||||
isCanceled: calendarEvent.isCanceled,
|
||||
conferenceSolution: calendarEvent.conferenceSolution,
|
||||
conferenceLink: {
|
||||
primaryLinkLabel: calendarEvent.conferenceLinkLabel,
|
||||
primaryLinkUrl: calendarEvent.conferenceLinkUrl,
|
||||
},
|
||||
externalCreatedAt: calendarEvent.externalCreatedAt,
|
||||
externalUpdatedAt: calendarEvent.externalUpdatedAt,
|
||||
}) satisfies DeepPartial<CalendarEventWorkspaceEntity>,
|
||||
),
|
||||
{},
|
||||
transactionManager,
|
||||
);
|
||||
|
||||
await calendarEventRepository.save(
|
||||
eventsToUpdate.map(
|
||||
(calendarEvent) =>
|
||||
({
|
||||
id: calendarEvent.id,
|
||||
iCalUID: calendarEvent.iCalUID,
|
||||
title: calendarEvent.title,
|
||||
description: calendarEvent.description,
|
||||
startsAt: calendarEvent.startsAt,
|
||||
endsAt: calendarEvent.endsAt,
|
||||
location: calendarEvent.location,
|
||||
isFullDay: calendarEvent.isFullDay,
|
||||
isCanceled: calendarEvent.isCanceled,
|
||||
conferenceSolution: calendarEvent.conferenceSolution,
|
||||
conferenceLink: {
|
||||
primaryLinkLabel: calendarEvent.conferenceLinkLabel,
|
||||
primaryLinkUrl: calendarEvent.conferenceLinkUrl,
|
||||
},
|
||||
externalCreatedAt: calendarEvent.externalCreatedAt,
|
||||
externalUpdatedAt: calendarEvent.externalUpdatedAt,
|
||||
}) satisfies DeepPartial<CalendarEventWorkspaceEntity>,
|
||||
),
|
||||
{},
|
||||
transactionManager,
|
||||
);
|
||||
await calendarEventRepository.save(
|
||||
eventsToUpdate.map(
|
||||
(calendarEvent) =>
|
||||
({
|
||||
id: calendarEvent.id,
|
||||
iCalUID: calendarEvent.iCalUID,
|
||||
title: calendarEvent.title,
|
||||
description: calendarEvent.description,
|
||||
startsAt: calendarEvent.startsAt,
|
||||
endsAt: calendarEvent.endsAt,
|
||||
location: calendarEvent.location,
|
||||
isFullDay: calendarEvent.isFullDay,
|
||||
isCanceled: calendarEvent.isCanceled,
|
||||
conferenceSolution: calendarEvent.conferenceSolution,
|
||||
conferenceLink: {
|
||||
primaryLinkLabel: calendarEvent.conferenceLinkLabel,
|
||||
primaryLinkUrl: calendarEvent.conferenceLinkUrl,
|
||||
},
|
||||
externalCreatedAt: calendarEvent.externalCreatedAt,
|
||||
externalUpdatedAt: calendarEvent.externalUpdatedAt,
|
||||
}) satisfies DeepPartial<CalendarEventWorkspaceEntity>,
|
||||
),
|
||||
{},
|
||||
transactionManager,
|
||||
);
|
||||
|
||||
await calendarChannelEventAssociationRepository.save(
|
||||
calendarChannelEventAssociationsToSave,
|
||||
{},
|
||||
transactionManager,
|
||||
);
|
||||
await calendarChannelEventAssociationRepository.save(
|
||||
calendarChannelEventAssociationsToSave,
|
||||
{},
|
||||
transactionManager,
|
||||
);
|
||||
|
||||
await this.calendarEventParticipantService.upsertAndDeleteCalendarEventParticipants(
|
||||
participantsToSave,
|
||||
participantsToUpdate,
|
||||
transactionManager,
|
||||
);
|
||||
});
|
||||
await this.calendarEventParticipantService.upsertAndDeleteCalendarEventParticipants(
|
||||
participantsToSave,
|
||||
participantsToUpdate,
|
||||
transactionManager,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
if (calendarChannel.isContactAutoCreationEnabled) {
|
||||
await this.messageQueueService.add<CreateCompanyAndContactJobData>(
|
||||
|
||||
@ -4,6 +4,7 @@ import { isDefined } from 'class-validator';
|
||||
import differenceWith from 'lodash.differencewith';
|
||||
import { Any } from 'typeorm';
|
||||
|
||||
import { WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
|
||||
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||
import { CalendarEventParticipantWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-event-participant.workspace-entity';
|
||||
import { CalendarEventParticipantWithCalendarEventId } from 'src/modules/calendar/common/types/calendar-event';
|
||||
@ -19,7 +20,7 @@ export class CalendarEventParticipantService {
|
||||
public async upsertAndDeleteCalendarEventParticipants(
|
||||
participantsToSave: CalendarEventParticipantWithCalendarEventId[],
|
||||
participantsToUpdate: CalendarEventParticipantWithCalendarEventId[],
|
||||
transactionManager?: any,
|
||||
transactionManager?: WorkspaceEntityManager,
|
||||
): Promise<void> {
|
||||
const calendarEventParticipantRepository =
|
||||
await this.twentyORMManager.getRepository<CalendarEventParticipantWorkspaceEntity>(
|
||||
|
||||
@ -3,7 +3,7 @@ import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import chunk from 'lodash.chunk';
|
||||
import compact from 'lodash.compact';
|
||||
import { Any, EntityManager, Repository } from 'typeorm';
|
||||
import { Any, Repository } from 'typeorm';
|
||||
|
||||
import { DatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/enums/database-event-action';
|
||||
import { ExceptionHandlerService } from 'src/engine/core-modules/exception-handler/exception-handler.service';
|
||||
@ -45,7 +45,6 @@ export class CreateCompanyAndContactService {
|
||||
contactsToCreate: Contact[],
|
||||
workspaceId: string,
|
||||
source: FieldActorSource,
|
||||
transactionManager?: EntityManager,
|
||||
): Promise<DeepPartial<PersonWorkspaceEntity>[]> {
|
||||
if (!contactsToCreate || contactsToCreate.length === 0) {
|
||||
return [];
|
||||
@ -61,10 +60,7 @@ export class CreateCompanyAndContactService {
|
||||
);
|
||||
|
||||
const workspaceMembers =
|
||||
await this.workspaceMemberRepository.getAllByWorkspaceId(
|
||||
workspaceId,
|
||||
transactionManager,
|
||||
);
|
||||
await this.workspaceMemberRepository.getAllByWorkspaceId(workspaceId);
|
||||
|
||||
const contactsToCreateFromOtherCompanies =
|
||||
filterOutSelfAndContactsFromCompanyOrWorkspace(
|
||||
@ -137,7 +133,6 @@ export class CreateCompanyAndContactService {
|
||||
const companiesObject = await this.createCompaniesService.createCompanies(
|
||||
workDomainNamesToCreateFormatted,
|
||||
workspaceId,
|
||||
transactionManager,
|
||||
);
|
||||
|
||||
const formattedContactsToCreate =
|
||||
@ -158,7 +153,6 @@ export class CreateCompanyAndContactService {
|
||||
return this.createContactService.createPeople(
|
||||
formattedContactsToCreate,
|
||||
workspaceId,
|
||||
transactionManager,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ import axios, { AxiosInstance } from 'axios';
|
||||
import uniqBy from 'lodash.uniqby';
|
||||
import { TWENTY_COMPANIES_BASE_URL } from 'twenty-shared/constants';
|
||||
import { ConnectedAccountProvider } from 'twenty-shared/types';
|
||||
import { DeepPartial, EntityManager, ILike } from 'typeorm';
|
||||
import { DeepPartial, ILike } from 'typeorm';
|
||||
|
||||
import { FieldActorSource } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
|
||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
||||
@ -37,7 +37,6 @@ export class CreateCompanyService {
|
||||
async createCompanies(
|
||||
companies: CompanyToCreate[],
|
||||
workspaceId: string,
|
||||
transactionManager?: EntityManager,
|
||||
): Promise<{
|
||||
[domainName: string]: string;
|
||||
}> {
|
||||
@ -63,12 +62,9 @@ export class CreateCompanyService {
|
||||
}));
|
||||
|
||||
// Find existing companies
|
||||
const existingCompanies = await companyRepository.find(
|
||||
{
|
||||
where: conditions,
|
||||
},
|
||||
transactionManager,
|
||||
);
|
||||
const existingCompanies = await companyRepository.find({
|
||||
where: conditions,
|
||||
});
|
||||
const existingCompanyIdsMap = this.createCompanyMap(existingCompanies);
|
||||
|
||||
// Filter out companies that already exist
|
||||
@ -87,10 +83,8 @@ export class CreateCompanyService {
|
||||
}
|
||||
|
||||
// Retrieve the last company position
|
||||
let lastCompanyPosition = await this.getLastCompanyPosition(
|
||||
companyRepository,
|
||||
transactionManager,
|
||||
);
|
||||
let lastCompanyPosition =
|
||||
await this.getLastCompanyPosition(companyRepository);
|
||||
const newCompaniesData = await Promise.all(
|
||||
newCompaniesToCreate.map((company) =>
|
||||
this.prepareCompanyData(company, ++lastCompanyPosition),
|
||||
@ -156,12 +150,10 @@ export class CreateCompanyService {
|
||||
|
||||
private async getLastCompanyPosition(
|
||||
companyRepository: WorkspaceRepository<CompanyWorkspaceEntity>,
|
||||
transactionManager?: EntityManager,
|
||||
): Promise<number> {
|
||||
const lastCompanyPosition = await companyRepository.maximum(
|
||||
'position',
|
||||
undefined,
|
||||
transactionManager,
|
||||
);
|
||||
|
||||
return lastCompanyPosition ?? 0;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { ConnectedAccountProvider } from 'twenty-shared/types';
|
||||
import { DeepPartial, EntityManager } from 'typeorm';
|
||||
import { DeepPartial } from 'typeorm';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { FieldActorSource } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
|
||||
@ -74,7 +74,6 @@ export class CreateContactService {
|
||||
public async createPeople(
|
||||
contactsToCreate: ContactToCreate[],
|
||||
workspaceId: string,
|
||||
transactionManager?: EntityManager,
|
||||
): Promise<DeepPartial<PersonWorkspaceEntity>[]> {
|
||||
if (contactsToCreate.length === 0) return [];
|
||||
|
||||
@ -87,31 +86,23 @@ export class CreateContactService {
|
||||
},
|
||||
);
|
||||
|
||||
const lastPersonPosition = await this.getLastPersonPosition(
|
||||
personRepository,
|
||||
transactionManager,
|
||||
);
|
||||
const lastPersonPosition =
|
||||
await this.getLastPersonPosition(personRepository);
|
||||
|
||||
const formattedContacts = this.formatContacts(
|
||||
contactsToCreate,
|
||||
lastPersonPosition,
|
||||
);
|
||||
|
||||
return personRepository.save(
|
||||
formattedContacts,
|
||||
undefined,
|
||||
transactionManager,
|
||||
);
|
||||
return personRepository.save(formattedContacts, undefined);
|
||||
}
|
||||
|
||||
private async getLastPersonPosition(
|
||||
personRepository: WorkspaceRepository<PersonWorkspaceEntity>,
|
||||
transactionManager?: EntityManager,
|
||||
): Promise<number> {
|
||||
const lastPersonPosition = await personRepository.maximum(
|
||||
'position',
|
||||
undefined,
|
||||
transactionManager,
|
||||
);
|
||||
|
||||
return lastPersonPosition ?? 0;
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { Any, EntityManager, Equal } from 'typeorm';
|
||||
import { Any, Equal } from 'typeorm';
|
||||
|
||||
import { WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
|
||||
import { ScopedWorkspaceContextFactory } from 'src/engine/twenty-orm/factories/scoped-workspace-context.factory';
|
||||
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||
import { WorkspaceEventEmitter } from 'src/engine/workspace-event-emitter/workspace-event-emitter';
|
||||
@ -39,7 +40,7 @@ export class MatchParticipantService<
|
||||
public async matchParticipants(
|
||||
participants: ParticipantWorkspaceEntity[],
|
||||
objectMetadataName: 'messageParticipant' | 'calendarEventParticipant',
|
||||
transactionManager?: EntityManager,
|
||||
transactionManager?: WorkspaceEntityManager,
|
||||
) {
|
||||
const participantRepository =
|
||||
await this.getParticipantRepository(objectMetadataName);
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { EntityManager, IsNull } from 'typeorm';
|
||||
import { IsNull } from 'typeorm';
|
||||
|
||||
import { WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
|
||||
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||
import { MessageThreadWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-thread.workspace-entity';
|
||||
import { MessageWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message.workspace-entity';
|
||||
@ -24,75 +25,77 @@ export class MessagingMessageCleanerService {
|
||||
|
||||
const workspaceDataSource = await this.twentyORMManager.getDatasource();
|
||||
|
||||
await workspaceDataSource.transaction(async (transactionManager) => {
|
||||
await deleteUsingPagination(
|
||||
workspaceId,
|
||||
500,
|
||||
async (
|
||||
limit: number,
|
||||
offset: number,
|
||||
workspaceId: string,
|
||||
transactionManager: EntityManager,
|
||||
) => {
|
||||
const nonAssociatedMessages = await messageRepository.find(
|
||||
{
|
||||
where: {
|
||||
messageChannelMessageAssociations: {
|
||||
id: IsNull(),
|
||||
await workspaceDataSource.transaction(
|
||||
async (transactionManager: WorkspaceEntityManager) => {
|
||||
await deleteUsingPagination(
|
||||
workspaceId,
|
||||
500,
|
||||
async (
|
||||
limit: number,
|
||||
offset: number,
|
||||
_workspaceId: string,
|
||||
transactionManager: WorkspaceEntityManager,
|
||||
) => {
|
||||
const nonAssociatedMessages = await messageRepository.find(
|
||||
{
|
||||
where: {
|
||||
messageChannelMessageAssociations: {
|
||||
id: IsNull(),
|
||||
},
|
||||
},
|
||||
take: limit,
|
||||
skip: offset,
|
||||
relations: ['messageChannelMessageAssociations'],
|
||||
},
|
||||
take: limit,
|
||||
skip: offset,
|
||||
relations: ['messageChannelMessageAssociations'],
|
||||
},
|
||||
transactionManager,
|
||||
);
|
||||
transactionManager,
|
||||
);
|
||||
|
||||
return nonAssociatedMessages.map(({ id }) => id);
|
||||
},
|
||||
async (
|
||||
ids: string[],
|
||||
workspaceId: string,
|
||||
transactionManager?: EntityManager,
|
||||
) => {
|
||||
await messageRepository.delete(ids, transactionManager);
|
||||
},
|
||||
transactionManager,
|
||||
);
|
||||
return nonAssociatedMessages.map(({ id }) => id);
|
||||
},
|
||||
async (
|
||||
ids: string[],
|
||||
workspaceId: string,
|
||||
transactionManager?: WorkspaceEntityManager,
|
||||
) => {
|
||||
await messageRepository.delete(ids, transactionManager);
|
||||
},
|
||||
transactionManager,
|
||||
);
|
||||
|
||||
await deleteUsingPagination(
|
||||
workspaceId,
|
||||
500,
|
||||
async (
|
||||
limit: number,
|
||||
offset: number,
|
||||
workspaceId: string,
|
||||
transactionManager?: EntityManager,
|
||||
) => {
|
||||
const orphanThreads = await messageThreadRepository.find(
|
||||
{
|
||||
where: {
|
||||
messages: {
|
||||
id: IsNull(),
|
||||
await deleteUsingPagination(
|
||||
workspaceId,
|
||||
500,
|
||||
async (
|
||||
limit: number,
|
||||
offset: number,
|
||||
_workspaceId: string,
|
||||
transactionManager?: WorkspaceEntityManager,
|
||||
) => {
|
||||
const orphanThreads = await messageThreadRepository.find(
|
||||
{
|
||||
where: {
|
||||
messages: {
|
||||
id: IsNull(),
|
||||
},
|
||||
},
|
||||
take: limit,
|
||||
skip: offset,
|
||||
},
|
||||
take: limit,
|
||||
skip: offset,
|
||||
},
|
||||
transactionManager,
|
||||
);
|
||||
transactionManager,
|
||||
);
|
||||
|
||||
return orphanThreads.map(({ id }) => id);
|
||||
},
|
||||
async (
|
||||
ids: string[],
|
||||
workspaceId: string,
|
||||
transactionManager?: EntityManager,
|
||||
) => {
|
||||
await messageThreadRepository.delete(ids, transactionManager);
|
||||
},
|
||||
transactionManager,
|
||||
);
|
||||
});
|
||||
return orphanThreads.map(({ id }) => id);
|
||||
},
|
||||
async (
|
||||
ids: string[],
|
||||
_workspaceId: string,
|
||||
transactionManager?: WorkspaceEntityManager,
|
||||
) => {
|
||||
await messageThreadRepository.delete(ids, transactionManager);
|
||||
},
|
||||
transactionManager,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { EntityManager } from 'typeorm';
|
||||
import { WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
|
||||
|
||||
export const deleteUsingPagination = async (
|
||||
workspaceId: string,
|
||||
@ -7,14 +7,14 @@ export const deleteUsingPagination = async (
|
||||
limit: number,
|
||||
offset: number,
|
||||
workspaceId: string,
|
||||
transactionManager?: EntityManager,
|
||||
transactionManager?: WorkspaceEntityManager,
|
||||
) => Promise<string[]>,
|
||||
deleter: (
|
||||
ids: string[],
|
||||
workspaceId: string,
|
||||
transactionManager?: EntityManager,
|
||||
transactionManager?: WorkspaceEntityManager,
|
||||
) => Promise<void>,
|
||||
transactionManager?: EntityManager,
|
||||
transactionManager?: WorkspaceEntityManager,
|
||||
) => {
|
||||
let hasMoreData = true;
|
||||
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { EntityManager } from 'typeorm';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
|
||||
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||
import { MessageChannelMessageAssociationWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-channel-message-association.workspace-entity';
|
||||
import { MessageThreadWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-thread.workspace-entity';
|
||||
@ -16,7 +16,7 @@ export class MessagingMessageService {
|
||||
public async saveMessagesWithinTransaction(
|
||||
messages: MessageWithParticipants[],
|
||||
messageChannelId: string,
|
||||
transactionManager: EntityManager,
|
||||
transactionManager: WorkspaceEntityManager,
|
||||
): Promise<{
|
||||
createdMessages: Partial<MessageWorkspaceEntity>[];
|
||||
messageExternalIdsAndIdsMap: Map<string, string>;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { EntityManager, Repository } from 'typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { DatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/enums/database-event-action';
|
||||
import { InjectMessageQueue } from 'src/engine/core-modules/message-queue/decorators/message-queue.decorator';
|
||||
@ -9,6 +9,7 @@ import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queu
|
||||
import { MessageQueueService } from 'src/engine/core-modules/message-queue/services/message-queue.service';
|
||||
import { FieldActorSource } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
|
||||
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||
import { WorkspaceEventEmitter } from 'src/engine/workspace-event-emitter/workspace-event-emitter';
|
||||
import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
|
||||
@ -55,7 +56,7 @@ export class MessagingSaveMessagesAndEnqueueContactCreationService {
|
||||
|
||||
const createdMessagesWithParticipants =
|
||||
await workspaceDataSource?.transaction(
|
||||
async (transactionManager: EntityManager) => {
|
||||
async (transactionManager: WorkspaceEntityManager) => {
|
||||
const { messageExternalIdsAndIdsMap, createdMessages } =
|
||||
await this.messageService.saveMessagesWithinTransaction(
|
||||
messagesToSave,
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { EntityManager } from 'typeorm';
|
||||
|
||||
import { WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
|
||||
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||
import { MatchParticipantService } from 'src/modules/match-participant/match-participant.service';
|
||||
import { MessageParticipantWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-participant.workspace-entity';
|
||||
@ -16,7 +15,7 @@ export class MessagingMessageParticipantService {
|
||||
|
||||
public async saveMessageParticipants(
|
||||
participants: ParticipantWithMessageId[],
|
||||
transactionManager?: EntityManager,
|
||||
transactionManager?: WorkspaceEntityManager,
|
||||
): Promise<void> {
|
||||
const messageParticipantRepository =
|
||||
await this.twentyORMManager.getRepository<MessageParticipantWorkspaceEntity>(
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { EntityManager } from 'typeorm';
|
||||
|
||||
import { ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
|
||||
import { objectRecordDiffMerge } from 'src/engine/core-modules/event-emitter/utils/object-record-diff-merge';
|
||||
@ -159,7 +157,6 @@ export class TimelineActivityRepository {
|
||||
linkedObjectMetadataId: string | undefined;
|
||||
}[],
|
||||
workspaceId: string,
|
||||
transactionManager?: EntityManager,
|
||||
) {
|
||||
if (activities.length === 0) {
|
||||
return;
|
||||
@ -191,7 +188,6 @@ export class TimelineActivityRepository {
|
||||
])
|
||||
.flat(),
|
||||
workspaceId,
|
||||
transactionManager,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,14 +1,13 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { EntityManager } from 'typeorm';
|
||||
|
||||
import { WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
|
||||
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||
import { WorkflowEventListenerWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-event-listener.workspace-entity';
|
||||
import {
|
||||
AutomatedTriggerType,
|
||||
AutomatedTriggerSettings,
|
||||
AutomatedTriggerType,
|
||||
WorkflowAutomatedTriggerWorkspaceEntity,
|
||||
} from 'src/modules/workflow/common/standard-objects/workflow-automated-trigger.workspace-entity';
|
||||
import { WorkflowEventListenerWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-event-listener.workspace-entity';
|
||||
|
||||
@Injectable()
|
||||
export class AutomatedTriggerWorkspaceService {
|
||||
@ -21,7 +20,7 @@ export class AutomatedTriggerWorkspaceService {
|
||||
settings,
|
||||
}: {
|
||||
workflowId: string;
|
||||
manager: EntityManager;
|
||||
manager: WorkspaceEntityManager;
|
||||
type: AutomatedTriggerType;
|
||||
settings: AutomatedTriggerSettings;
|
||||
}) {
|
||||
@ -68,7 +67,7 @@ export class AutomatedTriggerWorkspaceService {
|
||||
manager,
|
||||
}: {
|
||||
workflowId: string;
|
||||
manager: EntityManager;
|
||||
manager: WorkspaceEntityManager;
|
||||
}) {
|
||||
// Todo: remove workflowEventListenerRepository updates when data are migrated to workflowAutomatedTrigger
|
||||
const workflowEventListenerRepository =
|
||||
|
||||
@ -1,15 +1,17 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { EntityManager, Repository } from 'typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { DatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/enums/database-event-action';
|
||||
import { ActorMetadata } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
|
||||
import { ScopedWorkspaceContextFactory } from 'src/engine/twenty-orm/factories/scoped-workspace-context.factory';
|
||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
||||
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||
import { WorkspaceEventEmitter } from 'src/engine/workspace-event-emitter/workspace-event-emitter';
|
||||
import { AutomatedTriggerType } from 'src/modules/workflow/common/standard-objects/workflow-automated-trigger.workspace-entity';
|
||||
import {
|
||||
WorkflowVersionStatus,
|
||||
WorkflowVersionWorkspaceEntity,
|
||||
@ -20,6 +22,7 @@ import { WorkflowCommonWorkspaceService } from 'src/modules/workflow/common/work
|
||||
import { WorkflowRunnerWorkspaceService } from 'src/modules/workflow/workflow-runner/workspace-services/workflow-runner.workspace-service';
|
||||
import { WORKFLOW_VERSION_STATUS_UPDATED } from 'src/modules/workflow/workflow-status/constants/workflow-version-status-updated.constants';
|
||||
import { WorkflowVersionStatusUpdate } from 'src/modules/workflow/workflow-status/jobs/workflow-statuses-update.job';
|
||||
import { AutomatedTriggerWorkspaceService } from 'src/modules/workflow/workflow-trigger/automated-trigger/automated-trigger.workspace-service';
|
||||
import {
|
||||
WorkflowTriggerException,
|
||||
WorkflowTriggerExceptionCode,
|
||||
@ -28,8 +31,6 @@ import { WorkflowTriggerType } from 'src/modules/workflow/workflow-trigger/types
|
||||
import { assertVersionCanBeActivated } from 'src/modules/workflow/workflow-trigger/utils/assert-version-can-be-activated.util';
|
||||
import { computeCronPatternFromSchedule } from 'src/modules/workflow/workflow-trigger/utils/compute-cron-pattern-from-schedule';
|
||||
import { assertNever } from 'src/utils/assert';
|
||||
import { AutomatedTriggerWorkspaceService } from 'src/modules/workflow/workflow-trigger/automated-trigger/automated-trigger.workspace-service';
|
||||
import { AutomatedTriggerType } from 'src/modules/workflow/common/standard-objects/workflow-automated-trigger.workspace-entity';
|
||||
|
||||
@Injectable()
|
||||
export class WorkflowTriggerWorkspaceService {
|
||||
@ -174,7 +175,7 @@ export class WorkflowTriggerWorkspaceService {
|
||||
workflowVersion: WorkflowVersionWorkspaceEntity,
|
||||
workflowRepository: WorkspaceRepository<WorkflowWorkspaceEntity>,
|
||||
workflowVersionRepository: WorkspaceRepository<WorkflowVersionWorkspaceEntity>,
|
||||
manager: EntityManager,
|
||||
manager: WorkspaceEntityManager,
|
||||
) {
|
||||
if (
|
||||
workflow.lastPublishedVersionId &&
|
||||
@ -207,7 +208,7 @@ export class WorkflowTriggerWorkspaceService {
|
||||
private async performDeactivationSteps(
|
||||
workflowVersionId: string,
|
||||
workflowVersionRepository: WorkspaceRepository<WorkflowVersionWorkspaceEntity>,
|
||||
manager: EntityManager,
|
||||
manager: WorkspaceEntityManager,
|
||||
) {
|
||||
const workflowVersionNullable = await workflowVersionRepository.findOne({
|
||||
where: { id: workflowVersionId },
|
||||
@ -234,7 +235,7 @@ export class WorkflowTriggerWorkspaceService {
|
||||
private async setActiveVersionStatus(
|
||||
workflowVersion: WorkflowVersionWorkspaceEntity,
|
||||
workflowVersionRepository: WorkspaceRepository<WorkflowVersionWorkspaceEntity>,
|
||||
manager: EntityManager,
|
||||
manager: WorkspaceEntityManager,
|
||||
) {
|
||||
const activeWorkflowVersions = await workflowVersionRepository.find(
|
||||
{
|
||||
@ -269,7 +270,7 @@ export class WorkflowTriggerWorkspaceService {
|
||||
private async setDeactivatedVersionStatus(
|
||||
workflowVersion: WorkflowVersionWorkspaceEntity,
|
||||
workflowVersionRepository: WorkspaceRepository<WorkflowVersionWorkspaceEntity>,
|
||||
manager: EntityManager,
|
||||
manager: WorkspaceEntityManager,
|
||||
) {
|
||||
if (workflowVersion.status !== WorkflowVersionStatus.ACTIVE) {
|
||||
throw new WorkflowTriggerException(
|
||||
@ -296,7 +297,7 @@ export class WorkflowTriggerWorkspaceService {
|
||||
newPublishedVersionId: string,
|
||||
workflowRepository: WorkspaceRepository<WorkflowWorkspaceEntity>,
|
||||
workflowVersionRepository: WorkspaceRepository<WorkflowVersionWorkspaceEntity>,
|
||||
manager: EntityManager,
|
||||
manager: WorkspaceEntityManager,
|
||||
) {
|
||||
if (workflow.lastPublishedVersionId === newPublishedVersionId) {
|
||||
return;
|
||||
@ -319,7 +320,7 @@ export class WorkflowTriggerWorkspaceService {
|
||||
|
||||
private async enableTrigger(
|
||||
workflowVersion: WorkflowVersionWorkspaceEntity,
|
||||
manager: EntityManager,
|
||||
manager: WorkspaceEntityManager,
|
||||
) {
|
||||
assertWorkflowVersionTriggerIsDefined(workflowVersion);
|
||||
|
||||
@ -359,7 +360,7 @@ export class WorkflowTriggerWorkspaceService {
|
||||
|
||||
private async disableTrigger(
|
||||
workflowVersion: WorkflowVersionWorkspaceEntity,
|
||||
manager: EntityManager,
|
||||
manager: WorkspaceEntityManager,
|
||||
) {
|
||||
assertWorkflowVersionTriggerIsDefined(workflowVersion);
|
||||
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||
|
||||
import { EntityManager } from 'typeorm';
|
||||
|
||||
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
||||
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
|
||||
|
||||
@ -50,7 +48,6 @@ export class WorkspaceMemberRepository {
|
||||
|
||||
public async getAllByWorkspaceId(
|
||||
workspaceId: string,
|
||||
transactionManager?: EntityManager,
|
||||
): Promise<WorkspaceMemberWorkspaceEntity[]> {
|
||||
const dataSourceSchema =
|
||||
this.workspaceDataSourceService.getSchemaName(workspaceId);
|
||||
@ -60,7 +57,6 @@ export class WorkspaceMemberRepository {
|
||||
`SELECT * FROM ${dataSourceSchema}."workspaceMember"`,
|
||||
[],
|
||||
workspaceId,
|
||||
transactionManager,
|
||||
);
|
||||
|
||||
return workspaceMembers;
|
||||
|
||||
Reference in New Issue
Block a user