Fix user email unique constraint (#8898)
## Context Fix wrong unique index on user email as we don't want an index on email/deletedAt but a partial on a where condition on deletedAt. This should enforce email unicity excluding the ones that have a deletedAt ## Test Run ```sql SELECT email, COUNT(*) as duplicate_count FROM core."user" WHERE "deletedAt" IS NULL GROUP BY email HAVING COUNT(*) > 1 ORDER BY duplicate_count DESC; ``` to check duplicates before running the migration
This commit is contained in:
@ -0,0 +1,23 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class FixUserEmailUniqueConstraint1733408604468
|
||||||
|
implements MigrationInterface
|
||||||
|
{
|
||||||
|
name = 'FixUserEmailUniqueConstraint1733408604468';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "core"."user" DROP CONSTRAINT "UQ_USER_EMAIL"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE UNIQUE INDEX "UQ_USER_EMAIL" ON "core"."user" ("email") WHERE "deletedAt" IS NULL`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`DROP INDEX "core"."UQ_USER_EMAIL"`);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "core"."user" ADD CONSTRAINT "UQ_USER_EMAIL" UNIQUE ("email", "deletedAt")`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,11 +5,11 @@ import {
|
|||||||
Column,
|
Column,
|
||||||
CreateDateColumn,
|
CreateDateColumn,
|
||||||
Entity,
|
Entity,
|
||||||
|
Index,
|
||||||
ManyToOne,
|
ManyToOne,
|
||||||
OneToMany,
|
OneToMany,
|
||||||
PrimaryGeneratedColumn,
|
PrimaryGeneratedColumn,
|
||||||
Relation,
|
Relation,
|
||||||
Unique,
|
|
||||||
UpdateDateColumn,
|
UpdateDateColumn,
|
||||||
} from 'typeorm';
|
} from 'typeorm';
|
||||||
|
|
||||||
@ -28,7 +28,10 @@ registerEnumType(OnboardingStatus, {
|
|||||||
|
|
||||||
@Entity({ name: 'user', schema: 'core' })
|
@Entity({ name: 'user', schema: 'core' })
|
||||||
@ObjectType('User')
|
@ObjectType('User')
|
||||||
@Unique('UQ_USER_EMAIL', ['email', 'deletedAt'])
|
@Index('UQ_USER_EMAIL', ['email'], {
|
||||||
|
unique: true,
|
||||||
|
where: '"deletedAt" IS NULL',
|
||||||
|
})
|
||||||
export class User {
|
export class User {
|
||||||
@IDField(() => UUIDScalarType)
|
@IDField(() => UUIDScalarType)
|
||||||
@PrimaryGeneratedColumn('uuid')
|
@PrimaryGeneratedColumn('uuid')
|
||||||
|
|||||||
Reference in New Issue
Block a user