feat: باشگاه امتیازات کارکنان (موتور امتیاز، جدول رتبه، فروشگاه پاداش، نشانها، پنل مدیریت و گزارش ROI)
- موتور رویدادمحور با شرط، محدودیت، تأیید مدیر و idempotency - اتصال به لید، مشتری، معامله، فعالیت، روتین، پیشفاکتور، فاکتور و تیکت - صفحه /club و /club/admin، اعلان زنده امتیاز، آیتم منو - انتقال فرمساز سرنخ به ابزارها Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,255 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "GamificationSettings" (
|
||||
"id" TEXT NOT NULL,
|
||||
"organizationId" TEXT NOT NULL,
|
||||
"enabled" BOOLEAN NOT NULL DEFAULT true,
|
||||
"levels" JSONB NOT NULL DEFAULT '[]',
|
||||
"monthlyGoal" INTEGER NOT NULL DEFAULT 1500,
|
||||
"showFullLeaderboard" BOOLEAN NOT NULL DEFAULT true,
|
||||
"enabledAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "GamificationSettings_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "GamificationRule" (
|
||||
"id" TEXT NOT NULL,
|
||||
"organizationId" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"event" TEXT NOT NULL,
|
||||
"score" INTEGER NOT NULL DEFAULT 0,
|
||||
"coins" INTEGER NOT NULL DEFAULT 0,
|
||||
"conditions" JSONB NOT NULL DEFAULT '[]',
|
||||
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||
"maxPerDay" INTEGER,
|
||||
"maxCoinsPerDay" INTEGER,
|
||||
"maxPerUser" INTEGER,
|
||||
"cooldownMinutes" INTEGER,
|
||||
"oncePerEntity" BOOLEAN NOT NULL DEFAULT false,
|
||||
"firstTimeOnly" BOOLEAN NOT NULL DEFAULT false,
|
||||
"requiresApproval" BOOLEAN NOT NULL DEFAULT false,
|
||||
"roles" TEXT[] DEFAULT ARRAY[]::TEXT[],
|
||||
"teamIds" TEXT[] DEFAULT ARRAY[]::TEXT[],
|
||||
"position" INTEGER NOT NULL DEFAULT 0,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "GamificationRule_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "GamificationTransaction" (
|
||||
"id" TEXT NOT NULL,
|
||||
"organizationId" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"kind" TEXT NOT NULL,
|
||||
"event" TEXT,
|
||||
"ruleId" TEXT,
|
||||
"bonusId" TEXT,
|
||||
"badgeId" TEXT,
|
||||
"score" INTEGER NOT NULL DEFAULT 0,
|
||||
"coins" INTEGER NOT NULL DEFAULT 0,
|
||||
"status" TEXT NOT NULL DEFAULT 'approved',
|
||||
"title" TEXT NOT NULL,
|
||||
"entityType" TEXT,
|
||||
"entityId" TEXT,
|
||||
"entityTitle" TEXT,
|
||||
"idempotencyKey" TEXT,
|
||||
"reason" TEXT,
|
||||
"createdById" TEXT,
|
||||
"decidedById" TEXT,
|
||||
"decidedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "GamificationTransaction_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "GamificationWallet" (
|
||||
"id" TEXT NOT NULL,
|
||||
"organizationId" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"score" INTEGER NOT NULL DEFAULT 0,
|
||||
"coins" INTEGER NOT NULL DEFAULT 0,
|
||||
"coinsEarned" INTEGER NOT NULL DEFAULT 0,
|
||||
"bestMonthScore" INTEGER NOT NULL DEFAULT 0,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "GamificationWallet_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "GamificationReward" (
|
||||
"id" TEXT NOT NULL,
|
||||
"organizationId" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"cost" INTEGER NOT NULL,
|
||||
"icon" TEXT NOT NULL DEFAULT 'gift',
|
||||
"color" TEXT NOT NULL DEFAULT '#14b8a6',
|
||||
"stock" INTEGER,
|
||||
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||
"requiresApproval" BOOLEAN NOT NULL DEFAULT true,
|
||||
"position" INTEGER NOT NULL DEFAULT 0,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "GamificationReward_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "GamificationRedemption" (
|
||||
"id" TEXT NOT NULL,
|
||||
"organizationId" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"rewardId" TEXT NOT NULL,
|
||||
"cost" INTEGER NOT NULL,
|
||||
"status" TEXT NOT NULL DEFAULT 'pending',
|
||||
"note" TEXT,
|
||||
"decisionNote" TEXT,
|
||||
"decidedById" TEXT,
|
||||
"decidedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "GamificationRedemption_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "GamificationBadge" (
|
||||
"id" TEXT NOT NULL,
|
||||
"organizationId" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"icon" TEXT NOT NULL DEFAULT 'medal',
|
||||
"color" TEXT NOT NULL DEFAULT '#f59e0b',
|
||||
"metric" TEXT NOT NULL,
|
||||
"event" TEXT,
|
||||
"threshold" INTEGER NOT NULL,
|
||||
"coins" INTEGER NOT NULL DEFAULT 0,
|
||||
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||
"position" INTEGER NOT NULL DEFAULT 0,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "GamificationBadge_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "GamificationUserBadge" (
|
||||
"id" TEXT NOT NULL,
|
||||
"organizationId" TEXT NOT NULL,
|
||||
"badgeId" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"earnedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "GamificationUserBadge_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "GamificationBonus" (
|
||||
"id" TEXT NOT NULL,
|
||||
"organizationId" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"kind" TEXT NOT NULL,
|
||||
"event" TEXT,
|
||||
"threshold" INTEGER NOT NULL DEFAULT 1,
|
||||
"period" TEXT NOT NULL DEFAULT 'month',
|
||||
"score" INTEGER NOT NULL DEFAULT 0,
|
||||
"coins" INTEGER NOT NULL DEFAULT 0,
|
||||
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "GamificationBonus_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "GamificationSettings_organizationId_key" ON "GamificationSettings"("organizationId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "GamificationRule_organizationId_event_isActive_idx" ON "GamificationRule"("organizationId", "event", "isActive");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "GamificationTransaction_organizationId_createdAt_idx" ON "GamificationTransaction"("organizationId", "createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "GamificationTransaction_organizationId_userId_createdAt_idx" ON "GamificationTransaction"("organizationId", "userId", "createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "GamificationTransaction_organizationId_ruleId_userId_create_idx" ON "GamificationTransaction"("organizationId", "ruleId", "userId", "createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "GamificationTransaction_organizationId_status_idx" ON "GamificationTransaction"("organizationId", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "GamificationTransaction_organizationId_idempotencyKey_key" ON "GamificationTransaction"("organizationId", "idempotencyKey");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "GamificationWallet_organizationId_score_idx" ON "GamificationWallet"("organizationId", "score");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "GamificationWallet_organizationId_userId_key" ON "GamificationWallet"("organizationId", "userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "GamificationReward_organizationId_isActive_idx" ON "GamificationReward"("organizationId", "isActive");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "GamificationRedemption_organizationId_status_idx" ON "GamificationRedemption"("organizationId", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "GamificationRedemption_organizationId_userId_idx" ON "GamificationRedemption"("organizationId", "userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "GamificationBadge_organizationId_isActive_idx" ON "GamificationBadge"("organizationId", "isActive");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "GamificationUserBadge_organizationId_userId_idx" ON "GamificationUserBadge"("organizationId", "userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "GamificationUserBadge_badgeId_userId_key" ON "GamificationUserBadge"("badgeId", "userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "GamificationBonus_organizationId_isActive_idx" ON "GamificationBonus"("organizationId", "isActive");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "GamificationSettings" ADD CONSTRAINT "GamificationSettings_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "GamificationRule" ADD CONSTRAINT "GamificationRule_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "GamificationTransaction" ADD CONSTRAINT "GamificationTransaction_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "GamificationWallet" ADD CONSTRAINT "GamificationWallet_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "GamificationReward" ADD CONSTRAINT "GamificationReward_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "GamificationRedemption" ADD CONSTRAINT "GamificationRedemption_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "GamificationRedemption" ADD CONSTRAINT "GamificationRedemption_rewardId_fkey" FOREIGN KEY ("rewardId") REFERENCES "GamificationReward"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "GamificationBadge" ADD CONSTRAINT "GamificationBadge_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "GamificationUserBadge" ADD CONSTRAINT "GamificationUserBadge_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "GamificationUserBadge" ADD CONSTRAINT "GamificationUserBadge_badgeId_fkey" FOREIGN KEY ("badgeId") REFERENCES "GamificationBadge"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "GamificationBonus" ADD CONSTRAINT "GamificationBonus_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- Enable the new module for orgs with an explicit module list
|
||||
UPDATE "Organization"
|
||||
SET "enabledModules" = array_append("enabledModules", 'gamification')
|
||||
WHERE cardinality("enabledModules") > 0 AND NOT ('gamification' = ANY("enabledModules"));
|
||||
+987
-785
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user