Deprecate inject workspace repo (#6353)
This commit is contained in:
@ -4,42 +4,42 @@ import { EntityManager } from 'typeorm';
|
|||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
|
|
||||||
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
||||||
|
import { InjectMessageQueue } from 'src/engine/integrations/message-queue/decorators/message-queue.decorator';
|
||||||
import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants';
|
import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants';
|
||||||
import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service';
|
import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service';
|
||||||
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
|
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
|
||||||
|
import { WorkspaceDataSource } from 'src/engine/twenty-orm/datasource/workspace.datasource';
|
||||||
|
import { InjectWorkspaceDatasource } from 'src/engine/twenty-orm/decorators/inject-workspace-datasource.decorator';
|
||||||
|
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||||
|
import {
|
||||||
|
CalendarEventListFetchJob,
|
||||||
|
CalendarEventsImportJobData,
|
||||||
|
} from 'src/modules/calendar/calendar-event-import-manager/jobs/calendar-event-list-fetch.job';
|
||||||
|
import {
|
||||||
|
CalendarChannelVisibility,
|
||||||
|
CalendarChannelWorkspaceEntity,
|
||||||
|
} from 'src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity';
|
||||||
import { ConnectedAccountRepository } from 'src/modules/connected-account/repositories/connected-account.repository';
|
import { ConnectedAccountRepository } from 'src/modules/connected-account/repositories/connected-account.repository';
|
||||||
import {
|
import {
|
||||||
ConnectedAccountWorkspaceEntity,
|
|
||||||
ConnectedAccountProvider,
|
ConnectedAccountProvider,
|
||||||
|
ConnectedAccountWorkspaceEntity,
|
||||||
} from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
|
} from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
|
||||||
import { MessageChannelRepository } from 'src/modules/messaging/common/repositories/message-channel.repository';
|
import { MessageChannelRepository } from 'src/modules/messaging/common/repositories/message-channel.repository';
|
||||||
import {
|
import {
|
||||||
MessageChannelWorkspaceEntity,
|
MessageChannelSyncStatus,
|
||||||
MessageChannelType,
|
MessageChannelType,
|
||||||
MessageChannelVisibility,
|
MessageChannelVisibility,
|
||||||
MessageChannelSyncStatus,
|
MessageChannelWorkspaceEntity,
|
||||||
} from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
|
} from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
|
||||||
import {
|
import {
|
||||||
MessagingMessageListFetchJob,
|
MessagingMessageListFetchJob,
|
||||||
MessagingMessageListFetchJobData,
|
MessagingMessageListFetchJobData,
|
||||||
} from 'src/modules/messaging/message-import-manager/jobs/messaging-message-list-fetch.job';
|
} from 'src/modules/messaging/message-import-manager/jobs/messaging-message-list-fetch.job';
|
||||||
import { InjectMessageQueue } from 'src/engine/integrations/message-queue/decorators/message-queue.decorator';
|
|
||||||
import { InjectWorkspaceRepository } from 'src/engine/twenty-orm/decorators/inject-workspace-repository.decorator';
|
|
||||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
|
||||||
import { WorkspaceDataSource } from 'src/engine/twenty-orm/datasource/workspace.datasource';
|
|
||||||
import { InjectWorkspaceDatasource } from 'src/engine/twenty-orm/decorators/inject-workspace-datasource.decorator';
|
|
||||||
import {
|
|
||||||
CalendarChannelWorkspaceEntity,
|
|
||||||
CalendarChannelVisibility,
|
|
||||||
} from 'src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity';
|
|
||||||
import {
|
|
||||||
CalendarEventsImportJobData,
|
|
||||||
CalendarEventListFetchJob,
|
|
||||||
} from 'src/modules/calendar/calendar-event-import-manager/jobs/calendar-event-list-fetch.job';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class GoogleAPIsService {
|
export class GoogleAPIsService {
|
||||||
constructor(
|
constructor(
|
||||||
|
private readonly twentyORMManager: TwentyORMManager,
|
||||||
@InjectWorkspaceDatasource()
|
@InjectWorkspaceDatasource()
|
||||||
private readonly workspaceDataSource: WorkspaceDataSource,
|
private readonly workspaceDataSource: WorkspaceDataSource,
|
||||||
@InjectMessageQueue(MessageQueue.messagingQueue)
|
@InjectMessageQueue(MessageQueue.messagingQueue)
|
||||||
@ -51,8 +51,6 @@ export class GoogleAPIsService {
|
|||||||
private readonly connectedAccountRepository: ConnectedAccountRepository,
|
private readonly connectedAccountRepository: ConnectedAccountRepository,
|
||||||
@InjectObjectMetadataRepository(MessageChannelWorkspaceEntity)
|
@InjectObjectMetadataRepository(MessageChannelWorkspaceEntity)
|
||||||
private readonly messageChannelRepository: MessageChannelRepository,
|
private readonly messageChannelRepository: MessageChannelRepository,
|
||||||
@InjectWorkspaceRepository(CalendarChannelWorkspaceEntity)
|
|
||||||
private readonly calendarChannelRepository: WorkspaceRepository<CalendarChannelWorkspaceEntity>,
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async refreshGoogleRefreshToken(input: {
|
async refreshGoogleRefreshToken(input: {
|
||||||
@ -86,6 +84,11 @@ export class GoogleAPIsService {
|
|||||||
const existingAccountId = connectedAccounts?.[0]?.id;
|
const existingAccountId = connectedAccounts?.[0]?.id;
|
||||||
const newOrExistingConnectedAccountId = existingAccountId ?? v4();
|
const newOrExistingConnectedAccountId = existingAccountId ?? v4();
|
||||||
|
|
||||||
|
const calendarChannelRepository =
|
||||||
|
await this.twentyORMManager.getRepository<CalendarChannelWorkspaceEntity>(
|
||||||
|
'calendarChannel',
|
||||||
|
);
|
||||||
|
|
||||||
await this.workspaceDataSource.transaction(
|
await this.workspaceDataSource.transaction(
|
||||||
async (manager: EntityManager) => {
|
async (manager: EntityManager) => {
|
||||||
if (!existingAccountId) {
|
if (!existingAccountId) {
|
||||||
@ -117,7 +120,7 @@ export class GoogleAPIsService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (isCalendarEnabled) {
|
if (isCalendarEnabled) {
|
||||||
await this.calendarChannelRepository.save(
|
await calendarChannelRepository.save(
|
||||||
{
|
{
|
||||||
id: v4(),
|
id: v4(),
|
||||||
connectedAccountId: newOrExistingConnectedAccountId,
|
connectedAccountId: newOrExistingConnectedAccountId,
|
||||||
@ -167,7 +170,7 @@ export class GoogleAPIsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isCalendarEnabled) {
|
if (isCalendarEnabled) {
|
||||||
const calendarChannels = await this.calendarChannelRepository.find({
|
const calendarChannels = await calendarChannelRepository.find({
|
||||||
where: {
|
where: {
|
||||||
connectedAccountId: newOrExistingConnectedAccountId,
|
connectedAccountId: newOrExistingConnectedAccountId,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,20 +1,22 @@
|
|||||||
import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
|
|
||||||
import { UseGuards } from '@nestjs/common';
|
import { UseGuards } from '@nestjs/common';
|
||||||
|
import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
AvailableProduct,
|
AvailableProduct,
|
||||||
BillingWorkspaceService,
|
BillingWorkspaceService,
|
||||||
} from 'src/engine/core-modules/billing/billing.workspace-service';
|
} from 'src/engine/core-modules/billing/billing.workspace-service';
|
||||||
import { ProductInput } from 'src/engine/core-modules/billing/dto/product.input';
|
|
||||||
import { assert } from 'src/utils/assert';
|
|
||||||
import { ProductPricesEntity } from 'src/engine/core-modules/billing/dto/product-prices.entity';
|
|
||||||
import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard';
|
|
||||||
import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator';
|
|
||||||
import { User } from 'src/engine/core-modules/user/user.entity';
|
|
||||||
import { CheckoutSessionInput } from 'src/engine/core-modules/billing/dto/checkout-session.input';
|
|
||||||
import { SessionEntity } from 'src/engine/core-modules/billing/dto/session.entity';
|
|
||||||
import { BillingSessionInput } from 'src/engine/core-modules/billing/dto/billing-session.input';
|
import { BillingSessionInput } from 'src/engine/core-modules/billing/dto/billing-session.input';
|
||||||
|
import { CheckoutSessionInput } from 'src/engine/core-modules/billing/dto/checkout-session.input';
|
||||||
|
import { ProductPricesEntity } from 'src/engine/core-modules/billing/dto/product-prices.entity';
|
||||||
|
import { ProductInput } from 'src/engine/core-modules/billing/dto/product.input';
|
||||||
|
import { SessionEntity } from 'src/engine/core-modules/billing/dto/session.entity';
|
||||||
import { UpdateBillingEntity } from 'src/engine/core-modules/billing/dto/update-billing.entity';
|
import { UpdateBillingEntity } from 'src/engine/core-modules/billing/dto/update-billing.entity';
|
||||||
|
import { User } from 'src/engine/core-modules/user/user.entity';
|
||||||
|
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||||
|
import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator';
|
||||||
|
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
||||||
|
import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard';
|
||||||
|
import { assert } from 'src/utils/assert';
|
||||||
|
|
||||||
@Resolver()
|
@Resolver()
|
||||||
export class BillingResolver {
|
export class BillingResolver {
|
||||||
@ -60,6 +62,7 @@ export class BillingResolver {
|
|||||||
@Mutation(() => SessionEntity)
|
@Mutation(() => SessionEntity)
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
async checkoutSession(
|
async checkoutSession(
|
||||||
|
@AuthWorkspace() workspace: Workspace,
|
||||||
@AuthUser() user: User,
|
@AuthUser() user: User,
|
||||||
@Args() { recurringInterval, successUrlPath }: CheckoutSessionInput,
|
@Args() { recurringInterval, successUrlPath }: CheckoutSessionInput,
|
||||||
) {
|
) {
|
||||||
@ -87,6 +90,7 @@ export class BillingResolver {
|
|||||||
return {
|
return {
|
||||||
url: await this.billingWorkspaceService.computeCheckoutSessionURL(
|
url: await this.billingWorkspaceService.computeCheckoutSessionURL(
|
||||||
user,
|
user,
|
||||||
|
workspace,
|
||||||
stripePriceId,
|
stripePriceId,
|
||||||
successUrlPath,
|
successUrlPath,
|
||||||
),
|
),
|
||||||
|
|||||||
@ -4,24 +4,24 @@ import { InjectRepository } from '@nestjs/typeorm';
|
|||||||
import Stripe from 'stripe';
|
import Stripe from 'stripe';
|
||||||
import { Not, Repository } from 'typeorm';
|
import { Not, Repository } from 'typeorm';
|
||||||
|
|
||||||
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
import { BillingService } from 'src/engine/core-modules/billing/billing.service';
|
||||||
import { StripeService } from 'src/engine/core-modules/billing/stripe/stripe.service';
|
import { ProductPriceEntity } from 'src/engine/core-modules/billing/dto/product-price.entity';
|
||||||
|
import { BillingSubscriptionItem } from 'src/engine/core-modules/billing/entities/billing-subscription-item.entity';
|
||||||
import {
|
import {
|
||||||
BillingSubscription,
|
BillingSubscription,
|
||||||
SubscriptionInterval,
|
SubscriptionInterval,
|
||||||
SubscriptionStatus,
|
SubscriptionStatus,
|
||||||
} from 'src/engine/core-modules/billing/entities/billing-subscription.entity';
|
} from 'src/engine/core-modules/billing/entities/billing-subscription.entity';
|
||||||
import { BillingSubscriptionItem } from 'src/engine/core-modules/billing/entities/billing-subscription-item.entity';
|
import { StripeService } from 'src/engine/core-modules/billing/stripe/stripe.service';
|
||||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
|
||||||
import { ProductPriceEntity } from 'src/engine/core-modules/billing/dto/product-price.entity';
|
|
||||||
import { User } from 'src/engine/core-modules/user/user.entity';
|
|
||||||
import { assert } from 'src/utils/assert';
|
|
||||||
import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service';
|
|
||||||
import {
|
import {
|
||||||
FeatureFlagEntity,
|
FeatureFlagEntity,
|
||||||
FeatureFlagKeys,
|
FeatureFlagKeys,
|
||||||
} from 'src/engine/core-modules/feature-flag/feature-flag.entity';
|
} from 'src/engine/core-modules/feature-flag/feature-flag.entity';
|
||||||
import { BillingService } from 'src/engine/core-modules/billing/billing.service';
|
import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service';
|
||||||
|
import { User } from 'src/engine/core-modules/user/user.entity';
|
||||||
|
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||||
|
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
||||||
|
import { assert } from 'src/utils/assert';
|
||||||
|
|
||||||
export enum AvailableProduct {
|
export enum AvailableProduct {
|
||||||
BasePlan = 'base-plan',
|
BasePlan = 'base-plan',
|
||||||
@ -219,6 +219,7 @@ export class BillingWorkspaceService {
|
|||||||
|
|
||||||
async computeCheckoutSessionURL(
|
async computeCheckoutSessionURL(
|
||||||
user: User,
|
user: User,
|
||||||
|
workspace: Workspace,
|
||||||
priceId: string,
|
priceId: string,
|
||||||
successUrlPath?: string,
|
successUrlPath?: string,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
@ -228,7 +229,7 @@ export class BillingWorkspaceService {
|
|||||||
: frontBaseUrl;
|
: frontBaseUrl;
|
||||||
|
|
||||||
const quantity =
|
const quantity =
|
||||||
(await this.userWorkspaceService.getWorkspaceMemberCount()) || 1;
|
(await this.userWorkspaceService.getUserCount(workspace.id)) || 1;
|
||||||
|
|
||||||
const stripeCustomerId = (
|
const stripeCustomerId = (
|
||||||
await this.billingSubscriptionRepository.findOneBy({
|
await this.billingSubscriptionRepository.findOneBy({
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import { Logger, Scope } from '@nestjs/common';
|
import { Logger, Scope } from '@nestjs/common';
|
||||||
|
|
||||||
import { BillingWorkspaceService } from 'src/engine/core-modules/billing/billing.workspace-service';
|
import { BillingWorkspaceService } from 'src/engine/core-modules/billing/billing.workspace-service';
|
||||||
import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service';
|
|
||||||
import { StripeService } from 'src/engine/core-modules/billing/stripe/stripe.service';
|
import { StripeService } from 'src/engine/core-modules/billing/stripe/stripe.service';
|
||||||
|
import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service';
|
||||||
|
import { Process } from 'src/engine/integrations/message-queue/decorators/process.decorator';
|
||||||
import { Processor } from 'src/engine/integrations/message-queue/decorators/processor.decorator';
|
import { Processor } from 'src/engine/integrations/message-queue/decorators/processor.decorator';
|
||||||
import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants';
|
import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants';
|
||||||
import { Process } from 'src/engine/integrations/message-queue/decorators/process.decorator';
|
|
||||||
export type UpdateSubscriptionJobData = { workspaceId: string };
|
export type UpdateSubscriptionJobData = { workspaceId: string };
|
||||||
|
|
||||||
@Processor({
|
@Processor({
|
||||||
@ -23,8 +23,9 @@ export class UpdateSubscriptionJob {
|
|||||||
|
|
||||||
@Process(UpdateSubscriptionJob.name)
|
@Process(UpdateSubscriptionJob.name)
|
||||||
async handle(data: UpdateSubscriptionJobData): Promise<void> {
|
async handle(data: UpdateSubscriptionJobData): Promise<void> {
|
||||||
const workspaceMembersCount =
|
const workspaceMembersCount = await this.userWorkspaceService.getUserCount(
|
||||||
await this.userWorkspaceService.getWorkspaceMemberCount();
|
data.workspaceId,
|
||||||
|
);
|
||||||
|
|
||||||
if (!workspaceMembersCount || workspaceMembersCount <= 0) {
|
if (!workspaceMembersCount || workspaceMembersCount <= 0) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -1,20 +1,20 @@
|
|||||||
|
/* eslint-disable @nx/workspace-inject-workspace-repository */
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { BillingWorkspaceService } from 'src/engine/core-modules/billing/billing.workspace-service';
|
||||||
|
import { SubscriptionStatus } from 'src/engine/core-modules/billing/entities/billing-subscription.entity';
|
||||||
import { KeyValuePairService } from 'src/engine/core-modules/key-value-pair/key-value-pair.service';
|
import { KeyValuePairService } from 'src/engine/core-modules/key-value-pair/key-value-pair.service';
|
||||||
import { OnboardingStatus } from 'src/engine/core-modules/onboarding/enums/onboarding-status.enum';
|
import { OnboardingStatus } from 'src/engine/core-modules/onboarding/enums/onboarding-status.enum';
|
||||||
|
import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service';
|
||||||
import { User } from 'src/engine/core-modules/user/user.entity';
|
import { User } from 'src/engine/core-modules/user/user.entity';
|
||||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||||
import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service';
|
|
||||||
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
|
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
|
||||||
import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
|
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||||
import { ConnectedAccountRepository } from 'src/modules/connected-account/repositories/connected-account.repository';
|
|
||||||
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
|
|
||||||
import { WorkspaceManagerService } from 'src/engine/workspace-manager/workspace-manager.service';
|
import { WorkspaceManagerService } from 'src/engine/workspace-manager/workspace-manager.service';
|
||||||
import { InjectWorkspaceRepository } from 'src/engine/twenty-orm/decorators/inject-workspace-repository.decorator';
|
import { ConnectedAccountRepository } from 'src/modules/connected-account/repositories/connected-account.repository';
|
||||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
|
||||||
import { SubscriptionStatus } from 'src/engine/core-modules/billing/entities/billing-subscription.entity';
|
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
|
||||||
import { isDefined } from 'src/utils/is-defined';
|
import { isDefined } from 'src/utils/is-defined';
|
||||||
import { BillingWorkspaceService } from 'src/engine/core-modules/billing/billing.workspace-service';
|
|
||||||
|
|
||||||
enum OnboardingStepValues {
|
enum OnboardingStepValues {
|
||||||
SKIPPED = 'SKIPPED',
|
SKIPPED = 'SKIPPED',
|
||||||
@ -33,14 +33,13 @@ type OnboardingKeyValueType = {
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class OnboardingService {
|
export class OnboardingService {
|
||||||
constructor(
|
constructor(
|
||||||
|
private readonly twentyORMManager: TwentyORMManager,
|
||||||
private readonly billingWorkspaceService: BillingWorkspaceService,
|
private readonly billingWorkspaceService: BillingWorkspaceService,
|
||||||
private readonly workspaceManagerService: WorkspaceManagerService,
|
private readonly workspaceManagerService: WorkspaceManagerService,
|
||||||
private readonly userWorkspaceService: UserWorkspaceService,
|
private readonly userWorkspaceService: UserWorkspaceService,
|
||||||
private readonly keyValuePairService: KeyValuePairService<OnboardingKeyValueType>,
|
private readonly keyValuePairService: KeyValuePairService<OnboardingKeyValueType>,
|
||||||
@InjectObjectMetadataRepository(ConnectedAccountWorkspaceEntity)
|
@InjectObjectMetadataRepository(ConnectedAccountWorkspaceEntity)
|
||||||
private readonly connectedAccountRepository: ConnectedAccountRepository,
|
private readonly connectedAccountRepository: ConnectedAccountRepository,
|
||||||
@InjectWorkspaceRepository(WorkspaceMemberWorkspaceEntity)
|
|
||||||
private readonly workspaceMemberRepository: WorkspaceRepository<WorkspaceMemberWorkspaceEntity>,
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
private async isSubscriptionIncompleteOnboardingStatus(user: User) {
|
private async isSubscriptionIncompleteOnboardingStatus(user: User) {
|
||||||
@ -71,7 +70,12 @@ export class OnboardingService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async isProfileCreationOnboardingStatus(user: User) {
|
private async isProfileCreationOnboardingStatus(user: User) {
|
||||||
const workspaceMember = await this.workspaceMemberRepository.findOneBy({
|
const workspaceMemberRepository =
|
||||||
|
await this.twentyORMManager.getRepository<WorkspaceMemberWorkspaceEntity>(
|
||||||
|
'workspaceMember',
|
||||||
|
);
|
||||||
|
|
||||||
|
const workspaceMember = await workspaceMemberRepository.findOneBy({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -104,8 +108,9 @@ export class OnboardingService {
|
|||||||
});
|
});
|
||||||
const isInviteTeamSkipped =
|
const isInviteTeamSkipped =
|
||||||
inviteTeamValue === OnboardingStepValues.SKIPPED;
|
inviteTeamValue === OnboardingStepValues.SKIPPED;
|
||||||
const workspaceMemberCount =
|
const workspaceMemberCount = await this.userWorkspaceService.getUserCount(
|
||||||
await this.userWorkspaceService.getWorkspaceMemberCount();
|
workspace.id,
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
!isInviteTeamSkipped &&
|
!isInviteTeamSkipped &&
|
||||||
|
|||||||
@ -11,8 +11,6 @@ import { User } from 'src/engine/core-modules/user/user.entity';
|
|||||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||||
import { ObjectRecordCreateEvent } from 'src/engine/integrations/event-emitter/types/object-record-create.event';
|
import { ObjectRecordCreateEvent } from 'src/engine/integrations/event-emitter/types/object-record-create.event';
|
||||||
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
|
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
|
||||||
import { InjectWorkspaceRepository } from 'src/engine/twenty-orm/decorators/inject-workspace-repository.decorator';
|
|
||||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
|
||||||
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
|
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
|
||||||
import { assert } from 'src/utils/assert';
|
import { assert } from 'src/utils/assert';
|
||||||
|
|
||||||
@ -22,8 +20,6 @@ export class UserWorkspaceService extends TypeOrmQueryService<UserWorkspace> {
|
|||||||
private readonly userWorkspaceRepository: Repository<UserWorkspace>,
|
private readonly userWorkspaceRepository: Repository<UserWorkspace>,
|
||||||
@InjectRepository(User, 'core')
|
@InjectRepository(User, 'core')
|
||||||
private readonly userRepository: Repository<User>,
|
private readonly userRepository: Repository<User>,
|
||||||
@InjectWorkspaceRepository(WorkspaceMemberWorkspaceEntity)
|
|
||||||
private readonly workspaceMemberRepository: WorkspaceRepository<WorkspaceMemberWorkspaceEntity>,
|
|
||||||
private readonly dataSourceService: DataSourceService,
|
private readonly dataSourceService: DataSourceService,
|
||||||
private readonly typeORMService: TypeORMService,
|
private readonly typeORMService: TypeORMService,
|
||||||
private eventEmitter: EventEmitter2,
|
private eventEmitter: EventEmitter2,
|
||||||
@ -107,13 +103,10 @@ export class UserWorkspaceService extends TypeOrmQueryService<UserWorkspace> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getWorkspaceMemberCount(): Promise<number | undefined> {
|
public async getUserCount(workspaceId): Promise<number | undefined> {
|
||||||
// TODO: to refactor, this could happen today for the first signup since the workspace does not exist yet
|
return await this.userWorkspaceRepository.countBy({
|
||||||
if (!this.workspaceMemberRepository) {
|
workspaceId,
|
||||||
return undefined;
|
});
|
||||||
}
|
|
||||||
|
|
||||||
return await this.workspaceMemberRepository.count();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async checkUserWorkspaceExists(
|
async checkUserWorkspaceExists(
|
||||||
|
|||||||
@ -1,33 +1,33 @@
|
|||||||
|
import { UseGuards } from '@nestjs/common';
|
||||||
import {
|
import {
|
||||||
Resolver,
|
|
||||||
Query,
|
|
||||||
Args,
|
Args,
|
||||||
Mutation,
|
Mutation,
|
||||||
ResolveField,
|
|
||||||
Parent,
|
Parent,
|
||||||
|
Query,
|
||||||
|
ResolveField,
|
||||||
|
Resolver,
|
||||||
} from '@nestjs/graphql';
|
} from '@nestjs/graphql';
|
||||||
import { UseGuards } from '@nestjs/common';
|
|
||||||
|
|
||||||
import { FileUpload, GraphQLUpload } from 'graphql-upload';
|
import { FileUpload, GraphQLUpload } from 'graphql-upload';
|
||||||
|
|
||||||
import { FileFolder } from 'src/engine/core-modules/file/interfaces/file-folder.interface';
|
import { FileFolder } from 'src/engine/core-modules/file/interfaces/file-folder.interface';
|
||||||
|
|
||||||
import { streamToBuffer } from 'src/utils/stream-to-buffer';
|
|
||||||
import { FileUploadService } from 'src/engine/core-modules/file/file-upload/services/file-upload.service';
|
|
||||||
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
|
||||||
import { assert } from 'src/utils/assert';
|
|
||||||
import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard';
|
|
||||||
import { UpdateWorkspaceInput } from 'src/engine/core-modules/workspace/dtos/update-workspace-input';
|
|
||||||
import { User } from 'src/engine/core-modules/user/user.entity';
|
|
||||||
import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator';
|
|
||||||
import { ActivateWorkspaceInput } from 'src/engine/core-modules/workspace/dtos/activate-workspace-input';
|
|
||||||
import { BillingSubscription } from 'src/engine/core-modules/billing/entities/billing-subscription.entity';
|
|
||||||
import { BillingWorkspaceService } from 'src/engine/core-modules/billing/billing.workspace-service';
|
import { BillingWorkspaceService } from 'src/engine/core-modules/billing/billing.workspace-service';
|
||||||
import { DemoEnvGuard } from 'src/engine/guards/demo.env.guard';
|
import { BillingSubscription } from 'src/engine/core-modules/billing/entities/billing-subscription.entity';
|
||||||
import { WorkspaceCacheVersionService } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.service';
|
import { FileUploadService } from 'src/engine/core-modules/file/file-upload/services/file-upload.service';
|
||||||
|
import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service';
|
||||||
|
import { User } from 'src/engine/core-modules/user/user.entity';
|
||||||
|
import { ActivateWorkspaceInput } from 'src/engine/core-modules/workspace/dtos/activate-workspace-input';
|
||||||
import { SendInviteLink } from 'src/engine/core-modules/workspace/dtos/send-invite-link.entity';
|
import { SendInviteLink } from 'src/engine/core-modules/workspace/dtos/send-invite-link.entity';
|
||||||
import { SendInviteLinkInput } from 'src/engine/core-modules/workspace/dtos/send-invite-link.input';
|
import { SendInviteLinkInput } from 'src/engine/core-modules/workspace/dtos/send-invite-link.input';
|
||||||
import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service';
|
import { UpdateWorkspaceInput } from 'src/engine/core-modules/workspace/dtos/update-workspace-input';
|
||||||
|
import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator';
|
||||||
|
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
||||||
|
import { DemoEnvGuard } from 'src/engine/guards/demo.env.guard';
|
||||||
|
import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard';
|
||||||
|
import { WorkspaceCacheVersionService } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.service';
|
||||||
|
import { assert } from 'src/utils/assert';
|
||||||
|
import { streamToBuffer } from 'src/utils/stream-to-buffer';
|
||||||
|
|
||||||
import { Workspace } from './workspace.entity';
|
import { Workspace } from './workspace.entity';
|
||||||
|
|
||||||
@ -128,8 +128,10 @@ export class WorkspaceResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ResolveField(() => Number)
|
@ResolveField(() => Number)
|
||||||
async workspaceMembersCount(): Promise<number | undefined> {
|
async workspaceMembersCount(
|
||||||
return await this.userWorkspaceService.getWorkspaceMemberCount();
|
@Parent() workspace: Workspace,
|
||||||
|
): Promise<number | undefined> {
|
||||||
|
return await this.userWorkspaceService.getUserCount(workspace.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Mutation(() => SendInviteLink)
|
@Mutation(() => SendInviteLink)
|
||||||
|
|||||||
@ -36,4 +36,8 @@ export class WorkspaceDataSource extends DataSource {
|
|||||||
): WorkspaceEntityManager {
|
): WorkspaceEntityManager {
|
||||||
return new WorkspaceEntityManager(this.internalContext, this, queryRunner);
|
return new WorkspaceEntityManager(this.internalContext, this, queryRunner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getWorkspaceId(): string {
|
||||||
|
return this.internalContext.workspaceId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,9 +2,9 @@ import { Injectable } from '@nestjs/common';
|
|||||||
|
|
||||||
import { EntitySchema } from 'typeorm';
|
import { EntitySchema } from 'typeorm';
|
||||||
|
|
||||||
|
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||||
import { EntitySchemaColumnFactory } from 'src/engine/twenty-orm/factories/entity-schema-column.factory';
|
import { EntitySchemaColumnFactory } from 'src/engine/twenty-orm/factories/entity-schema-column.factory';
|
||||||
import { EntitySchemaRelationFactory } from 'src/engine/twenty-orm/factories/entity-schema-relation.factory';
|
import { EntitySchemaRelationFactory } from 'src/engine/twenty-orm/factories/entity-schema-relation.factory';
|
||||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
|
||||||
import { WorkspaceEntitiesStorage } from 'src/engine/twenty-orm/storage/workspace-entities.storage';
|
import { WorkspaceEntitiesStorage } from 'src/engine/twenty-orm/storage/workspace-entities.storage';
|
||||||
import { computeTableName } from 'src/engine/utils/compute-table-name.util';
|
import { computeTableName } from 'src/engine/utils/compute-table-name.util';
|
||||||
import { WorkspaceCacheStorageService } from 'src/engine/workspace-cache-storage/workspace-cache-storage.service';
|
import { WorkspaceCacheStorageService } from 'src/engine/workspace-cache-storage/workspace-cache-storage.service';
|
||||||
@ -20,35 +20,7 @@ export class EntitySchemaFactory {
|
|||||||
async create(
|
async create(
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
objectMetadata: ObjectMetadataEntity,
|
objectMetadata: ObjectMetadataEntity,
|
||||||
): Promise<EntitySchema>;
|
|
||||||
|
|
||||||
async create(
|
|
||||||
workspaceId: string,
|
|
||||||
objectMetadataName: string,
|
|
||||||
): Promise<EntitySchema>;
|
|
||||||
|
|
||||||
async create(
|
|
||||||
workspaceId: string,
|
|
||||||
objectMetadataOrObjectMetadataName: ObjectMetadataEntity | string,
|
|
||||||
): Promise<EntitySchema> {
|
): Promise<EntitySchema> {
|
||||||
let objectMetadata: ObjectMetadataEntity | null =
|
|
||||||
typeof objectMetadataOrObjectMetadataName !== 'string'
|
|
||||||
? objectMetadataOrObjectMetadataName
|
|
||||||
: null;
|
|
||||||
|
|
||||||
if (typeof objectMetadataOrObjectMetadataName === 'string') {
|
|
||||||
objectMetadata =
|
|
||||||
(await this.workspaceCacheStorageService.getObjectMetadata(
|
|
||||||
workspaceId,
|
|
||||||
(objectMetadata) =>
|
|
||||||
objectMetadata.nameSingular === objectMetadataOrObjectMetadataName,
|
|
||||||
)) ?? null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!objectMetadata) {
|
|
||||||
throw new Error('Object metadata not found');
|
|
||||||
}
|
|
||||||
|
|
||||||
const columns = this.entitySchemaColumnFactory.create(
|
const columns = this.entitySchemaColumnFactory.create(
|
||||||
workspaceId,
|
workspaceId,
|
||||||
objectMetadata.fields,
|
objectMetadata.fields,
|
||||||
|
|||||||
@ -54,9 +54,42 @@ export class TwentyORMManager {
|
|||||||
throw new Error('Workspace data source not found');
|
throw new Error('Workspace data source not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const workspaceId = this.workspaceDataSource.getWorkspaceId();
|
||||||
|
|
||||||
|
let objectMetadataCollection =
|
||||||
|
await this.workspaceCacheStorageService.getObjectMetadataCollection(
|
||||||
|
workspaceId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!objectMetadataCollection) {
|
||||||
|
objectMetadataCollection = await this.objectMetadataRepository.find({
|
||||||
|
where: { workspaceId },
|
||||||
|
relations: [
|
||||||
|
'fields.object',
|
||||||
|
'fields',
|
||||||
|
'fields.fromRelationMetadata',
|
||||||
|
'fields.toRelationMetadata',
|
||||||
|
'fields.fromRelationMetadata.toObjectMetadata',
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.workspaceCacheStorageService.setObjectMetadataCollection(
|
||||||
|
workspaceId,
|
||||||
|
objectMetadataCollection,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const objectMetadata = objectMetadataCollection.find(
|
||||||
|
(objectMetadata) => objectMetadata.nameSingular === objectMetadataName,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!objectMetadata) {
|
||||||
|
throw new Error('Object metadata not found');
|
||||||
|
}
|
||||||
|
|
||||||
const entitySchema = await this.entitySchemaFactory.create(
|
const entitySchema = await this.entitySchemaFactory.create(
|
||||||
this.workspaceDataSource.internalContext.workspaceId,
|
workspaceId,
|
||||||
objectMetadataName,
|
objectMetadata,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!entitySchema) {
|
if (!entitySchema) {
|
||||||
@ -95,38 +128,38 @@ export class TwentyORMManager {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let objectMetadataCollection =
|
||||||
|
await this.workspaceCacheStorageService.getObjectMetadataCollection(
|
||||||
|
workspaceId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!objectMetadataCollection) {
|
||||||
|
objectMetadataCollection = await this.objectMetadataRepository.find({
|
||||||
|
where: { workspaceId },
|
||||||
|
relations: [
|
||||||
|
'fields.object',
|
||||||
|
'fields',
|
||||||
|
'fields.fromRelationMetadata',
|
||||||
|
'fields.toRelationMetadata',
|
||||||
|
'fields.fromRelationMetadata.toObjectMetadata',
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.workspaceCacheStorageService.setObjectMetadataCollection(
|
||||||
|
workspaceId,
|
||||||
|
objectMetadataCollection,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const entities = await Promise.all(
|
||||||
|
objectMetadataCollection.map((objectMetadata) =>
|
||||||
|
this.entitySchemaFactory.create(workspaceId, objectMetadata),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
const workspaceDataSource = await workspaceDataSourceCacheInstance.execute(
|
const workspaceDataSource = await workspaceDataSourceCacheInstance.execute(
|
||||||
`${workspaceId}-${cacheVersion}`,
|
`${workspaceId}-${cacheVersion}`,
|
||||||
async () => {
|
async () => {
|
||||||
let objectMetadataCollection =
|
|
||||||
await this.workspaceCacheStorageService.getObjectMetadataCollection(
|
|
||||||
workspaceId,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!objectMetadataCollection) {
|
|
||||||
objectMetadataCollection = await this.objectMetadataRepository.find({
|
|
||||||
where: { workspaceId },
|
|
||||||
relations: [
|
|
||||||
'fields.object',
|
|
||||||
'fields',
|
|
||||||
'fields.fromRelationMetadata',
|
|
||||||
'fields.toRelationMetadata',
|
|
||||||
'fields.fromRelationMetadata.toObjectMetadata',
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
await this.workspaceCacheStorageService.setObjectMetadataCollection(
|
|
||||||
workspaceId,
|
|
||||||
objectMetadataCollection,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const entities = await Promise.all(
|
|
||||||
objectMetadataCollection.map((objectMetadata) =>
|
|
||||||
this.entitySchemaFactory.create(workspaceId, objectMetadata),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
const workspaceDataSource =
|
const workspaceDataSource =
|
||||||
await this.workspaceDataSourceFactory.create(entities, workspaceId);
|
await this.workspaceDataSourceFactory.create(entities, workspaceId);
|
||||||
|
|
||||||
@ -135,9 +168,17 @@ export class TwentyORMManager {
|
|||||||
(dataSource) => dataSource.destroy(),
|
(dataSource) => dataSource.destroy(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const objectMetadata = objectMetadataCollection.find(
|
||||||
|
(objectMetadata) => objectMetadata.nameSingular === objectMetadataName,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!objectMetadata) {
|
||||||
|
throw new Error('Object metadata not found');
|
||||||
|
}
|
||||||
|
|
||||||
const entitySchema = await this.entitySchemaFactory.create(
|
const entitySchema = await this.entitySchemaFactory.create(
|
||||||
workspaceId,
|
workspaceId,
|
||||||
objectMetadataName,
|
objectMetadata,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!workspaceDataSource) {
|
if (!workspaceDataSource) {
|
||||||
|
|||||||
@ -6,9 +6,9 @@ import {
|
|||||||
TwentyORMOptions,
|
TwentyORMOptions,
|
||||||
} from 'src/engine/twenty-orm/interfaces/twenty-orm-options.interface';
|
} from 'src/engine/twenty-orm/interfaces/twenty-orm-options.interface';
|
||||||
|
|
||||||
import { createTwentyORMProviders } from 'src/engine/twenty-orm/twenty-orm.providers';
|
|
||||||
import { TwentyORMCoreModule } from 'src/engine/twenty-orm/twenty-orm-core.module';
|
import { TwentyORMCoreModule } from 'src/engine/twenty-orm/twenty-orm-core.module';
|
||||||
|
|
||||||
|
// Todo: remove this file
|
||||||
@Global()
|
@Global()
|
||||||
@Module({})
|
@Module({})
|
||||||
export class TwentyORMModule {
|
export class TwentyORMModule {
|
||||||
@ -19,8 +19,8 @@ export class TwentyORMModule {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static forFeature(objects: EntityClassOrSchema[] = []): DynamicModule {
|
static forFeature(_objects: EntityClassOrSchema[] = []): DynamicModule {
|
||||||
const providers = createTwentyORMProviders(objects);
|
const providers = [];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
module: TwentyORMModule,
|
module: TwentyORMModule,
|
||||||
|
|||||||
@ -1,44 +0,0 @@
|
|||||||
import { Provider, Type } from '@nestjs/common';
|
|
||||||
import { EntityClassOrSchema } from '@nestjs/typeorm/dist/interfaces/entity-class-or-schema.type';
|
|
||||||
|
|
||||||
import { getWorkspaceRepositoryToken } from 'src/engine/twenty-orm/utils/get-workspace-repository-token.util';
|
|
||||||
import { TWENTY_ORM_WORKSPACE_DATASOURCE } from 'src/engine/twenty-orm/twenty-orm.constants';
|
|
||||||
import { EntitySchemaFactory } from 'src/engine/twenty-orm/factories/entity-schema.factory';
|
|
||||||
import { WorkspaceDataSource } from 'src/engine/twenty-orm/datasource/workspace.datasource';
|
|
||||||
import { convertClassNameToObjectMetadataName } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/convert-class-to-object-metadata-name.util';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create providers for the given entities.
|
|
||||||
*/
|
|
||||||
export function createTwentyORMProviders(
|
|
||||||
objects?: EntityClassOrSchema[],
|
|
||||||
): Provider[] {
|
|
||||||
return (objects || []).map((object) => ({
|
|
||||||
provide: getWorkspaceRepositoryToken(object),
|
|
||||||
useFactory: async (
|
|
||||||
dataSource: WorkspaceDataSource | null,
|
|
||||||
entitySchemaFactory: EntitySchemaFactory,
|
|
||||||
) => {
|
|
||||||
const objectMetadataName = convertClassNameToObjectMetadataName(
|
|
||||||
(object as Type).name,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!dataSource) {
|
|
||||||
// TODO: Throw here when the code is well architected
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const entitySchema = await entitySchemaFactory.create(
|
|
||||||
dataSource.internalContext.workspaceId,
|
|
||||||
objectMetadataName,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!entitySchema) {
|
|
||||||
throw new Error('Entity schema not found');
|
|
||||||
}
|
|
||||||
|
|
||||||
return dataSource.getRepository(entitySchema);
|
|
||||||
},
|
|
||||||
inject: [TWENTY_ORM_WORKSPACE_DATASOURCE, EntitySchemaFactory],
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
@ -6,13 +6,10 @@ import { Process } from 'src/engine/integrations/message-queue/decorators/proces
|
|||||||
import { Processor } from 'src/engine/integrations/message-queue/decorators/processor.decorator';
|
import { Processor } from 'src/engine/integrations/message-queue/decorators/processor.decorator';
|
||||||
import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants';
|
import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants';
|
||||||
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
|
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
|
||||||
import { InjectWorkspaceRepository } from 'src/engine/twenty-orm/decorators/inject-workspace-repository.decorator';
|
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
|
||||||
import { BlocklistRepository } from 'src/modules/blocklist/repositories/blocklist.repository';
|
import { BlocklistRepository } from 'src/modules/blocklist/repositories/blocklist.repository';
|
||||||
import { BlocklistWorkspaceEntity } from 'src/modules/blocklist/standard-objects/blocklist.workspace-entity';
|
import { BlocklistWorkspaceEntity } from 'src/modules/blocklist/standard-objects/blocklist.workspace-entity';
|
||||||
import { CalendarEventCleanerService } from 'src/modules/calendar/calendar-event-cleaner/services/calendar-event-cleaner.service';
|
import { CalendarEventCleanerService } from 'src/modules/calendar/calendar-event-cleaner/services/calendar-event-cleaner.service';
|
||||||
import { CalendarChannelEventAssociationWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-channel-event-association.workspace-entity';
|
|
||||||
import { CalendarChannelWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity';
|
|
||||||
|
|
||||||
export type BlocklistItemDeleteCalendarEventsJobData = {
|
export type BlocklistItemDeleteCalendarEventsJobData = {
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
@ -29,10 +26,7 @@ export class BlocklistItemDeleteCalendarEventsJob {
|
|||||||
);
|
);
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@InjectWorkspaceRepository(CalendarChannelWorkspaceEntity)
|
private readonly twentyORMManager: TwentyORMManager,
|
||||||
private readonly calendarChannelRepository: WorkspaceRepository<CalendarChannelWorkspaceEntity>,
|
|
||||||
@InjectWorkspaceRepository(CalendarChannelEventAssociationWorkspaceEntity)
|
|
||||||
private readonly calendarChannelEventAssociationRepository: WorkspaceRepository<CalendarChannelEventAssociationWorkspaceEntity>,
|
|
||||||
@InjectObjectMetadataRepository(BlocklistWorkspaceEntity)
|
@InjectObjectMetadataRepository(BlocklistWorkspaceEntity)
|
||||||
private readonly blocklistRepository: BlocklistRepository,
|
private readonly blocklistRepository: BlocklistRepository,
|
||||||
private readonly calendarEventCleanerService: CalendarEventCleanerService,
|
private readonly calendarEventCleanerService: CalendarEventCleanerService,
|
||||||
@ -67,7 +61,10 @@ export class BlocklistItemDeleteCalendarEventsJob {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const calendarChannels = await this.calendarChannelRepository.find({
|
const calendarChannelRepository =
|
||||||
|
await this.twentyORMManager.getRepository('calendarChannel');
|
||||||
|
|
||||||
|
const calendarChannels = await calendarChannelRepository.find({
|
||||||
where: {
|
where: {
|
||||||
connectedAccount: {
|
connectedAccount: {
|
||||||
accountOwnerId: workspaceMemberId,
|
accountOwnerId: workspaceMemberId,
|
||||||
@ -79,7 +76,12 @@ export class BlocklistItemDeleteCalendarEventsJob {
|
|||||||
|
|
||||||
const isHandleDomain = handle.startsWith('@');
|
const isHandleDomain = handle.startsWith('@');
|
||||||
|
|
||||||
await this.calendarChannelEventAssociationRepository.delete({
|
const calendarChannelEventAssociationRepository =
|
||||||
|
await this.twentyORMManager.getRepository(
|
||||||
|
'calendarChannelEventAssociation',
|
||||||
|
);
|
||||||
|
|
||||||
|
await calendarChannelEventAssociationRepository.delete({
|
||||||
calendarEvent: {
|
calendarEvent: {
|
||||||
calendarEventParticipants: {
|
calendarEventParticipants: {
|
||||||
handle: isHandleDomain ? ILike(`%${handle}`) : handle,
|
handle: isHandleDomain ? ILike(`%${handle}`) : handle,
|
||||||
|
|||||||
@ -2,18 +2,17 @@ import { Scope } from '@nestjs/common';
|
|||||||
|
|
||||||
import { Any } from 'typeorm';
|
import { Any } from 'typeorm';
|
||||||
|
|
||||||
|
import { Process } from 'src/engine/integrations/message-queue/decorators/process.decorator';
|
||||||
import { Processor } from 'src/engine/integrations/message-queue/decorators/processor.decorator';
|
import { Processor } from 'src/engine/integrations/message-queue/decorators/processor.decorator';
|
||||||
import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants';
|
import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants';
|
||||||
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
|
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
|
||||||
import { ConnectedAccountRepository } from 'src/modules/connected-account/repositories/connected-account.repository';
|
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||||
import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
|
|
||||||
import { Process } from 'src/engine/integrations/message-queue/decorators/process.decorator';
|
|
||||||
import { InjectWorkspaceRepository } from 'src/engine/twenty-orm/decorators/inject-workspace-repository.decorator';
|
|
||||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
|
||||||
import {
|
import {
|
||||||
CalendarChannelSyncStage,
|
CalendarChannelSyncStage,
|
||||||
CalendarChannelWorkspaceEntity,
|
CalendarChannelWorkspaceEntity,
|
||||||
} from 'src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity';
|
} from 'src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity';
|
||||||
|
import { ConnectedAccountRepository } from 'src/modules/connected-account/repositories/connected-account.repository';
|
||||||
|
import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
|
||||||
|
|
||||||
export type BlocklistReimportCalendarEventsJobData = {
|
export type BlocklistReimportCalendarEventsJobData = {
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
@ -26,10 +25,9 @@ export type BlocklistReimportCalendarEventsJobData = {
|
|||||||
})
|
})
|
||||||
export class BlocklistReimportCalendarEventsJob {
|
export class BlocklistReimportCalendarEventsJob {
|
||||||
constructor(
|
constructor(
|
||||||
|
private readonly twentyORMManager: TwentyORMManager,
|
||||||
@InjectObjectMetadataRepository(ConnectedAccountWorkspaceEntity)
|
@InjectObjectMetadataRepository(ConnectedAccountWorkspaceEntity)
|
||||||
private readonly connectedAccountRepository: ConnectedAccountRepository,
|
private readonly connectedAccountRepository: ConnectedAccountRepository,
|
||||||
@InjectWorkspaceRepository(CalendarChannelWorkspaceEntity)
|
|
||||||
private readonly calendarChannelRepository: WorkspaceRepository<CalendarChannelWorkspaceEntity>,
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@Process(BlocklistReimportCalendarEventsJob.name)
|
@Process(BlocklistReimportCalendarEventsJob.name)
|
||||||
@ -46,7 +44,11 @@ export class BlocklistReimportCalendarEventsJob {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.calendarChannelRepository.update(
|
const calendarChannelRepository = await this.twentyORMManager.getRepository(
|
||||||
|
CalendarChannelWorkspaceEntity,
|
||||||
|
);
|
||||||
|
|
||||||
|
await calendarChannelRepository.update(
|
||||||
{
|
{
|
||||||
connectedAccountId: Any(
|
connectedAccountId: Any(
|
||||||
connectedAccounts.map((connectedAccount) => connectedAccount.id),
|
connectedAccounts.map((connectedAccount) => connectedAccount.id),
|
||||||
|
|||||||
@ -2,38 +2,35 @@ import { Injectable } from '@nestjs/common';
|
|||||||
|
|
||||||
import { Any, IsNull } from 'typeorm';
|
import { Any, IsNull } from 'typeorm';
|
||||||
|
|
||||||
import { InjectWorkspaceRepository } from 'src/engine/twenty-orm/decorators/inject-workspace-repository.decorator';
|
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
|
||||||
import { deleteUsingPagination } from 'src/modules/messaging/message-cleaner/utils/delete-using-pagination.util';
|
import { deleteUsingPagination } from 'src/modules/messaging/message-cleaner/utils/delete-using-pagination.util';
|
||||||
import { CalendarEventWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-event.workspace-entity';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CalendarEventCleanerService {
|
export class CalendarEventCleanerService {
|
||||||
constructor(
|
constructor(private readonly twentyORMManager: TwentyORMManager) {}
|
||||||
@InjectWorkspaceRepository(CalendarEventWorkspaceEntity)
|
|
||||||
private readonly calendarEventRepository: WorkspaceRepository<CalendarEventWorkspaceEntity>,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public async cleanWorkspaceCalendarEvents(workspaceId: string) {
|
public async cleanWorkspaceCalendarEvents(workspaceId: string) {
|
||||||
|
const calendarEventRepository =
|
||||||
|
await this.twentyORMManager.getRepository('calendarEvent');
|
||||||
|
|
||||||
await deleteUsingPagination(
|
await deleteUsingPagination(
|
||||||
workspaceId,
|
workspaceId,
|
||||||
500,
|
500,
|
||||||
async (limit, offset) => {
|
async (limit, offset) => {
|
||||||
const nonAssociatedCalendarEvents =
|
const nonAssociatedCalendarEvents = await calendarEventRepository.find({
|
||||||
await this.calendarEventRepository.find({
|
where: {
|
||||||
where: {
|
calendarChannelEventAssociations: {
|
||||||
calendarChannelEventAssociations: {
|
id: IsNull(),
|
||||||
id: IsNull(),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
take: limit,
|
},
|
||||||
skip: offset,
|
take: limit,
|
||||||
});
|
skip: offset,
|
||||||
|
});
|
||||||
|
|
||||||
return nonAssociatedCalendarEvents.map(({ id }) => id);
|
return nonAssociatedCalendarEvents.map(({ id }) => id);
|
||||||
},
|
},
|
||||||
async (ids) => {
|
async (ids) => {
|
||||||
await this.calendarEventRepository.delete({ id: Any(ids) });
|
await calendarEventRepository.delete({ id: Any(ids) });
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,19 +1,18 @@
|
|||||||
import { Scope } from '@nestjs/common';
|
import { Scope } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { Process } from 'src/engine/integrations/message-queue/decorators/process.decorator';
|
||||||
import { Processor } from 'src/engine/integrations/message-queue/decorators/processor.decorator';
|
import { Processor } from 'src/engine/integrations/message-queue/decorators/processor.decorator';
|
||||||
import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants';
|
import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants';
|
||||||
import { Process } from 'src/engine/integrations/message-queue/decorators/process.decorator';
|
|
||||||
import { CalendarEventsImportService } from 'src/modules/calendar/calendar-event-import-manager/services/calendar-events-import.service';
|
|
||||||
import { isThrottled } from 'src/modules/connected-account/utils/is-throttled';
|
|
||||||
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
|
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
|
||||||
import { ConnectedAccountRepository } from 'src/modules/connected-account/repositories/connected-account.repository';
|
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||||
import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
|
import { CalendarEventsImportService } from 'src/modules/calendar/calendar-event-import-manager/services/calendar-events-import.service';
|
||||||
import {
|
import {
|
||||||
CalendarChannelSyncStage,
|
CalendarChannelSyncStage,
|
||||||
CalendarChannelWorkspaceEntity,
|
CalendarChannelWorkspaceEntity,
|
||||||
} from 'src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity';
|
} from 'src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity';
|
||||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
import { ConnectedAccountRepository } from 'src/modules/connected-account/repositories/connected-account.repository';
|
||||||
import { InjectWorkspaceRepository } from 'src/engine/twenty-orm/decorators/inject-workspace-repository.decorator';
|
import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
|
||||||
|
import { isThrottled } from 'src/modules/connected-account/utils/is-throttled';
|
||||||
|
|
||||||
export type CalendarEventsImportJobData = {
|
export type CalendarEventsImportJobData = {
|
||||||
calendarChannelId: string;
|
calendarChannelId: string;
|
||||||
@ -26,18 +25,22 @@ export type CalendarEventsImportJobData = {
|
|||||||
})
|
})
|
||||||
export class CalendarEventListFetchJob {
|
export class CalendarEventListFetchJob {
|
||||||
constructor(
|
constructor(
|
||||||
|
private readonly twentyORMManager: TwentyORMManager,
|
||||||
private readonly calendarEventsImportService: CalendarEventsImportService,
|
private readonly calendarEventsImportService: CalendarEventsImportService,
|
||||||
@InjectObjectMetadataRepository(ConnectedAccountWorkspaceEntity)
|
@InjectObjectMetadataRepository(ConnectedAccountWorkspaceEntity)
|
||||||
private readonly connectedAccountRepository: ConnectedAccountRepository,
|
private readonly connectedAccountRepository: ConnectedAccountRepository,
|
||||||
@InjectWorkspaceRepository(CalendarChannelWorkspaceEntity)
|
|
||||||
private readonly calendarChannelRepository: WorkspaceRepository<CalendarChannelWorkspaceEntity>,
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@Process(CalendarEventListFetchJob.name)
|
@Process(CalendarEventListFetchJob.name)
|
||||||
async handle(data: CalendarEventsImportJobData): Promise<void> {
|
async handle(data: CalendarEventsImportJobData): Promise<void> {
|
||||||
const { workspaceId, calendarChannelId } = data;
|
const { workspaceId, calendarChannelId } = data;
|
||||||
|
|
||||||
const calendarChannel = await this.calendarChannelRepository.findOne({
|
const calendarChannelRepository =
|
||||||
|
await this.twentyORMManager.getRepository<CalendarChannelWorkspaceEntity>(
|
||||||
|
'calendarChannel',
|
||||||
|
);
|
||||||
|
|
||||||
|
const calendarChannel = await calendarChannelRepository.findOne({
|
||||||
where: {
|
where: {
|
||||||
id: calendarChannelId,
|
id: calendarChannelId,
|
||||||
isSyncEnabled: true,
|
isSyncEnabled: true,
|
||||||
@ -65,7 +68,7 @@ export class CalendarEventListFetchJob {
|
|||||||
|
|
||||||
switch (calendarChannel.syncStage) {
|
switch (calendarChannel.syncStage) {
|
||||||
case CalendarChannelSyncStage.FULL_CALENDAR_EVENT_LIST_FETCH_PENDING:
|
case CalendarChannelSyncStage.FULL_CALENDAR_EVENT_LIST_FETCH_PENDING:
|
||||||
await this.calendarChannelRepository.update(calendarChannelId, {
|
await calendarChannelRepository.update(calendarChannelId, {
|
||||||
syncCursor: '',
|
syncCursor: '',
|
||||||
syncStageStartedAt: null,
|
syncStageStartedAt: null,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -3,8 +3,7 @@ import { Injectable } from '@nestjs/common';
|
|||||||
import { CacheStorageService } from 'src/engine/integrations/cache-storage/cache-storage.service';
|
import { CacheStorageService } from 'src/engine/integrations/cache-storage/cache-storage.service';
|
||||||
import { InjectCacheStorage } from 'src/engine/integrations/cache-storage/decorators/cache-storage.decorator';
|
import { InjectCacheStorage } from 'src/engine/integrations/cache-storage/decorators/cache-storage.decorator';
|
||||||
import { CacheStorageNamespace } from 'src/engine/integrations/cache-storage/types/cache-storage-namespace.enum';
|
import { CacheStorageNamespace } from 'src/engine/integrations/cache-storage/types/cache-storage-namespace.enum';
|
||||||
import { InjectWorkspaceRepository } from 'src/engine/twenty-orm/decorators/inject-workspace-repository.decorator';
|
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
|
||||||
import {
|
import {
|
||||||
CalendarChannelSyncStage,
|
CalendarChannelSyncStage,
|
||||||
CalendarChannelSyncStatus,
|
CalendarChannelSyncStatus,
|
||||||
@ -14,14 +13,18 @@ import {
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class CalendarChannelSyncStatusService {
|
export class CalendarChannelSyncStatusService {
|
||||||
constructor(
|
constructor(
|
||||||
@InjectWorkspaceRepository(CalendarChannelWorkspaceEntity)
|
private readonly twentyORMManager: TwentyORMManager,
|
||||||
private readonly calendarChannelRepository: WorkspaceRepository<CalendarChannelWorkspaceEntity>,
|
|
||||||
@InjectCacheStorage(CacheStorageNamespace.Calendar)
|
@InjectCacheStorage(CacheStorageNamespace.Calendar)
|
||||||
private readonly cacheStorage: CacheStorageService,
|
private readonly cacheStorage: CacheStorageService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public async scheduleFullCalendarEventListFetch(calendarChannelId: string) {
|
public async scheduleFullCalendarEventListFetch(calendarChannelId: string) {
|
||||||
await this.calendarChannelRepository.update(calendarChannelId, {
|
const calendarChannelRepository =
|
||||||
|
await this.twentyORMManager.getRepository<CalendarChannelWorkspaceEntity>(
|
||||||
|
'calendarChannel',
|
||||||
|
);
|
||||||
|
|
||||||
|
await calendarChannelRepository.update(calendarChannelId, {
|
||||||
syncStage:
|
syncStage:
|
||||||
CalendarChannelSyncStage.FULL_CALENDAR_EVENT_LIST_FETCH_PENDING,
|
CalendarChannelSyncStage.FULL_CALENDAR_EVENT_LIST_FETCH_PENDING,
|
||||||
});
|
});
|
||||||
@ -30,14 +33,24 @@ export class CalendarChannelSyncStatusService {
|
|||||||
public async schedulePartialCalendarEventListFetch(
|
public async schedulePartialCalendarEventListFetch(
|
||||||
calendarChannelId: string,
|
calendarChannelId: string,
|
||||||
) {
|
) {
|
||||||
await this.calendarChannelRepository.update(calendarChannelId, {
|
const calendarChannelRepository =
|
||||||
|
await this.twentyORMManager.getRepository<CalendarChannelWorkspaceEntity>(
|
||||||
|
'calendarChannel',
|
||||||
|
);
|
||||||
|
|
||||||
|
await calendarChannelRepository.update(calendarChannelId, {
|
||||||
syncStage:
|
syncStage:
|
||||||
CalendarChannelSyncStage.PARTIAL_CALENDAR_EVENT_LIST_FETCH_PENDING,
|
CalendarChannelSyncStage.PARTIAL_CALENDAR_EVENT_LIST_FETCH_PENDING,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async markAsCalendarEventListFetchOngoing(calendarChannelId: string) {
|
public async markAsCalendarEventListFetchOngoing(calendarChannelId: string) {
|
||||||
await this.calendarChannelRepository.update(calendarChannelId, {
|
const calendarChannelRepository =
|
||||||
|
await this.twentyORMManager.getRepository<CalendarChannelWorkspaceEntity>(
|
||||||
|
'calendarChannel',
|
||||||
|
);
|
||||||
|
|
||||||
|
await calendarChannelRepository.update(calendarChannelId, {
|
||||||
syncStage: CalendarChannelSyncStage.CALENDAR_EVENT_LIST_FETCH_ONGOING,
|
syncStage: CalendarChannelSyncStage.CALENDAR_EVENT_LIST_FETCH_ONGOING,
|
||||||
syncStatus: CalendarChannelSyncStatus.ONGOING,
|
syncStatus: CalendarChannelSyncStatus.ONGOING,
|
||||||
syncStageStartedAt: new Date().toISOString(),
|
syncStageStartedAt: new Date().toISOString(),
|
||||||
@ -52,7 +65,12 @@ export class CalendarChannelSyncStatusService {
|
|||||||
`calendar-events-to-import:${workspaceId}:google-calendar:${calendarChannelId}`,
|
`calendar-events-to-import:${workspaceId}:google-calendar:${calendarChannelId}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
await this.calendarChannelRepository.update(calendarChannelId, {
|
const calendarChannelRepository =
|
||||||
|
await this.twentyORMManager.getRepository<CalendarChannelWorkspaceEntity>(
|
||||||
|
'calendarChannel',
|
||||||
|
);
|
||||||
|
|
||||||
|
await calendarChannelRepository.update(calendarChannelId, {
|
||||||
syncCursor: '',
|
syncCursor: '',
|
||||||
syncStageStartedAt: null,
|
syncStageStartedAt: null,
|
||||||
throttleFailureCount: 0,
|
throttleFailureCount: 0,
|
||||||
@ -62,13 +80,23 @@ export class CalendarChannelSyncStatusService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async scheduleCalendarEventsImport(calendarChannelId: string) {
|
public async scheduleCalendarEventsImport(calendarChannelId: string) {
|
||||||
await this.calendarChannelRepository.update(calendarChannelId, {
|
const calendarChannelRepository =
|
||||||
|
await this.twentyORMManager.getRepository<CalendarChannelWorkspaceEntity>(
|
||||||
|
'calendarChannel',
|
||||||
|
);
|
||||||
|
|
||||||
|
await calendarChannelRepository.update(calendarChannelId, {
|
||||||
syncStage: CalendarChannelSyncStage.CALENDAR_EVENTS_IMPORT_PENDING,
|
syncStage: CalendarChannelSyncStage.CALENDAR_EVENTS_IMPORT_PENDING,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async markAsCalendarEventsImportOngoing(calendarChannelId: string) {
|
public async markAsCalendarEventsImportOngoing(calendarChannelId: string) {
|
||||||
await this.calendarChannelRepository.update(calendarChannelId, {
|
const calendarChannelRepository =
|
||||||
|
await this.twentyORMManager.getRepository<CalendarChannelWorkspaceEntity>(
|
||||||
|
'calendarChannel',
|
||||||
|
);
|
||||||
|
|
||||||
|
await calendarChannelRepository.update(calendarChannelId, {
|
||||||
syncStage: CalendarChannelSyncStage.CALENDAR_EVENTS_IMPORT_ONGOING,
|
syncStage: CalendarChannelSyncStage.CALENDAR_EVENTS_IMPORT_ONGOING,
|
||||||
syncStatus: CalendarChannelSyncStatus.ONGOING,
|
syncStatus: CalendarChannelSyncStatus.ONGOING,
|
||||||
});
|
});
|
||||||
@ -77,7 +105,12 @@ export class CalendarChannelSyncStatusService {
|
|||||||
public async markAsCompletedAndSchedulePartialMessageListFetch(
|
public async markAsCompletedAndSchedulePartialMessageListFetch(
|
||||||
calendarChannelId: string,
|
calendarChannelId: string,
|
||||||
) {
|
) {
|
||||||
await this.calendarChannelRepository.update(calendarChannelId, {
|
const calendarChannelRepository =
|
||||||
|
await this.twentyORMManager.getRepository<CalendarChannelWorkspaceEntity>(
|
||||||
|
'calendarChannel',
|
||||||
|
);
|
||||||
|
|
||||||
|
await calendarChannelRepository.update(calendarChannelId, {
|
||||||
syncStage:
|
syncStage:
|
||||||
CalendarChannelSyncStage.PARTIAL_CALENDAR_EVENT_LIST_FETCH_PENDING,
|
CalendarChannelSyncStage.PARTIAL_CALENDAR_EVENT_LIST_FETCH_PENDING,
|
||||||
syncStatus: CalendarChannelSyncStatus.ACTIVE,
|
syncStatus: CalendarChannelSyncStatus.ACTIVE,
|
||||||
@ -92,11 +125,16 @@ export class CalendarChannelSyncStatusService {
|
|||||||
calendarChannelId: string,
|
calendarChannelId: string,
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
) {
|
) {
|
||||||
|
const calendarChannelRepository =
|
||||||
|
await this.twentyORMManager.getRepository<CalendarChannelWorkspaceEntity>(
|
||||||
|
'calendarChannel',
|
||||||
|
);
|
||||||
|
|
||||||
await this.cacheStorage.del(
|
await this.cacheStorage.del(
|
||||||
`calendar-events-to-import:${workspaceId}:google-calendar:${calendarChannelId}`,
|
`calendar-events-to-import:${workspaceId}:google-calendar:${calendarChannelId}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
await this.calendarChannelRepository.update(calendarChannelId, {
|
await calendarChannelRepository.update(calendarChannelId, {
|
||||||
syncStatus: CalendarChannelSyncStatus.FAILED_UNKNOWN,
|
syncStatus: CalendarChannelSyncStatus.FAILED_UNKNOWN,
|
||||||
syncStage: CalendarChannelSyncStage.FAILED,
|
syncStage: CalendarChannelSyncStage.FAILED,
|
||||||
});
|
});
|
||||||
@ -106,11 +144,16 @@ export class CalendarChannelSyncStatusService {
|
|||||||
calendarChannelId: string,
|
calendarChannelId: string,
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
) {
|
) {
|
||||||
|
const calendarChannelRepository =
|
||||||
|
await this.twentyORMManager.getRepository<CalendarChannelWorkspaceEntity>(
|
||||||
|
'calendarChannel',
|
||||||
|
);
|
||||||
|
|
||||||
await this.cacheStorage.del(
|
await this.cacheStorage.del(
|
||||||
`calendar-events-to-import:${workspaceId}:google-calendar:${calendarChannelId}`,
|
`calendar-events-to-import:${workspaceId}:google-calendar:${calendarChannelId}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
await this.calendarChannelRepository.update(calendarChannelId, {
|
await calendarChannelRepository.update(calendarChannelId, {
|
||||||
syncStatus: CalendarChannelSyncStatus.FAILED_INSUFFICIENT_PERMISSIONS,
|
syncStatus: CalendarChannelSyncStatus.FAILED_INSUFFICIENT_PERMISSIONS,
|
||||||
syncStage: CalendarChannelSyncStage.FAILED,
|
syncStage: CalendarChannelSyncStage.FAILED,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
import { InjectWorkspaceRepository } from 'src/engine/twenty-orm/decorators/inject-workspace-repository.decorator';
|
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
|
||||||
import { CALENDAR_THROTTLE_MAX_ATTEMPTS } from 'src/modules/calendar/calendar-event-import-manager/constants/calendar-throttle-max-attempts';
|
import { CALENDAR_THROTTLE_MAX_ATTEMPTS } from 'src/modules/calendar/calendar-event-import-manager/constants/calendar-throttle-max-attempts';
|
||||||
import { CalendarChannelSyncStatusService } from 'src/modules/calendar/calendar-event-import-manager/services/calendar-channel-sync-status.service';
|
import { CalendarChannelSyncStatusService } from 'src/modules/calendar/calendar-event-import-manager/services/calendar-channel-sync-status.service';
|
||||||
import { CalendarEventError } from 'src/modules/calendar/calendar-event-import-manager/types/calendar-event-error.type';
|
import { CalendarEventError } from 'src/modules/calendar/calendar-event-import-manager/types/calendar-event-error.type';
|
||||||
@ -16,9 +15,8 @@ export enum CalendarEventImportSyncStep {
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class CalendarEventImportErrorHandlerService {
|
export class CalendarEventImportErrorHandlerService {
|
||||||
constructor(
|
constructor(
|
||||||
|
private readonly twentyORMManager: TwentyORMManager,
|
||||||
private readonly calendarChannelSyncStatusService: CalendarChannelSyncStatusService,
|
private readonly calendarChannelSyncStatusService: CalendarChannelSyncStatusService,
|
||||||
@InjectWorkspaceRepository(CalendarChannelWorkspaceEntity)
|
|
||||||
private readonly calendarChannelRepository: WorkspaceRepository<CalendarChannelWorkspaceEntity>,
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public async handleError(
|
public async handleError(
|
||||||
@ -68,7 +66,12 @@ export class CalendarEventImportErrorHandlerService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.calendarChannelRepository.increment(
|
const calendarChannelRepository =
|
||||||
|
await this.twentyORMManager.getRepository<CalendarChannelWorkspaceEntity>(
|
||||||
|
'calendarChannel',
|
||||||
|
);
|
||||||
|
|
||||||
|
await calendarChannelRepository.increment(
|
||||||
{
|
{
|
||||||
id: calendarChannel.id,
|
id: calendarChannel.id,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -3,8 +3,7 @@ import { Injectable } from '@nestjs/common';
|
|||||||
import { Any } from 'typeorm';
|
import { Any } from 'typeorm';
|
||||||
|
|
||||||
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
|
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
|
||||||
import { InjectWorkspaceRepository } from 'src/engine/twenty-orm/decorators/inject-workspace-repository.decorator';
|
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
|
||||||
import { BlocklistRepository } from 'src/modules/blocklist/repositories/blocklist.repository';
|
import { BlocklistRepository } from 'src/modules/blocklist/repositories/blocklist.repository';
|
||||||
import { BlocklistWorkspaceEntity } from 'src/modules/blocklist/standard-objects/blocklist.workspace-entity';
|
import { BlocklistWorkspaceEntity } from 'src/modules/blocklist/standard-objects/blocklist.workspace-entity';
|
||||||
import { CalendarEventCleanerService } from 'src/modules/calendar/calendar-event-cleaner/services/calendar-event-cleaner.service';
|
import { CalendarEventCleanerService } from 'src/modules/calendar/calendar-event-cleaner/services/calendar-event-cleaner.service';
|
||||||
@ -29,10 +28,7 @@ import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/s
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class CalendarEventsImportService {
|
export class CalendarEventsImportService {
|
||||||
constructor(
|
constructor(
|
||||||
@InjectWorkspaceRepository(CalendarChannelWorkspaceEntity)
|
private readonly twentyORMManager: TwentyORMManager,
|
||||||
private readonly calendarChannelRepository: WorkspaceRepository<CalendarChannelWorkspaceEntity>,
|
|
||||||
@InjectWorkspaceRepository(CalendarChannelEventAssociationWorkspaceEntity)
|
|
||||||
private readonly calendarChannelEventAssociationRepository: WorkspaceRepository<CalendarChannelEventAssociationWorkspaceEntity>,
|
|
||||||
@InjectObjectMetadataRepository(BlocklistWorkspaceEntity)
|
@InjectObjectMetadataRepository(BlocklistWorkspaceEntity)
|
||||||
private readonly blocklistRepository: BlocklistRepository,
|
private readonly blocklistRepository: BlocklistRepository,
|
||||||
private readonly calendarEventCleanerService: CalendarEventCleanerService,
|
private readonly calendarEventCleanerService: CalendarEventCleanerService,
|
||||||
@ -79,8 +75,13 @@ export class CalendarEventsImportService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const calendarChannelRepository =
|
||||||
|
await this.twentyORMManager.getRepository<CalendarChannelWorkspaceEntity>(
|
||||||
|
'calendarChannel',
|
||||||
|
);
|
||||||
|
|
||||||
if (!calendarEvents || calendarEvents?.length === 0) {
|
if (!calendarEvents || calendarEvents?.length === 0) {
|
||||||
await this.calendarChannelRepository.update(
|
await calendarChannelRepository.update(
|
||||||
{
|
{
|
||||||
id: calendarChannel.id,
|
id: calendarChannel.id,
|
||||||
},
|
},
|
||||||
@ -117,7 +118,12 @@ export class CalendarEventsImportService {
|
|||||||
workspaceId,
|
workspaceId,
|
||||||
);
|
);
|
||||||
|
|
||||||
await this.calendarChannelEventAssociationRepository.delete({
|
const calendarChannelEventAssociationRepository =
|
||||||
|
await this.twentyORMManager.getRepository<CalendarChannelEventAssociationWorkspaceEntity>(
|
||||||
|
'calendarChannelEventAssociation',
|
||||||
|
);
|
||||||
|
|
||||||
|
await calendarChannelEventAssociationRepository.delete({
|
||||||
eventExternalId: Any(cancelledEventExternalIds),
|
eventExternalId: Any(cancelledEventExternalIds),
|
||||||
calendarChannel: {
|
calendarChannel: {
|
||||||
id: calendarChannel.id,
|
id: calendarChannel.id,
|
||||||
@ -128,7 +134,7 @@ export class CalendarEventsImportService {
|
|||||||
workspaceId,
|
workspaceId,
|
||||||
);
|
);
|
||||||
|
|
||||||
await this.calendarChannelRepository.update(
|
await calendarChannelRepository.update(
|
||||||
{
|
{
|
||||||
id: calendarChannel.id,
|
id: calendarChannel.id,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -8,8 +8,7 @@ import { MessageQueue } from 'src/engine/integrations/message-queue/message-queu
|
|||||||
import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service';
|
import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service';
|
||||||
import { WorkspaceDataSource } from 'src/engine/twenty-orm/datasource/workspace.datasource';
|
import { WorkspaceDataSource } from 'src/engine/twenty-orm/datasource/workspace.datasource';
|
||||||
import { InjectWorkspaceDatasource } from 'src/engine/twenty-orm/decorators/inject-workspace-datasource.decorator';
|
import { InjectWorkspaceDatasource } from 'src/engine/twenty-orm/decorators/inject-workspace-datasource.decorator';
|
||||||
import { InjectWorkspaceRepository } from 'src/engine/twenty-orm/decorators/inject-workspace-repository.decorator';
|
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
|
||||||
import { injectIdsInCalendarEvents } from 'src/modules/calendar/calendar-event-import-manager/utils/inject-ids-in-calendar-events.util';
|
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';
|
import { CalendarEventParticipantService } from 'src/modules/calendar/calendar-event-participant-manager/services/calendar-event-participant.service';
|
||||||
import { CalendarChannelEventAssociationWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-channel-event-association.workspace-entity';
|
import { CalendarChannelEventAssociationWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-channel-event-association.workspace-entity';
|
||||||
@ -26,10 +25,7 @@ import {
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class CalendarSaveEventsService {
|
export class CalendarSaveEventsService {
|
||||||
constructor(
|
constructor(
|
||||||
@InjectWorkspaceRepository(CalendarEventWorkspaceEntity)
|
private readonly twentyORMManager: TwentyORMManager,
|
||||||
private readonly calendarEventRepository: WorkspaceRepository<CalendarEventWorkspaceEntity>,
|
|
||||||
@InjectWorkspaceRepository(CalendarChannelEventAssociationWorkspaceEntity)
|
|
||||||
private readonly calendarChannelEventAssociationRepository: WorkspaceRepository<CalendarChannelEventAssociationWorkspaceEntity>,
|
|
||||||
@InjectWorkspaceDatasource()
|
@InjectWorkspaceDatasource()
|
||||||
private readonly workspaceDataSource: WorkspaceDataSource,
|
private readonly workspaceDataSource: WorkspaceDataSource,
|
||||||
private readonly calendarEventParticipantService: CalendarEventParticipantService,
|
private readonly calendarEventParticipantService: CalendarEventParticipantService,
|
||||||
@ -44,7 +40,12 @@ export class CalendarSaveEventsService {
|
|||||||
connectedAccount: ConnectedAccountWorkspaceEntity,
|
connectedAccount: ConnectedAccountWorkspaceEntity,
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const existingCalendarEvents = await this.calendarEventRepository.find({
|
const calendarEventRepository =
|
||||||
|
await this.twentyORMManager.getRepository<CalendarEventWorkspaceEntity>(
|
||||||
|
'calendarEvent',
|
||||||
|
);
|
||||||
|
|
||||||
|
const existingCalendarEvents = await calendarEventRepository.find({
|
||||||
where: {
|
where: {
|
||||||
iCalUID: Any(filteredEvents.map((event) => event.iCalUID as string)),
|
iCalUID: Any(filteredEvents.map((event) => event.iCalUID as string)),
|
||||||
},
|
},
|
||||||
@ -77,8 +78,13 @@ export class CalendarSaveEventsService {
|
|||||||
existingEventsICalUIDs.includes(calendarEvent.iCalUID),
|
existingEventsICalUIDs.includes(calendarEvent.iCalUID),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const calendarChannelEventAssociationRepository =
|
||||||
|
await this.twentyORMManager.getRepository<CalendarChannelEventAssociationWorkspaceEntity>(
|
||||||
|
'calendarChannelEventAssociation',
|
||||||
|
);
|
||||||
|
|
||||||
const existingCalendarChannelEventAssociations =
|
const existingCalendarChannelEventAssociations =
|
||||||
await this.calendarChannelEventAssociationRepository.find({
|
await calendarChannelEventAssociationRepository.find({
|
||||||
where: {
|
where: {
|
||||||
eventExternalId: Any(
|
eventExternalId: Any(
|
||||||
calendarEventsWithIds.map((calendarEvent) => calendarEvent.id),
|
calendarEventsWithIds.map((calendarEvent) => calendarEvent.id),
|
||||||
@ -114,19 +120,15 @@ export class CalendarSaveEventsService {
|
|||||||
[];
|
[];
|
||||||
|
|
||||||
await this.workspaceDataSource?.transaction(async (transactionManager) => {
|
await this.workspaceDataSource?.transaction(async (transactionManager) => {
|
||||||
await this.calendarEventRepository.save(
|
await calendarEventRepository.save(eventsToSave, {}, transactionManager);
|
||||||
eventsToSave,
|
|
||||||
{},
|
|
||||||
transactionManager,
|
|
||||||
);
|
|
||||||
|
|
||||||
await this.calendarEventRepository.save(
|
await calendarEventRepository.save(
|
||||||
eventsToUpdate,
|
eventsToUpdate,
|
||||||
{},
|
{},
|
||||||
transactionManager,
|
transactionManager,
|
||||||
);
|
);
|
||||||
|
|
||||||
await this.calendarChannelEventAssociationRepository.save(
|
await calendarChannelEventAssociationRepository.save(
|
||||||
calendarChannelEventAssociationsToSave,
|
calendarChannelEventAssociationsToSave,
|
||||||
{},
|
{},
|
||||||
transactionManager,
|
transactionManager,
|
||||||
|
|||||||
@ -5,8 +5,7 @@ import { IsNull } from 'typeorm';
|
|||||||
import { Process } from 'src/engine/integrations/message-queue/decorators/process.decorator';
|
import { Process } from 'src/engine/integrations/message-queue/decorators/process.decorator';
|
||||||
import { Processor } from 'src/engine/integrations/message-queue/decorators/processor.decorator';
|
import { Processor } from 'src/engine/integrations/message-queue/decorators/processor.decorator';
|
||||||
import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants';
|
import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants';
|
||||||
import { InjectWorkspaceRepository } from 'src/engine/twenty-orm/decorators/inject-workspace-repository.decorator';
|
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
|
||||||
import { CalendarChannelWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity';
|
import { CalendarChannelWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity';
|
||||||
import { CalendarEventParticipantWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-event-participant.workspace-entity';
|
import { CalendarEventParticipantWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-event-participant.workspace-entity';
|
||||||
import { CreateCompanyAndContactService } from 'src/modules/contact-creation-manager/services/create-company-and-contact.service';
|
import { CreateCompanyAndContactService } from 'src/modules/contact-creation-manager/services/create-company-and-contact.service';
|
||||||
@ -25,11 +24,8 @@ export class CalendarCreateCompanyAndContactAfterSyncJob {
|
|||||||
CalendarCreateCompanyAndContactAfterSyncJob.name,
|
CalendarCreateCompanyAndContactAfterSyncJob.name,
|
||||||
);
|
);
|
||||||
constructor(
|
constructor(
|
||||||
|
private readonly twentyORMManager: TwentyORMManager,
|
||||||
private readonly createCompanyAndContactService: CreateCompanyAndContactService,
|
private readonly createCompanyAndContactService: CreateCompanyAndContactService,
|
||||||
@InjectWorkspaceRepository(CalendarChannelWorkspaceEntity)
|
|
||||||
private readonly calendarChannelRepository: WorkspaceRepository<CalendarChannelWorkspaceEntity>,
|
|
||||||
@InjectWorkspaceRepository(CalendarEventParticipantWorkspaceEntity)
|
|
||||||
private readonly calendarEventParticipantRepository: WorkspaceRepository<CalendarEventParticipantWorkspaceEntity>,
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@Process(CalendarCreateCompanyAndContactAfterSyncJob.name)
|
@Process(CalendarCreateCompanyAndContactAfterSyncJob.name)
|
||||||
@ -41,7 +37,12 @@ export class CalendarCreateCompanyAndContactAfterSyncJob {
|
|||||||
);
|
);
|
||||||
const { workspaceId, calendarChannelId } = data;
|
const { workspaceId, calendarChannelId } = data;
|
||||||
|
|
||||||
const calendarChannel = await this.calendarChannelRepository.findOne({
|
const calendarChannelRepository =
|
||||||
|
await this.twentyORMManager.getRepository<CalendarChannelWorkspaceEntity>(
|
||||||
|
'calendarChannel',
|
||||||
|
);
|
||||||
|
|
||||||
|
const calendarChannel = await calendarChannelRepository.findOne({
|
||||||
where: {
|
where: {
|
||||||
id: calendarChannelId,
|
id: calendarChannelId,
|
||||||
},
|
},
|
||||||
@ -67,8 +68,13 @@ export class CalendarCreateCompanyAndContactAfterSyncJob {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const calendarEventParticipantRepository =
|
||||||
|
await this.twentyORMManager.getRepository<CalendarEventParticipantWorkspaceEntity>(
|
||||||
|
'calendarEventParticipant',
|
||||||
|
);
|
||||||
|
|
||||||
const calendarEventParticipantsWithoutPersonIdAndWorkspaceMemberId =
|
const calendarEventParticipantsWithoutPersonIdAndWorkspaceMemberId =
|
||||||
await this.calendarEventParticipantRepository.find({
|
await calendarEventParticipantRepository.find({
|
||||||
where: {
|
where: {
|
||||||
calendarEvent: {
|
calendarEvent: {
|
||||||
calendarChannelEventAssociations: {
|
calendarChannelEventAssociations: {
|
||||||
|
|||||||
@ -5,16 +5,14 @@ import { isDefined } from 'class-validator';
|
|||||||
import differenceWith from 'lodash.differencewith';
|
import differenceWith from 'lodash.differencewith';
|
||||||
import { Any } from 'typeorm';
|
import { Any } from 'typeorm';
|
||||||
|
|
||||||
import { InjectWorkspaceRepository } from 'src/engine/twenty-orm/decorators/inject-workspace-repository.decorator';
|
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
|
||||||
import { CalendarEventParticipantWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-event-participant.workspace-entity';
|
import { CalendarEventParticipantWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-event-participant.workspace-entity';
|
||||||
import { CalendarEventParticipantWithCalendarEventId } from 'src/modules/calendar/common/types/calendar-event';
|
import { CalendarEventParticipantWithCalendarEventId } from 'src/modules/calendar/common/types/calendar-event';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CalendarEventParticipantService {
|
export class CalendarEventParticipantService {
|
||||||
constructor(
|
constructor(
|
||||||
@InjectWorkspaceRepository(CalendarEventParticipantWorkspaceEntity)
|
private readonly twentyORMManager: TwentyORMManager,
|
||||||
private readonly calendarEventParticipantRepository: WorkspaceRepository<CalendarEventParticipantWorkspaceEntity>,
|
|
||||||
private readonly eventEmitter: EventEmitter2,
|
private readonly eventEmitter: EventEmitter2,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@ -23,8 +21,13 @@ export class CalendarEventParticipantService {
|
|||||||
participantsToUpdate: CalendarEventParticipantWithCalendarEventId[],
|
participantsToUpdate: CalendarEventParticipantWithCalendarEventId[],
|
||||||
transactionManager?: any,
|
transactionManager?: any,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
const calendarEventParticipantRepository =
|
||||||
|
await this.twentyORMManager.getRepository<CalendarEventParticipantWorkspaceEntity>(
|
||||||
|
'calendarEventParticipant',
|
||||||
|
);
|
||||||
|
|
||||||
const existingCalendarEventParticipants =
|
const existingCalendarEventParticipants =
|
||||||
await this.calendarEventParticipantRepository.find({
|
await calendarEventParticipantRepository.find({
|
||||||
where: {
|
where: {
|
||||||
calendarEventId: Any(
|
calendarEventId: Any(
|
||||||
participantsToUpdate
|
participantsToUpdate
|
||||||
@ -74,7 +77,7 @@ export class CalendarEventParticipantService {
|
|||||||
participantToUpdate.calendarEventId,
|
participantToUpdate.calendarEventId,
|
||||||
);
|
);
|
||||||
|
|
||||||
await this.calendarEventParticipantRepository.delete(
|
await calendarEventParticipantRepository.delete(
|
||||||
{
|
{
|
||||||
id: Any(
|
id: Any(
|
||||||
calendarEventParticipantsToDelete.map(
|
calendarEventParticipantsToDelete.map(
|
||||||
@ -86,7 +89,7 @@ export class CalendarEventParticipantService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
for (const calendarEventParticipantToUpdate of calendarEventParticipantsToUpdate) {
|
for (const calendarEventParticipantToUpdate of calendarEventParticipantsToUpdate) {
|
||||||
await this.calendarEventParticipantRepository.update(
|
await calendarEventParticipantRepository.update(
|
||||||
{
|
{
|
||||||
calendarEventId: calendarEventParticipantToUpdate.calendarEventId,
|
calendarEventId: calendarEventParticipantToUpdate.calendarEventId,
|
||||||
handle: calendarEventParticipantToUpdate.handle,
|
handle: calendarEventParticipantToUpdate.handle,
|
||||||
@ -100,7 +103,7 @@ export class CalendarEventParticipantService {
|
|||||||
|
|
||||||
participantsToSave.push(...newCalendarEventParticipants);
|
participantsToSave.push(...newCalendarEventParticipants);
|
||||||
|
|
||||||
await this.calendarEventParticipantRepository.save(
|
await calendarEventParticipantRepository.save(
|
||||||
participantsToSave,
|
participantsToSave,
|
||||||
{},
|
{},
|
||||||
transactionManager,
|
transactionManager,
|
||||||
@ -113,8 +116,13 @@ export class CalendarEventParticipantService {
|
|||||||
personId?: string,
|
personId?: string,
|
||||||
workspaceMemberId?: string,
|
workspaceMemberId?: string,
|
||||||
) {
|
) {
|
||||||
|
const calendarEventParticipantRepository =
|
||||||
|
await this.twentyORMManager.getRepository<CalendarEventParticipantWorkspaceEntity>(
|
||||||
|
'calendarEventParticipant',
|
||||||
|
);
|
||||||
|
|
||||||
const calendarEventParticipantsToUpdate =
|
const calendarEventParticipantsToUpdate =
|
||||||
await this.calendarEventParticipantRepository.find({
|
await calendarEventParticipantRepository.find({
|
||||||
where: {
|
where: {
|
||||||
handle: email,
|
handle: email,
|
||||||
},
|
},
|
||||||
@ -124,7 +132,7 @@ export class CalendarEventParticipantService {
|
|||||||
calendarEventParticipantsToUpdate.map((participant) => participant.id);
|
calendarEventParticipantsToUpdate.map((participant) => participant.id);
|
||||||
|
|
||||||
if (personId) {
|
if (personId) {
|
||||||
await this.calendarEventParticipantRepository.update(
|
await calendarEventParticipantRepository.update(
|
||||||
{
|
{
|
||||||
id: Any(calendarEventParticipantIdsToUpdate),
|
id: Any(calendarEventParticipantIdsToUpdate),
|
||||||
},
|
},
|
||||||
@ -136,7 +144,7 @@ export class CalendarEventParticipantService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const updatedCalendarEventParticipants =
|
const updatedCalendarEventParticipants =
|
||||||
await this.calendarEventParticipantRepository.find({
|
await calendarEventParticipantRepository.find({
|
||||||
where: {
|
where: {
|
||||||
id: Any(calendarEventParticipantIdsToUpdate),
|
id: Any(calendarEventParticipantIdsToUpdate),
|
||||||
},
|
},
|
||||||
@ -149,7 +157,7 @@ export class CalendarEventParticipantService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (workspaceMemberId) {
|
if (workspaceMemberId) {
|
||||||
await this.calendarEventParticipantRepository.update(
|
await calendarEventParticipantRepository.update(
|
||||||
{
|
{
|
||||||
id: Any(calendarEventParticipantIdsToUpdate),
|
id: Any(calendarEventParticipantIdsToUpdate),
|
||||||
},
|
},
|
||||||
@ -168,8 +176,13 @@ export class CalendarEventParticipantService {
|
|||||||
personId?: string,
|
personId?: string,
|
||||||
workspaceMemberId?: string,
|
workspaceMemberId?: string,
|
||||||
) {
|
) {
|
||||||
|
const calendarEventParticipantRepository =
|
||||||
|
await this.twentyORMManager.getRepository<CalendarEventParticipantWorkspaceEntity>(
|
||||||
|
'calendarEventParticipant',
|
||||||
|
);
|
||||||
|
|
||||||
if (personId) {
|
if (personId) {
|
||||||
await this.calendarEventParticipantRepository.update(
|
await calendarEventParticipantRepository.update(
|
||||||
{
|
{
|
||||||
handle,
|
handle,
|
||||||
},
|
},
|
||||||
@ -179,7 +192,7 @@ export class CalendarEventParticipantService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (workspaceMemberId) {
|
if (workspaceMemberId) {
|
||||||
await this.calendarEventParticipantRepository.update(
|
await calendarEventParticipantRepository.update(
|
||||||
{
|
{
|
||||||
handle,
|
handle,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
import { BadRequestException, NotFoundException, Scope } from '@nestjs/common';
|
import { BadRequestException, NotFoundException, Scope } from '@nestjs/common';
|
||||||
|
|
||||||
import { FindManyResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
|
||||||
import { WorkspaceQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface';
|
import { WorkspaceQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface';
|
||||||
|
import { FindManyResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||||
|
|
||||||
import { InjectWorkspaceRepository } from 'src/engine/twenty-orm/decorators/inject-workspace-repository.decorator';
|
|
||||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
|
||||||
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
|
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
|
||||||
|
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||||
import { CanAccessCalendarEventService } from 'src/modules/calendar/common/query-hooks/calendar-event/services/can-access-calendar-event.service';
|
import { CanAccessCalendarEventService } from 'src/modules/calendar/common/query-hooks/calendar-event/services/can-access-calendar-event.service';
|
||||||
import { CalendarChannelEventAssociationWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-channel-event-association.workspace-entity';
|
import { CalendarChannelEventAssociationWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-channel-event-association.workspace-entity';
|
||||||
|
|
||||||
@ -17,8 +16,7 @@ export class CalendarEventFindManyPreQueryHook
|
|||||||
implements WorkspaceQueryHookInstance
|
implements WorkspaceQueryHookInstance
|
||||||
{
|
{
|
||||||
constructor(
|
constructor(
|
||||||
@InjectWorkspaceRepository(CalendarChannelEventAssociationWorkspaceEntity)
|
private readonly twentyORMManager: TwentyORMManager,
|
||||||
private readonly calendarChannelEventAssociationRepository: WorkspaceRepository<CalendarChannelEventAssociationWorkspaceEntity>,
|
|
||||||
private readonly canAccessCalendarEventService: CanAccessCalendarEventService,
|
private readonly canAccessCalendarEventService: CanAccessCalendarEventService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@ -31,8 +29,13 @@ export class CalendarEventFindManyPreQueryHook
|
|||||||
throw new BadRequestException('id filter is required');
|
throw new BadRequestException('id filter is required');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const calendarChannelEventAssociationRepository =
|
||||||
|
await this.twentyORMManager.getRepository<CalendarChannelEventAssociationWorkspaceEntity>(
|
||||||
|
'calendarChannelEventAssociation',
|
||||||
|
);
|
||||||
|
|
||||||
const calendarChannelCalendarEventAssociations =
|
const calendarChannelCalendarEventAssociations =
|
||||||
await this.calendarChannelEventAssociationRepository.find({
|
await calendarChannelEventAssociationRepository.find({
|
||||||
where: {
|
where: {
|
||||||
calendarEventId: payload?.filter?.id?.eq,
|
calendarEventId: payload?.filter?.id?.eq,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -4,8 +4,7 @@ import { WorkspaceQueryHookInstance } from 'src/engine/api/graphql/workspace-que
|
|||||||
import { FindOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
import { FindOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||||
|
|
||||||
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
|
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
|
||||||
import { InjectWorkspaceRepository } from 'src/engine/twenty-orm/decorators/inject-workspace-repository.decorator';
|
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
|
||||||
import { CanAccessCalendarEventService } from 'src/modules/calendar/common/query-hooks/calendar-event/services/can-access-calendar-event.service';
|
import { CanAccessCalendarEventService } from 'src/modules/calendar/common/query-hooks/calendar-event/services/can-access-calendar-event.service';
|
||||||
import { CalendarChannelEventAssociationWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-channel-event-association.workspace-entity';
|
import { CalendarChannelEventAssociationWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-channel-event-association.workspace-entity';
|
||||||
|
|
||||||
@ -17,8 +16,7 @@ export class CalendarEventFindOnePreQueryHook
|
|||||||
implements WorkspaceQueryHookInstance
|
implements WorkspaceQueryHookInstance
|
||||||
{
|
{
|
||||||
constructor(
|
constructor(
|
||||||
@InjectWorkspaceRepository(CalendarChannelEventAssociationWorkspaceEntity)
|
private readonly twentyORMManager: TwentyORMManager,
|
||||||
private readonly calendarChannelEventAssociationRepository: WorkspaceRepository<CalendarChannelEventAssociationWorkspaceEntity>,
|
|
||||||
private readonly canAccessCalendarEventService: CanAccessCalendarEventService,
|
private readonly canAccessCalendarEventService: CanAccessCalendarEventService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@ -31,9 +29,14 @@ export class CalendarEventFindOnePreQueryHook
|
|||||||
throw new BadRequestException('id filter is required');
|
throw new BadRequestException('id filter is required');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const calendarChannelEventAssociationRepository =
|
||||||
|
await this.twentyORMManager.getRepository<CalendarChannelEventAssociationWorkspaceEntity>(
|
||||||
|
'calendarChannelEventAssociation',
|
||||||
|
);
|
||||||
|
|
||||||
// TODO: Re-implement this using twenty ORM
|
// TODO: Re-implement this using twenty ORM
|
||||||
const calendarChannelCalendarEventAssociations =
|
const calendarChannelCalendarEventAssociations =
|
||||||
await this.calendarChannelEventAssociationRepository.find({
|
await calendarChannelEventAssociationRepository.find({
|
||||||
where: {
|
where: {
|
||||||
calendarEventId: payload?.filter?.id?.eq,
|
calendarEventId: payload?.filter?.id?.eq,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -4,23 +4,21 @@ import groupBy from 'lodash.groupby';
|
|||||||
import { Any } from 'typeorm';
|
import { Any } from 'typeorm';
|
||||||
|
|
||||||
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
|
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
|
||||||
import { InjectWorkspaceRepository } from 'src/engine/twenty-orm/decorators/inject-workspace-repository.decorator';
|
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
import { CalendarChannelEventAssociationWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-channel-event-association.workspace-entity';
|
||||||
|
import {
|
||||||
|
CalendarChannelVisibility,
|
||||||
|
CalendarChannelWorkspaceEntity,
|
||||||
|
} from 'src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity';
|
||||||
import { ConnectedAccountRepository } from 'src/modules/connected-account/repositories/connected-account.repository';
|
import { ConnectedAccountRepository } from 'src/modules/connected-account/repositories/connected-account.repository';
|
||||||
import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
|
import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
|
||||||
import { WorkspaceMemberRepository } from 'src/modules/workspace-member/repositories/workspace-member.repository';
|
import { WorkspaceMemberRepository } from 'src/modules/workspace-member/repositories/workspace-member.repository';
|
||||||
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
|
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
|
||||||
import { CalendarChannelEventAssociationWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-channel-event-association.workspace-entity';
|
|
||||||
import {
|
|
||||||
CalendarChannelWorkspaceEntity,
|
|
||||||
CalendarChannelVisibility,
|
|
||||||
} from 'src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CanAccessCalendarEventService {
|
export class CanAccessCalendarEventService {
|
||||||
constructor(
|
constructor(
|
||||||
@InjectWorkspaceRepository(CalendarChannelWorkspaceEntity)
|
private readonly twentyORMManager: TwentyORMManager,
|
||||||
private readonly calendarChannelRepository: WorkspaceRepository<CalendarChannelWorkspaceEntity>,
|
|
||||||
@InjectObjectMetadataRepository(ConnectedAccountWorkspaceEntity)
|
@InjectObjectMetadataRepository(ConnectedAccountWorkspaceEntity)
|
||||||
private readonly connectedAccountRepository: ConnectedAccountRepository,
|
private readonly connectedAccountRepository: ConnectedAccountRepository,
|
||||||
@InjectObjectMetadataRepository(WorkspaceMemberWorkspaceEntity)
|
@InjectObjectMetadataRepository(WorkspaceMemberWorkspaceEntity)
|
||||||
@ -32,7 +30,12 @@ export class CanAccessCalendarEventService {
|
|||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
calendarChannelCalendarEventAssociations: CalendarChannelEventAssociationWorkspaceEntity[],
|
calendarChannelCalendarEventAssociations: CalendarChannelEventAssociationWorkspaceEntity[],
|
||||||
) {
|
) {
|
||||||
const calendarChannels = await this.calendarChannelRepository.find({
|
const calendarRepository =
|
||||||
|
await this.twentyORMManager.getRepository<CalendarChannelWorkspaceEntity>(
|
||||||
|
'calendarChannel',
|
||||||
|
);
|
||||||
|
|
||||||
|
const calendarChannels = await calendarRepository.find({
|
||||||
where: {
|
where: {
|
||||||
id: Any(
|
id: Any(
|
||||||
calendarChannelCalendarEventAssociations.map(
|
calendarChannelCalendarEventAssociations.map(
|
||||||
|
|||||||
@ -4,18 +4,16 @@ import { WorkspaceQueryHookInstance } from 'src/engine/api/graphql/workspace-que
|
|||||||
import { DeleteOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
import { DeleteOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||||
|
|
||||||
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
|
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
|
||||||
import { InjectWorkspaceRepository } from 'src/engine/twenty-orm/decorators/inject-workspace-repository.decorator';
|
|
||||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
|
||||||
import { MessageChannelWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
|
|
||||||
import { ObjectRecordDeleteEvent } from 'src/engine/integrations/event-emitter/types/object-record-delete.event';
|
import { ObjectRecordDeleteEvent } from 'src/engine/integrations/event-emitter/types/object-record-delete.event';
|
||||||
|
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||||
|
import { MessageChannelWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
|
||||||
|
|
||||||
@WorkspaceQueryHook(`connectedAccount.deleteOne`)
|
@WorkspaceQueryHook(`connectedAccount.deleteOne`)
|
||||||
export class ConnectedAccountDeleteOnePreQueryHook
|
export class ConnectedAccountDeleteOnePreQueryHook
|
||||||
implements WorkspaceQueryHookInstance
|
implements WorkspaceQueryHookInstance
|
||||||
{
|
{
|
||||||
constructor(
|
constructor(
|
||||||
@InjectWorkspaceRepository(MessageChannelWorkspaceEntity)
|
private readonly twentyORMManager: TwentyORMManager,
|
||||||
private readonly messageChannelRepository: WorkspaceRepository<MessageChannelWorkspaceEntity>,
|
|
||||||
private eventEmitter: EventEmitter2,
|
private eventEmitter: EventEmitter2,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@ -26,7 +24,12 @@ export class ConnectedAccountDeleteOnePreQueryHook
|
|||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const connectedAccountId = payload.id;
|
const connectedAccountId = payload.id;
|
||||||
|
|
||||||
const messageChannels = await this.messageChannelRepository.findBy({
|
const messageChannelRepository =
|
||||||
|
await this.twentyORMManager.getRepository<MessageChannelWorkspaceEntity>(
|
||||||
|
'messageChannel',
|
||||||
|
);
|
||||||
|
|
||||||
|
const messageChannels = await messageChannelRepository.findBy({
|
||||||
connectedAccountId,
|
connectedAccountId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -2,22 +2,26 @@ import { Injectable } from '@nestjs/common';
|
|||||||
|
|
||||||
import { EntityManager } from 'typeorm';
|
import { EntityManager } from 'typeorm';
|
||||||
|
|
||||||
import { InjectWorkspaceRepository } from 'src/engine/twenty-orm/decorators/inject-workspace-repository.decorator';
|
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
|
||||||
import { MessageThreadWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-thread.workspace-entity';
|
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';
|
import { MessageWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message.workspace-entity';
|
||||||
import { deleteUsingPagination } from 'src/modules/messaging/message-cleaner/utils/delete-using-pagination.util';
|
import { deleteUsingPagination } from 'src/modules/messaging/message-cleaner/utils/delete-using-pagination.util';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class MessagingMessageCleanerService {
|
export class MessagingMessageCleanerService {
|
||||||
constructor(
|
constructor(private readonly twentyORMManager: TwentyORMManager) {}
|
||||||
@InjectWorkspaceRepository(MessageWorkspaceEntity)
|
|
||||||
private readonly messageRepository: WorkspaceRepository<MessageWorkspaceEntity>,
|
|
||||||
@InjectWorkspaceRepository(MessageThreadWorkspaceEntity)
|
|
||||||
private readonly messageThreadRepository: WorkspaceRepository<MessageThreadWorkspaceEntity>,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public async cleanWorkspaceThreads(workspaceId: string) {
|
public async cleanWorkspaceThreads(workspaceId: string) {
|
||||||
|
const messageThreadRepository =
|
||||||
|
await this.twentyORMManager.getRepository<MessageThreadWorkspaceEntity>(
|
||||||
|
'messageThread',
|
||||||
|
);
|
||||||
|
|
||||||
|
const messageRepository =
|
||||||
|
await this.twentyORMManager.getRepository<MessageWorkspaceEntity>(
|
||||||
|
'message',
|
||||||
|
);
|
||||||
|
|
||||||
await deleteUsingPagination(
|
await deleteUsingPagination(
|
||||||
workspaceId,
|
workspaceId,
|
||||||
500,
|
500,
|
||||||
@ -27,7 +31,7 @@ export class MessagingMessageCleanerService {
|
|||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
transactionManager?: EntityManager,
|
transactionManager?: EntityManager,
|
||||||
) => {
|
) => {
|
||||||
const nonAssociatedMessages = await this.messageRepository.find(
|
const nonAssociatedMessages = await messageRepository.find(
|
||||||
{
|
{
|
||||||
where: {
|
where: {
|
||||||
messageChannelMessageAssociations: [],
|
messageChannelMessageAssociations: [],
|
||||||
@ -46,7 +50,7 @@ export class MessagingMessageCleanerService {
|
|||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
transactionManager?: EntityManager,
|
transactionManager?: EntityManager,
|
||||||
) => {
|
) => {
|
||||||
await this.messageRepository.delete(ids, transactionManager);
|
await messageRepository.delete(ids, transactionManager);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -59,7 +63,7 @@ export class MessagingMessageCleanerService {
|
|||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
transactionManager?: EntityManager,
|
transactionManager?: EntityManager,
|
||||||
) => {
|
) => {
|
||||||
const orphanThreads = await this.messageThreadRepository.find(
|
const orphanThreads = await messageThreadRepository.find(
|
||||||
{
|
{
|
||||||
where: {
|
where: {
|
||||||
messages: [],
|
messages: [],
|
||||||
@ -77,7 +81,7 @@ export class MessagingMessageCleanerService {
|
|||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
transactionManager?: EntityManager,
|
transactionManager?: EntityManager,
|
||||||
) => {
|
) => {
|
||||||
await this.messageThreadRepository.delete(ids, transactionManager);
|
await messageThreadRepository.delete(ids, transactionManager);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,14 +5,13 @@ import { In } from 'typeorm';
|
|||||||
import { Process } from 'src/engine/integrations/message-queue/decorators/process.decorator';
|
import { Process } from 'src/engine/integrations/message-queue/decorators/process.decorator';
|
||||||
import { Processor } from 'src/engine/integrations/message-queue/decorators/processor.decorator';
|
import { Processor } from 'src/engine/integrations/message-queue/decorators/processor.decorator';
|
||||||
import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants';
|
import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants';
|
||||||
|
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||||
|
import { MessagingChannelSyncStatusService } from 'src/modules/messaging/common/services/messaging-channel-sync-status.service';
|
||||||
import {
|
import {
|
||||||
MessageChannelSyncStage,
|
MessageChannelSyncStage,
|
||||||
MessageChannelWorkspaceEntity,
|
MessageChannelWorkspaceEntity,
|
||||||
} from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
|
} from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
|
||||||
import { isSyncStale } from 'src/modules/messaging/message-import-manager/utils/is-sync-stale.util';
|
import { isSyncStale } from 'src/modules/messaging/message-import-manager/utils/is-sync-stale.util';
|
||||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
|
||||||
import { InjectWorkspaceRepository } from 'src/engine/twenty-orm/decorators/inject-workspace-repository.decorator';
|
|
||||||
import { MessagingChannelSyncStatusService } from 'src/modules/messaging/common/services/messaging-channel-sync-status.service';
|
|
||||||
|
|
||||||
export type MessagingOngoingStaleJobData = {
|
export type MessagingOngoingStaleJobData = {
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
@ -25,8 +24,7 @@ export type MessagingOngoingStaleJobData = {
|
|||||||
export class MessagingOngoingStaleJob {
|
export class MessagingOngoingStaleJob {
|
||||||
private readonly logger = new Logger(MessagingOngoingStaleJob.name);
|
private readonly logger = new Logger(MessagingOngoingStaleJob.name);
|
||||||
constructor(
|
constructor(
|
||||||
@InjectWorkspaceRepository(MessageChannelWorkspaceEntity)
|
private readonly twentyORMManager: TwentyORMManager,
|
||||||
private readonly messageChannelRepository: WorkspaceRepository<MessageChannelWorkspaceEntity>,
|
|
||||||
private readonly messagingChannelSyncStatusService: MessagingChannelSyncStatusService,
|
private readonly messagingChannelSyncStatusService: MessagingChannelSyncStatusService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@ -34,7 +32,12 @@ export class MessagingOngoingStaleJob {
|
|||||||
async handle(data: MessagingOngoingStaleJobData): Promise<void> {
|
async handle(data: MessagingOngoingStaleJobData): Promise<void> {
|
||||||
const { workspaceId } = data;
|
const { workspaceId } = data;
|
||||||
|
|
||||||
const messageChannels = await this.messageChannelRepository.find({
|
const messageChannelRepository =
|
||||||
|
await this.twentyORMManager.getRepository<MessageChannelWorkspaceEntity>(
|
||||||
|
'messageChannel',
|
||||||
|
);
|
||||||
|
|
||||||
|
const messageChannels = await messageChannelRepository.find({
|
||||||
where: {
|
where: {
|
||||||
syncStage: In([
|
syncStage: In([
|
||||||
MessageChannelSyncStage.MESSAGES_IMPORT_ONGOING,
|
MessageChannelSyncStage.MESSAGES_IMPORT_ONGOING,
|
||||||
|
|||||||
@ -2,8 +2,7 @@ import { WorkspaceQueryHookInstance } from 'src/engine/api/graphql/workspace-que
|
|||||||
import { DeleteOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
import { DeleteOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||||
|
|
||||||
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
|
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
|
||||||
import { InjectWorkspaceRepository } from 'src/engine/twenty-orm/decorators/inject-workspace-repository.decorator';
|
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
|
||||||
import { CommentWorkspaceEntity } from 'src/modules/activity/standard-objects/comment.workspace-entity';
|
import { CommentWorkspaceEntity } from 'src/modules/activity/standard-objects/comment.workspace-entity';
|
||||||
import { AttachmentWorkspaceEntity } from 'src/modules/attachment/standard-objects/attachment.workspace-entity';
|
import { AttachmentWorkspaceEntity } from 'src/modules/attachment/standard-objects/attachment.workspace-entity';
|
||||||
|
|
||||||
@ -11,12 +10,7 @@ import { AttachmentWorkspaceEntity } from 'src/modules/attachment/standard-objec
|
|||||||
export class WorkspaceMemberDeleteOnePreQueryHook
|
export class WorkspaceMemberDeleteOnePreQueryHook
|
||||||
implements WorkspaceQueryHookInstance
|
implements WorkspaceQueryHookInstance
|
||||||
{
|
{
|
||||||
constructor(
|
constructor(private readonly twentyORMManager: TwentyORMManager) {}
|
||||||
@InjectWorkspaceRepository(AttachmentWorkspaceEntity)
|
|
||||||
private readonly attachmentRepository: WorkspaceRepository<AttachmentWorkspaceEntity>,
|
|
||||||
@InjectWorkspaceRepository(CommentWorkspaceEntity)
|
|
||||||
private readonly commentRepository: WorkspaceRepository<CommentWorkspaceEntity>,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
// There is no need to validate the user's access to the workspace member since we don't have permission yet.
|
// There is no need to validate the user's access to the workspace member since we don't have permission yet.
|
||||||
async execute(
|
async execute(
|
||||||
@ -24,13 +18,23 @@ export class WorkspaceMemberDeleteOnePreQueryHook
|
|||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
payload: DeleteOneResolverArgs,
|
payload: DeleteOneResolverArgs,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
const attachmentRepository =
|
||||||
|
await this.twentyORMManager.getRepository<AttachmentWorkspaceEntity>(
|
||||||
|
'attachment',
|
||||||
|
);
|
||||||
|
|
||||||
|
const commentRepository =
|
||||||
|
await this.twentyORMManager.getRepository<CommentWorkspaceEntity>(
|
||||||
|
'comment',
|
||||||
|
);
|
||||||
|
|
||||||
const authorId = payload.id;
|
const authorId = payload.id;
|
||||||
|
|
||||||
await this.attachmentRepository.delete({
|
await attachmentRepository.delete({
|
||||||
authorId,
|
authorId,
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.commentRepository.delete({
|
await commentRepository.delete({
|
||||||
authorId,
|
authorId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user