diff --git a/packages/prisma/migrations/20240918202101_adds_per_user_and_team_feature_flags/migration.sql b/packages/prisma/migrations/20240918202101_adds_per_user_and_team_feature_flags/migration.sql new file mode 100644 index 0000000000..0c8702fb3c --- /dev/null +++ b/packages/prisma/migrations/20240918202101_adds_per_user_and_team_feature_flags/migration.sql @@ -0,0 +1,33 @@ +-- CreateTable +CREATE TABLE "UserFeatures" ( + "userId" INTEGER NOT NULL, + "featureId" TEXT NOT NULL, + "assignedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "assignedBy" TEXT NOT NULL, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "UserFeatures_pkey" PRIMARY KEY ("userId","featureId") +); + +-- CreateTable +CREATE TABLE "TeamFeatures" ( + "teamId" INTEGER NOT NULL, + "featureId" TEXT NOT NULL, + "assignedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "assignedBy" TEXT NOT NULL, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "TeamFeatures_pkey" PRIMARY KEY ("teamId","featureId") +); + +-- AddForeignKey +ALTER TABLE "UserFeatures" ADD CONSTRAINT "UserFeatures_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "UserFeatures" ADD CONSTRAINT "UserFeatures_featureId_fkey" FOREIGN KEY ("featureId") REFERENCES "Feature"("slug") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "TeamFeatures" ADD CONSTRAINT "TeamFeatures_teamId_fkey" FOREIGN KEY ("teamId") REFERENCES "Team"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "TeamFeatures" ADD CONSTRAINT "TeamFeatures_featureId_fkey" FOREIGN KEY ("featureId") REFERENCES "Feature"("slug") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/packages/prisma/schema.prisma b/packages/prisma/schema.prisma index 4883cad79c..ffa466ebe8 100644 --- a/packages/prisma/schema.prisma +++ b/packages/prisma/schema.prisma @@ -330,12 +330,12 @@ model User { movedToProfile Profile? @relation("moved_to_profile", fields: [movedToProfileId], references: [id], onDelete: SetNull) secondaryEmails SecondaryEmail[] isPlatformManaged Boolean @default(false) - OutOfOfficeReasons OutOfOfficeReason[] smsLockState SMSLockState @default(UNLOCKED) smsLockReviewedByAdmin Boolean @default(false) NotificationsSubscriptions NotificationsSubscriptions[] referralLinkId String? + features UserFeatures[] @@unique([email]) @@unique([email, username]) @@ -437,6 +437,7 @@ model Team { activeOrgWorkflows WorkflowsOnTeams[] attributes Attribute[] smsLockReviewedByAdmin Boolean @default(false) + features TeamFeatures[] @@unique([slug, parentId]) @@index([parentId]) @@ -1142,24 +1143,50 @@ model VerifiedEmail { model Feature { // The feature slug, ex: 'v2-workflows' - slug String @id @unique + slug String @id @unique // If the feature is currently enabled - enabled Boolean @default(false) + enabled Boolean @default(false) // A short description of the feature description String? // The type of feature flag - type FeatureType? @default(RELEASE) + type FeatureType? @default(RELEASE) // If the flag is considered stale - stale Boolean? @default(false) + stale Boolean? @default(false) lastUsedAt DateTime? - createdAt DateTime? @default(now()) - updatedAt DateTime? @default(now()) @updatedAt + createdAt DateTime? @default(now()) + updatedAt DateTime? @default(now()) @updatedAt updatedBy Int? + users UserFeatures[] + teams TeamFeatures[] @@index([enabled]) @@index([stale]) } +model UserFeatures { + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + userId Int + feature Feature @relation(fields: [featureId], references: [slug], onDelete: Cascade) + featureId String + assignedAt DateTime @default(now()) + assignedBy String + updatedAt DateTime @updatedAt + + @@id([userId, featureId]) +} + +model TeamFeatures { + team Team @relation(fields: [teamId], references: [id], onDelete: Cascade) + teamId Int + feature Feature @relation(fields: [featureId], references: [slug], onDelete: Cascade) + featureId String + assignedAt DateTime @default(now()) + assignedBy String + updatedAt DateTime @updatedAt + + @@id([teamId, featureId]) +} + enum FeatureType { RELEASE EXPERIMENT