Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3c88950
clickhouse contact channel, team, and team member tables
BilalG1 Mar 16, 2026
9f9c9a4
clickhouse sync email outbox table
BilalG1 Mar 16, 2026
008c6b0
clickhouse sync session replays
BilalG1 Mar 16, 2026
10b2f19
fix analytics query test
BilalG1 Mar 16, 2026
ab778e1
add email outbox cols
BilalG1 Mar 16, 2026
3edc7f1
Merge branch 'dev' into clickhouse-sync-extra-tables
BilalG1 Mar 16, 2026
062b15e
Merge branch 'clickhouse-sync-extra-tables' into clickhouse-sync-emai…
BilalG1 Mar 16, 2026
e82a684
Merge branch 'clickhouse-sync-email-outbox-table' into clickhouse-syn…
BilalG1 Mar 16, 2026
e23c673
team member profile clickhouse table
BilalG1 Mar 17, 2026
823036b
Merge branch 'clickhouse-sync-extra-tables' of https://github.com/sta…
BilalG1 Mar 17, 2026
60e9b86
team member and team invite clickhouse tables
BilalG1 Mar 17, 2026
a1417f6
Merge remote-tracking branch 'origin/clickhouse-sync-team-member-and-…
BilalG1 Mar 17, 2026
3896f62
analytics query update test
BilalG1 Mar 17, 2026
7d797b5
Merge remote-tracking branch 'origin/clickhouse-sync-email-outbox-tab…
BilalG1 Mar 17, 2026
57176ab
update session replays table
BilalG1 Mar 17, 2026
66cff4d
clickhouse sync project permissions and notifications
BilalG1 Mar 18, 2026
bf008e2
clickhouse sync session and connected accounts
BilalG1 Mar 18, 2026
2bd11cb
clickhouse improve sync speed
BilalG1 Mar 18, 2026
d9503fb
remove extra comments
BilalG1 Mar 23, 2026
b969f45
Merge branch 'dev' into clickhouse-sync-improve-test-speed
BilalG1 Mar 23, 2026
b6f3f30
merge origin/dev
BilalG1 Apr 6, 2026
98ba678
pr comment fixes
BilalG1 Apr 6, 2026
82fabef
Merge branch 'dev' into clickhouse-sync-improve-test-speed
BilalG1 Apr 6, 2026
8111f4e
Merge branch 'dev' into clickhouse-sync-improve-test-speed
BilalG1 Apr 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- AlterTable
ALTER TABLE "Team" ADD COLUMN "sequenceId" BIGINT,
ADD COLUMN "shouldUpdateSequenceId" BOOLEAN NOT NULL DEFAULT true;

-- AlterTable
ALTER TABLE "TeamMember" ADD COLUMN "sequenceId" BIGINT,
ADD COLUMN "shouldUpdateSequenceId" BOOLEAN NOT NULL DEFAULT true;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-- AlterTable
ALTER TABLE "EmailOutbox" ADD COLUMN "sequenceId" BIGINT,
ADD COLUMN "shouldUpdateSequenceId" BOOLEAN NOT NULL DEFAULT true;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-- AlterTable
ALTER TABLE "SessionReplay" ADD COLUMN "sequenceId" BIGINT,
ADD COLUMN "shouldUpdateSequenceId" BOOLEAN NOT NULL DEFAULT true;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- AlterTable
ALTER TABLE "TeamMemberDirectPermission" ADD COLUMN "sequenceId" BIGINT,
ADD COLUMN "shouldUpdateSequenceId" BOOLEAN NOT NULL DEFAULT true;

-- AlterTable
ALTER TABLE "VerificationCode" ADD COLUMN "sequenceId" BIGINT,
ADD COLUMN "shouldUpdateSequenceId" BOOLEAN NOT NULL DEFAULT true;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- AlterTable
ALTER TABLE "ProjectUserDirectPermission" ADD COLUMN "sequenceId" BIGINT,
ADD COLUMN "shouldUpdateSequenceId" BOOLEAN NOT NULL DEFAULT true;

