feat: keep deletions restorable and confirm a pipeline's deals before it is removed

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-13 22:23:09 +03:30
co-authored by Cursor
parent c04582072d
commit 2cc81bb596
17 changed files with 1158 additions and 6 deletions
@@ -0,0 +1,20 @@
ALTER TABLE "Organization" ADD COLUMN "deletionRetention" TEXT NOT NULL DEFAULT 'never';
CREATE TABLE "DeletionArchive" (
"id" TEXT NOT NULL,
"organizationId" TEXT NOT NULL,
"model" TEXT NOT NULL,
"entityId" TEXT NOT NULL,
"label" TEXT NOT NULL,
"snapshot" JSONB NOT NULL,
"deletedById" TEXT,
"deletedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "DeletionArchive_pkey" PRIMARY KEY ("id")
);
CREATE INDEX "DeletionArchive_organizationId_deletedAt_idx" ON "DeletionArchive"("organizationId", "deletedAt");
CREATE INDEX "DeletionArchive_organizationId_model_idx" ON "DeletionArchive"("organizationId", "model");
ALTER TABLE "DeletionArchive" ADD CONSTRAINT "DeletionArchive_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE "DeletionArchive" ADD CONSTRAINT "DeletionArchive_deletedById_fkey" FOREIGN KEY ("deletedById") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
+22
View File
@@ -235,6 +235,9 @@ model Organization {
gamificationBadges GamificationBadge[]
gamificationUserBadges GamificationUserBadge[]
gamificationBonuses GamificationBonus[]
/// month | two_months | three_months | six_months | year | never
deletionRetention String @default("never")
deletionArchives DeletionArchive[]
}
model User {
@@ -294,6 +297,7 @@ model User {
createdRoutineTasks RoutineTask[] @relation("RoutineTaskCreator")
routineTaskEvents RoutineTaskEvent[]
routineSettings RoutineUserSettings[]
deletionArchives DeletionArchive[] @relation("DeletionActor")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@ -1859,6 +1863,24 @@ model AuditLog {
@@index([organizationId, entityType, createdAt])
}
/// نسخهٔ قابل بازگشتِ رکوردهای حذف‌شده
model DeletionArchive {
id String @id @default(cuid())
organizationId String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
/// نام مدل پریزما
model String
entityId String
label String
snapshot Json
deletedById String?
deletedBy User? @relation("DeletionActor", fields: [deletedById], references: [id], onDelete: SetNull)
deletedAt DateTime @default(now())
@@index([organizationId, deletedAt])
@@index([organizationId, model])
}
/// فیلترهای ذخیره‌شده برای لیست‌ها و مسیرهای فروش
/// ستون‌های مخفی هر جدول برای هر کاربر (به‌ازای هر سازمان)
model UserTablePreference {