diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/2-9/2-9-instance-command-fast-1780050277781-add-email-group-suppressed-recipient.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/2-9/2-9-instance-command-fast-1780060974610-add-email-group-suppressed-recipient.ts similarity index 90% rename from packages/twenty-server/src/database/commands/upgrade-version-command/2-9/2-9-instance-command-fast-1780050277781-add-email-group-suppressed-recipient.ts rename to packages/twenty-server/src/database/commands/upgrade-version-command/2-9/2-9-instance-command-fast-1780060974610-add-email-group-suppressed-recipient.ts index 99f49855502..e91ae598a12 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/2-9/2-9-instance-command-fast-1780050277781-add-email-group-suppressed-recipient.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/2-9/2-9-instance-command-fast-1780060974610-add-email-group-suppressed-recipient.ts @@ -3,13 +3,13 @@ import { QueryRunner } from 'typeorm'; import { RegisteredInstanceCommand } from 'src/engine/core-modules/upgrade/decorators/registered-instance-command.decorator'; import { FastInstanceCommand } from 'src/engine/core-modules/upgrade/interfaces/fast-instance-command.interface'; -@RegisteredInstanceCommand('2.9.0', 1780050277781) +@RegisteredInstanceCommand('2.9.0', 1780060974610) export class AddEmailGroupSuppressedRecipientFastInstanceCommand implements FastInstanceCommand { public async up(queryRunner: QueryRunner): Promise { await queryRunner.query('CREATE TYPE "core"."emailGroupSuppressedRecipient_scope_enum" AS ENUM(\'GLOBAL\', \'CAMPAIGN\')'); await queryRunner.query('CREATE TYPE "core"."emailGroupSuppressedRecipient_reason_enum" AS ENUM(\'HARD_BOUNCE\', \'COMPLAINT\', \'UNSUBSCRIBE\')'); await queryRunner.query('CREATE TYPE "core"."emailGroupSuppressedRecipient_createdbysource_enum" AS ENUM(\'EMAIL\', \'CALENDAR\', \'WORKFLOW\', \'AGENT\', \'API\', \'IMPORT\', \'MANUAL\', \'SYSTEM\', \'WEBHOOK\', \'APPLICATION\')'); - await queryRunner.query('CREATE TABLE "core"."emailGroupSuppressedRecipient" ("workspaceId" uuid NOT NULL, "id" uuid NOT NULL DEFAULT uuid_generate_v4(), "emailAddress" character varying NOT NULL, "scope" "core"."emailGroupSuppressedRecipient_scope_enum" NOT NULL, "reason" "core"."emailGroupSuppressedRecipient_reason_enum" NOT NULL, "isSuppressed" boolean NOT NULL DEFAULT true, "providerEventId" character varying, "createdBySource" "core"."emailGroupSuppressedRecipient_createdbysource_enum" NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), CONSTRAINT "IDX_EMAIL_GROUP_SUPPRESSED_RECIPIENT_WORKSPACE_EMAIL_SCOPE_UNIQUE" UNIQUE ("workspaceId", "emailAddress", "scope"), CONSTRAINT "PK_55b0607e539d7941cbaedf1328a" PRIMARY KEY ("id"))'); + await queryRunner.query('CREATE TABLE "core"."emailGroupSuppressedRecipient" ("workspaceId" uuid NOT NULL, "id" uuid NOT NULL DEFAULT uuid_generate_v4(), "emailAddress" character varying NOT NULL, "scope" "core"."emailGroupSuppressedRecipient_scope_enum" NOT NULL, "reason" "core"."emailGroupSuppressedRecipient_reason_enum" NOT NULL, "isSuppressed" boolean NOT NULL DEFAULT true, "providerEventId" character varying, "createdBySource" "core"."emailGroupSuppressedRecipient_createdbysource_enum" NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), CONSTRAINT "IDX_EMAIL_GROUP_SUPPRESSED_RECIPIENT_WS_EMAIL_SCOPE_UNIQUE" UNIQUE ("workspaceId", "emailAddress", "scope"), CONSTRAINT "PK_55b0607e539d7941cbaedf1328a" PRIMARY KEY ("id"))'); await queryRunner.query('ALTER TABLE "core"."emailGroupSuppressedRecipient" ADD CONSTRAINT "FK_866066f1e73b748f917fd6fcd80" FOREIGN KEY ("workspaceId") REFERENCES "core"."workspace"("id") ON DELETE CASCADE ON UPDATE NO ACTION'); } diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/instance-commands.constant.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/instance-commands.constant.ts index ab15d93092f..2ed96b22862 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/instance-commands.constant.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/instance-commands.constant.ts @@ -58,7 +58,7 @@ import { DropFieldMetadataIsUniqueColumnFastInstanceCommand } from 'src/database import { EmailingDomainTenantStatusAndGlobalUniquenessFastInstanceCommand } from 'src/database/commands/upgrade-version-command/2-9/2-9-instance-command-fast-1799000020000-emailing-domain-tenant-status-and-global-uniqueness'; import { EncryptNonSecretApplicationVariableSlowInstanceCommand } from 'src/database/commands/upgrade-version-command/2-9/2-9-instance-command-slow-1798400000000-encrypt-non-secret-application-variable'; import { MigrateAiModelPreferencesSlowInstanceCommand } from 'src/database/commands/upgrade-version-command/2-9/2-9-instance-command-slow-1799000010000-migrate-ai-model-preferences'; -import { AddEmailGroupSuppressedRecipientFastInstanceCommand } from 'src/database/commands/upgrade-version-command/2-9/2-9-instance-command-fast-1780050277781-add-email-group-suppressed-recipient'; +import { AddEmailGroupSuppressedRecipientFastInstanceCommand } from 'src/database/commands/upgrade-version-command/2-9/2-9-instance-command-fast-1780060974610-add-email-group-suppressed-recipient'; export const INSTANCE_COMMANDS = [ AddViewFieldGroupIdIndexOnViewFieldFastInstanceCommand, diff --git a/packages/twenty-server/src/engine/core-modules/emailing-domain/email-group-suppressed-recipient.entity.ts b/packages/twenty-server/src/engine/core-modules/emailing-domain/email-group-suppressed-recipient.entity.ts index 80a012ebbb3..9a9b9f852b2 100644 --- a/packages/twenty-server/src/engine/core-modules/emailing-domain/email-group-suppressed-recipient.entity.ts +++ b/packages/twenty-server/src/engine/core-modules/emailing-domain/email-group-suppressed-recipient.entity.ts @@ -14,7 +14,7 @@ import { EmailGroupSuppressionScope } from 'src/engine/core-modules/emailing-dom import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/types/workspace-related-entity'; @Entity({ name: 'emailGroupSuppressedRecipient', schema: 'core' }) -@Unique('IDX_EMAIL_GROUP_SUPPRESSED_RECIPIENT_WORKSPACE_EMAIL_SCOPE_UNIQUE', [ +@Unique('IDX_EMAIL_GROUP_SUPPRESSED_RECIPIENT_WS_EMAIL_SCOPE_UNIQUE', [ 'workspaceId', 'emailAddress', 'scope', diff --git a/packages/twenty-server/src/engine/core-modules/emailing-domain/services/email-group-suppression.service.ts b/packages/twenty-server/src/engine/core-modules/emailing-domain/services/email-group-suppression.service.ts index 472115aa133..b772af44716 100644 --- a/packages/twenty-server/src/engine/core-modules/emailing-domain/services/email-group-suppression.service.ts +++ b/packages/twenty-server/src/engine/core-modules/emailing-domain/services/email-group-suppression.service.ts @@ -1,7 +1,8 @@ import { Injectable } from '@nestjs/common'; +import { isNonEmptyString } from '@sniptt/guards'; import { FieldActorSource } from 'twenty-shared/types'; -import { isDefined, isNonEmptyArray } from 'twenty-shared/utils'; +import { isNonEmptyArray } from 'twenty-shared/utils'; import { In } from 'typeorm'; import { BLOCKED_SCOPES_BY_SEND_TYPE } from 'src/engine/core-modules/emailing-domain/constants/blocked-scopes-by-send-type.constant'; @@ -66,32 +67,22 @@ export class EmailGroupSuppressionService { providerEventId = null, }: SuppressRecipientArgs): Promise { const normalizedEmailAddress = emailAddress.trim().toLowerCase(); - const scope = SUPPRESSION_SCOPE_BY_REASON[reason]; - - const existingSuppression = - await this.suppressedRecipientRepository.findOne(workspaceId, { - where: { emailAddress: normalizedEmailAddress, scope }, - }); - - if (isDefined(existingSuppression)) { - if (!existingSuppression.isSuppressed) { - await this.suppressedRecipientRepository.update( - workspaceId, - { id: existingSuppression.id }, - { isSuppressed: true }, - ); - } + if (!isNonEmptyString(normalizedEmailAddress)) { return; } - await this.suppressedRecipientRepository.save(workspaceId, { - emailAddress: normalizedEmailAddress, - scope, - reason, - isSuppressed: true, - createdBySource, - providerEventId, - }); + await this.suppressedRecipientRepository.upsert( + workspaceId, + { + emailAddress: normalizedEmailAddress, + scope: SUPPRESSION_SCOPE_BY_REASON[reason], + reason, + isSuppressed: true, + createdBySource, + providerEventId, + }, + ['workspaceId', 'emailAddress', 'scope'], + ); } }