-- AlterTable
ALTER TABLE "UserNotificationPreference" ADD COLUMN "sequenceId" BIGINT,
ADD COLUMN "shouldUpdateSequenceId" BOOLEAN NOT NULL DEFAULT true;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- AlterTable
ALTER TABLE "ProjectUserRefreshToken" ADD COLUMN "sequenceId" BIGINT,
ADD COLUMN "shouldUpdateSequenceId" BOOLEAN NOT NULL DEFAULT true;

-- AlterTable
ALTER TABLE "ProjectUserOAuthAccount" ADD COLUMN "sequenceId" BIGINT,
ADD COLUMN "shouldUpdateSequenceId" BOOLEAN NOT NULL DEFAULT true;
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
-- Team indexes
-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS "Team_sequenceId_key" ON /* SCHEMA_NAME_SENTINEL */."Team"("sequenceId");

-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE INDEX CONCURRENTLY IF NOT EXISTS "Team_tenancyId_sequenceId_idx" ON /* SCHEMA_NAME_SENTINEL */."Team"("tenancyId", "sequenceId");

-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE INDEX CONCURRENTLY IF NOT EXISTS "Team_shouldUpdateSequenceId_idx" ON /* SCHEMA_NAME_SENTINEL */."Team"("shouldUpdateSequenceId", "tenancyId");

-- TeamMember indexes
-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS "TeamMember_sequenceId_key" ON /* SCHEMA_NAME_SENTINEL */."TeamMember"("sequenceId");

-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE INDEX CONCURRENTLY IF NOT EXISTS "TeamMember_tenancyId_sequenceId_idx" ON /* SCHEMA_NAME_SENTINEL */."TeamMember"("tenancyId", "sequenceId");

-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE INDEX CONCURRENTLY IF NOT EXISTS "TeamMember_shouldUpdateSequenceId_idx" ON /* SCHEMA_NAME_SENTINEL */."TeamMember"("shouldUpdateSequenceId", "tenancyId");

-- EmailOutbox indexes
-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS "EmailOutbox_sequenceId_key" ON /* SCHEMA_NAME_SENTINEL */."EmailOutbox"("sequenceId");

-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE INDEX CONCURRENTLY IF NOT EXISTS "EmailOutbox_tenancyId_sequenceId_idx" ON /* SCHEMA_NAME_SENTINEL */."EmailOutbox"("tenancyId", "sequenceId");

-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE INDEX CONCURRENTLY IF NOT EXISTS "EmailOutbox_shouldUpdateSequenceId_idx" ON /* SCHEMA_NAME_SENTINEL */."EmailOutbox"("shouldUpdateSequenceId", "tenancyId");

-- SessionReplay indexes
-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS "SessionReplay_sequenceId_key" ON /* SCHEMA_NAME_SENTINEL */."SessionReplay"("sequenceId");

-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE INDEX CONCURRENTLY IF NOT EXISTS "SessionReplay_tenancyId_sequenceId_idx" ON /* SCHEMA_NAME_SENTINEL */."SessionReplay"("tenancyId", "sequenceId");

-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE INDEX CONCURRENTLY IF NOT EXISTS "SessionReplay_shouldUpdateSequenceId_idx" ON /* SCHEMA_NAME_SENTINEL */."SessionReplay"("shouldUpdateSequenceId", "tenancyId");

-- TeamMemberDirectPermission indexes
-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS "TeamMemberDirectPermission_sequenceId_key" ON /* SCHEMA_NAME_SENTINEL */."TeamMemberDirectPermission"("sequenceId");

-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE INDEX CONCURRENTLY IF NOT EXISTS "TeamMemberDirectPermission_shouldUpdateSequenceId_idx" ON /* SCHEMA_NAME_SENTINEL */."TeamMemberDirectPermission"("shouldUpdateSequenceId", "tenancyId");

-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE INDEX CONCURRENTLY IF NOT EXISTS "TeamMemberDirectPermission_tenancyId_sequenceId_idx" ON /* SCHEMA_NAME_SENTINEL */."TeamMemberDirectPermission"("tenancyId", "sequenceId");

-- VerificationCode indexes
-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS "VerificationCode_sequenceId_key" ON /* SCHEMA_NAME_SENTINEL */."VerificationCode"("sequenceId");

-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE INDEX CONCURRENTLY IF NOT EXISTS "VerificationCode_shouldUpdateSequenceId_type_idx" ON /* SCHEMA_NAME_SENTINEL */."VerificationCode"("shouldUpdateSequenceId", "type");

-- ProjectUserDirectPermission indexes
-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS "ProjectUserDirectPermission_sequenceId_key" ON /* SCHEMA_NAME_SENTINEL */."ProjectUserDirectPermission"("sequenceId");

-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE INDEX CONCURRENTLY IF NOT EXISTS "ProjectUserDirectPermission_shouldUpdateSequenceId_idx" ON /* SCHEMA_NAME_SENTINEL */."ProjectUserDirectPermission"("shouldUpdateSequenceId", "tenancyId");

-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE INDEX CONCURRENTLY IF NOT EXISTS "ProjectUserDirectPermission_tenancyId_sequenceId_idx" ON /* SCHEMA_NAME_SENTINEL */."ProjectUserDirectPermission"("tenancyId", "sequenceId");

-- UserNotificationPreference indexes
-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS "UserNotificationPreference_sequenceId_key" ON /* SCHEMA_NAME_SENTINEL */."UserNotificationPreference"("sequenceId");

-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE INDEX CONCURRENTLY IF NOT EXISTS "UserNotificationPreference_shouldUpdateSequenceId_idx" ON /* SCHEMA_NAME_SENTINEL */."UserNotificationPreference"("shouldUpdateSequenceId", "tenancyId");

-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE INDEX CONCURRENTLY IF NOT EXISTS "UserNotificationPreference_tenancyId_sequenceId_idx" ON /* SCHEMA_NAME_SENTINEL */."UserNotificationPreference"("tenancyId", "sequenceId");

-- ProjectUserRefreshToken indexes
-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS "ProjectUserRefreshToken_sequenceId_key" ON /* SCHEMA_NAME_SENTINEL */."ProjectUserRefreshToken"("sequenceId");

-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE INDEX CONCURRENTLY IF NOT EXISTS "ProjectUserRefreshToken_shouldUpdateSequenceId_idx" ON /* SCHEMA_NAME_SENTINEL */."ProjectUserRefreshToken"("shouldUpdateSequenceId", "tenancyId");

-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE INDEX CONCURRENTLY IF NOT EXISTS "ProjectUserRefreshToken_tenancyId_sequenceId_idx" ON /* SCHEMA_NAME_SENTINEL */."ProjectUserRefreshToken"("tenancyId", "sequenceId");

-- ProjectUserOAuthAccount indexes
-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS "ProjectUserOAuthAccount_sequenceId_key" ON /* SCHEMA_NAME_SENTINEL */."ProjectUserOAuthAccount"("sequenceId");

-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE INDEX CONCURRENTLY IF NOT EXISTS "ProjectUserOAuthAccount_shouldUpdateSequenceId_idx" ON /* SCHEMA_NAME_SENTINEL */."ProjectUserOAuthAccount"("shouldUpdateSequenceId", "tenancyId");

-- SPLIT_STATEMENT_SENTINEL
-- SINGLE_STATEMENT_SENTINEL
-- RUN_OUTSIDE_TRANSACTION_SENTINEL
CREATE INDEX CONCURRENTLY IF NOT EXISTS "ProjectUserOAuthAccount_tenancyId_sequenceId_idx" ON /* SCHEMA_NAME_SENTINEL */."ProjectUserOAuthAccount"("tenancyId", "sequenceId");
49 changes: 49 additions & 0 deletions apps/backend/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -179,11 +179,16 @@ model Team {
serverMetadata Json?
profileImageUrl String?

sequenceId BigInt? @unique
shouldUpdateSequenceId Boolean @default(true)

teamMembers TeamMember[]
projectApiKey ProjectApiKey[]

@@id([tenancyId, teamId])
@@unique([mirroredProjectId, mirroredBranchId, teamId])
@@index([tenancyId, sequenceId], name: "Team_tenancyId_sequenceId_idx")
@@index([shouldUpdateSequenceId, tenancyId], name: "Team_shouldUpdateSequenceId_idx")
}

// This is used for fields that are boolean but only the true value is part of a unique constraint.
Expand All @@ -205,6 +210,9 @@ model TeamMember {
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt

sequenceId BigInt? @unique
shouldUpdateSequenceId Boolean @default(true)

projectUser ProjectUser @relation(fields: [tenancyId, projectUserId], references: [tenancyId, projectUserId], onDelete: Cascade)
team Team @relation(fields: [tenancyId, teamId], references: [tenancyId, teamId], onDelete: Cascade)
isSelected BooleanTrue?
Expand All @@ -213,6 +221,8 @@ model TeamMember {
@@id([tenancyId, projectUserId, teamId])
@@unique([tenancyId, projectUserId, isSelected])
@@index([tenancyId, projectUserId, isSelected], map: "TeamMember_projectUserId_isSelected_idx")
@@index([tenancyId, sequenceId], name: "TeamMember_tenancyId_sequenceId_idx")
@@index([shouldUpdateSequenceId, tenancyId], name: "TeamMember_shouldUpdateSequenceId_idx")
}

model ProjectUserDirectPermission {
Expand All @@ -226,7 +236,12 @@ model ProjectUserDirectPermission {

projectUser ProjectUser @relation(fields: [tenancyId, projectUserId], references: [tenancyId, projectUserId], onDelete: Cascade)

sequenceId BigInt? @unique
shouldUpdateSequenceId Boolean @default(true)

@@unique([tenancyId, projectUserId, permissionId])
@@index([shouldUpdateSequenceId, tenancyId], name: "ProjectUserDirectPermission_shouldUpdateSequenceId_idx")
@@index([tenancyId, sequenceId], name: "ProjectUserDirectPermission_tenancyId_sequenceId_idx")
}

model TeamMemberDirectPermission {
Expand All @@ -241,7 +256,12 @@ model TeamMemberDirectPermission {

teamMember TeamMember @relation(fields: [tenancyId, projectUserId, teamId], references: [tenancyId, projectUserId, teamId], onDelete: Cascade)

sequenceId BigInt? @unique
shouldUpdateSequenceId Boolean @default(true)

@@unique([tenancyId, projectUserId, teamId, permissionId])
@@index([shouldUpdateSequenceId, tenancyId], name: "TeamMemberDirectPermission_shouldUpdateSequenceId_idx")
@@index([tenancyId, sequenceId], name: "TeamMemberDirectPermission_tenancyId_sequenceId_idx")
}

model ProjectUser {
Expand Down Expand Up @@ -343,9 +363,14 @@ model ProjectUserOAuthAccount {
allowConnectedAccounts Boolean @default(true)
allowSignIn Boolean @default(true)

sequenceId BigInt? @unique
shouldUpdateSequenceId Boolean @default(true)

@@id([tenancyId, id])
@@unique([tenancyId, configOAuthProviderId, projectUserId, providerAccountId])
@@index([tenancyId, projectUserId])
@@index([tenancyId, sequenceId], name: "ProjectUserOAuthAccount_tenancyId_sequenceId_idx")
@@index([shouldUpdateSequenceId, tenancyId], name: "ProjectUserOAuthAccount_shouldUpdateSequenceId_idx")
}

model SessionReplay {
Expand All @@ -361,6 +386,9 @@ model SessionReplay {
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt

sequenceId BigInt? @unique
shouldUpdateSequenceId Boolean @default(true)

projectUser ProjectUser @relation(fields: [tenancyId, projectUserId], references: [tenancyId, projectUserId], onDelete: Cascade)
tenancy Tenancy @relation(fields: [tenancyId], references: [id], onDelete: Cascade)

Expand All @@ -371,6 +399,8 @@ model SessionReplay {
@@index([tenancyId, lastEventAt])
// index by updatedAt instead of lastEventAt because event timing can be spoofed
@@index([tenancyId, refreshTokenId, updatedAt])
@@index([tenancyId, sequenceId], name: "SessionReplay_tenancyId_sequenceId_idx")
@@index([shouldUpdateSequenceId, tenancyId], name: "SessionReplay_shouldUpdateSequenceId_idx")
@@map("SessionReplay")
}

Expand Down Expand Up @@ -612,7 +642,12 @@ model ProjectUserRefreshToken {
expiresAt DateTime?
isImpersonation Boolean @default(false)

sequenceId BigInt? @unique
shouldUpdateSequenceId Boolean @default(true)

@@id([tenancyId, id])
@@index([tenancyId, sequenceId], name: "ProjectUserRefreshToken_tenancyId_sequenceId_idx")
@@index([shouldUpdateSequenceId, tenancyId], name: "ProjectUserRefreshToken_shouldUpdateSequenceId_idx")
}

model ProjectUserAuthorizationCode {
Expand Down Expand Up @@ -655,9 +690,13 @@ model VerificationCode {
data Json
attemptCount Int @default(0)

sequenceId BigInt? @unique
shouldUpdateSequenceId Boolean @default(true)

@@id([projectId, branchId, id])
@@unique([projectId, branchId, code])
@@index([data(ops: JsonbPathOps)], type: Gin)
@@index([shouldUpdateSequenceId, type], name: "VerificationCode_shouldUpdateSequenceId_type_idx")
}

enum VerificationCodeType {
Expand Down Expand Up @@ -1012,13 +1051,18 @@ model EmailOutbox {
unsubscribedAt DateTime?
markedAsSpamAt DateTime?

sequenceId BigInt? @unique
shouldUpdateSequenceId Boolean @default(true)

tenancy Tenancy @relation(fields: [tenancyId], references: [id], onDelete: Cascade)

@@id([tenancyId, id])
@@index([tenancyId, finishedSendingAt(sort: Desc), scheduledAtIfNotYetQueued(sort: Desc), priority, id], map: "EmailOutbox_ordering_idx")
@@index([tenancyId, simpleStatus], map: "EmailOutbox_simple_status_tenancy_idx")
@@index([tenancyId, status], map: "EmailOutbox_status_tenancy_idx")
@@index([isQueued], map: "EmailOutbox_isQueued_idx")
@@index([tenancyId, sequenceId], name: "EmailOutbox_tenancyId_sequenceId_idx")
@@index([shouldUpdateSequenceId, tenancyId], name: "EmailOutbox_shouldUpdateSequenceId_idx")
}

model EmailOutboxProcessingMetadata {
Expand Down Expand Up @@ -1078,8 +1122,13 @@ model UserNotificationPreference {
enabled Boolean
projectUser ProjectUser @relation(fields: [tenancyId, projectUserId], references: [tenancyId, projectUserId], onDelete: Cascade)

sequenceId BigInt? @unique
shouldUpdateSequenceId Boolean @default(true)

@@id([tenancyId, id])
@@unique([tenancyId, projectUserId, notificationCategoryId])
@@index([shouldUpdateSequenceId, tenancyId], name: "UserNotificationPreference_shouldUpdateSequenceId_idx")
@@index([tenancyId, sequenceId], name: "UserNotificationPreference_tenancyId_sequenceId_idx")
}

model ThreadMessage {
Expand Down
Loading
Loading