Bariki cashback, order edit, and current work in progress
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
dda917fc71
commit
45477fb018
94 files changed
+10955
-650
No files matched your search
@@ -0,0 +1,267 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "PointsKind" AS ENUM ('ORDER', 'BONUS');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "PointsStatus" AS ENUM ('PENDING', 'ACTIVE', 'SPENT', 'EXPIRED', 'REVERSED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "PointsChannel" AS ENUM ('WEB', 'BOT', 'CSV', 'AUTO', 'CLIENT');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "RedemptionStatus" AS ENUM ('REQUESTED', 'CONFIRMED', 'REJECTED', 'REVERSED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "SuggestionStatus" AS ENUM ('OPEN', 'ACCEPTED', 'REJECTED');
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Agency" ADD COLUMN "housewarmingDays" INTEGER NOT NULL DEFAULT 60,
|
||||
ADD COLUMN "housewarmingPoints" INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Client" ADD COLUMN "pointsActive" INTEGER NOT NULL DEFAULT 0,
|
||||
ADD COLUMN "pointsActivityAt" TIMESTAMP(3),
|
||||
ADD COLUMN "pointsDebt" INTEGER NOT NULL DEFAULT 0,
|
||||
ADD COLUMN "pointsPending" INTEGER NOT NULL DEFAULT 0,
|
||||
ADD COLUMN "pointsWarn14At" TIMESTAMP(3),
|
||||
ADD COLUMN "pointsWarn3At" TIMESTAMP(3),
|
||||
ADD COLUMN "streakCount" INTEGER NOT NULL DEFAULT 0,
|
||||
ADD COLUMN "streakLastAt" TIMESTAMP(3);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Order" ADD COLUMN "pointsUsed" INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Service" ADD COLUMN "pointsCategoryId" TEXT;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "PointsCategory" (
|
||||
"id" TEXT NOT NULL,
|
||||
"code" TEXT NOT NULL,
|
||||
"name" JSONB NOT NULL,
|
||||
"rateBarev" INTEGER NOT NULL,
|
||||
"ratePlus" INTEGER NOT NULL,
|
||||
"rateElite" INTEGER NOT NULL,
|
||||
"active" BOOLEAN NOT NULL DEFAULT true,
|
||||
"sortOrder" INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
CONSTRAINT "PointsCategory_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "PointsBonusType" (
|
||||
"id" TEXT NOT NULL,
|
||||
"code" TEXT NOT NULL,
|
||||
"name" JSONB NOT NULL,
|
||||
"defaultAmount" INTEGER NOT NULL,
|
||||
"ttlDays" INTEGER,
|
||||
"active" BOOLEAN NOT NULL DEFAULT true,
|
||||
"sortOrder" INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
CONSTRAINT "PointsBonusType_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "PointsAccrual" (
|
||||
"id" TEXT NOT NULL,
|
||||
"clientId" TEXT NOT NULL,
|
||||
"kind" "PointsKind" NOT NULL,
|
||||
"categoryId" TEXT,
|
||||
"bonusTypeId" TEXT,
|
||||
"orderId" TEXT,
|
||||
"orderRef" TEXT,
|
||||
"orderAmount" INTEGER,
|
||||
"excludedAmount" INTEGER NOT NULL DEFAULT 0,
|
||||
"paidWithPoints" INTEGER NOT NULL DEFAULT 0,
|
||||
"tier" TEXT,
|
||||
"ratePct" INTEGER,
|
||||
"streakBonusPct" INTEGER NOT NULL DEFAULT 0,
|
||||
"suggestedAmount" INTEGER,
|
||||
"amount" INTEGER NOT NULL,
|
||||
"remaining" INTEGER NOT NULL,
|
||||
"expiredAmount" INTEGER NOT NULL DEFAULT 0,
|
||||
"status" "PointsStatus" NOT NULL,
|
||||
"serviceDate" TIMESTAMP(3) NOT NULL,
|
||||
"availableAt" TIMESTAMP(3) NOT NULL,
|
||||
"expiresAt" TIMESTAMP(3),
|
||||
"reason" TEXT,
|
||||
"commentForClient" TEXT,
|
||||
"createdById" TEXT,
|
||||
"channel" "PointsChannel" NOT NULL,
|
||||
"idempotencyKey" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "PointsAccrual_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "PointsRedemption" (
|
||||
"id" TEXT NOT NULL,
|
||||
"clientId" TEXT NOT NULL,
|
||||
"orderId" TEXT,
|
||||
"orderRef" TEXT,
|
||||
"orderAmount" INTEGER,
|
||||
"amount" INTEGER NOT NULL,
|
||||
"status" "RedemptionStatus" NOT NULL,
|
||||
"channel" "PointsChannel" NOT NULL,
|
||||
"note" TEXT,
|
||||
"requestedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"expiresAt" TIMESTAMP(3),
|
||||
"confirmedById" TEXT,
|
||||
"confirmedAt" TIMESTAMP(3),
|
||||
"reason" TEXT,
|
||||
"idempotencyKey" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "PointsRedemption_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "PointsRedemptionItem" (
|
||||
"id" TEXT NOT NULL,
|
||||
"redemptionId" TEXT NOT NULL,
|
||||
"accrualId" TEXT NOT NULL,
|
||||
"amount" INTEGER NOT NULL,
|
||||
|
||||
CONSTRAINT "PointsRedemptionItem_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "PointsReversal" (
|
||||
"id" TEXT NOT NULL,
|
||||
"targetType" TEXT NOT NULL,
|
||||
"targetId" TEXT NOT NULL,
|
||||
"clientId" TEXT NOT NULL,
|
||||
"amount" INTEGER NOT NULL,
|
||||
"debt" INTEGER NOT NULL DEFAULT 0,
|
||||
"createdById" TEXT,
|
||||
"channel" "PointsChannel" NOT NULL,
|
||||
"reason" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "PointsReversal_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "PointsSuggestion" (
|
||||
"id" TEXT NOT NULL,
|
||||
"clientId" TEXT NOT NULL,
|
||||
"mechanic" TEXT NOT NULL,
|
||||
"dedupeKey" TEXT NOT NULL,
|
||||
"payload" JSONB NOT NULL,
|
||||
"suggestedAmount" INTEGER NOT NULL,
|
||||
"status" "SuggestionStatus" NOT NULL DEFAULT 'OPEN',
|
||||
"resolvedById" TEXT,
|
||||
"resolvedAt" TIMESTAMP(3),
|
||||
"reason" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "PointsSuggestion_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "PointsCategory_code_key" ON "PointsCategory"("code");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "PointsBonusType_code_key" ON "PointsBonusType"("code");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "PointsAccrual_idempotencyKey_key" ON "PointsAccrual"("idempotencyKey");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "PointsAccrual_clientId_status_idx" ON "PointsAccrual"("clientId", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "PointsAccrual_status_availableAt_idx" ON "PointsAccrual"("status", "availableAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "PointsAccrual_orderId_idx" ON "PointsAccrual"("orderId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "PointsAccrual_createdAt_idx" ON "PointsAccrual"("createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "PointsRedemption_idempotencyKey_key" ON "PointsRedemption"("idempotencyKey");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "PointsRedemption_clientId_status_idx" ON "PointsRedemption"("clientId", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "PointsRedemption_status_requestedAt_idx" ON "PointsRedemption"("status", "requestedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "PointsRedemptionItem_accrualId_idx" ON "PointsRedemptionItem"("accrualId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "PointsReversal_targetType_targetId_idx" ON "PointsReversal"("targetType", "targetId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "PointsReversal_clientId_idx" ON "PointsReversal"("clientId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "PointsReversal_createdAt_idx" ON "PointsReversal"("createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "PointsSuggestion_dedupeKey_key" ON "PointsSuggestion"("dedupeKey");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "PointsSuggestion_status_createdAt_idx" ON "PointsSuggestion"("status", "createdAt");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Service" ADD CONSTRAINT "Service_pointsCategoryId_fkey" FOREIGN KEY ("pointsCategoryId") REFERENCES "PointsCategory"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "PointsAccrual" ADD CONSTRAINT "PointsAccrual_clientId_fkey" FOREIGN KEY ("clientId") REFERENCES "Client"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "PointsAccrual" ADD CONSTRAINT "PointsAccrual_categoryId_fkey" FOREIGN KEY ("categoryId") REFERENCES "PointsCategory"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "PointsAccrual" ADD CONSTRAINT "PointsAccrual_bonusTypeId_fkey" FOREIGN KEY ("bonusTypeId") REFERENCES "PointsBonusType"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "PointsAccrual" ADD CONSTRAINT "PointsAccrual_orderId_fkey" FOREIGN KEY ("orderId") REFERENCES "Order"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "PointsRedemption" ADD CONSTRAINT "PointsRedemption_clientId_fkey" FOREIGN KEY ("clientId") REFERENCES "Client"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "PointsRedemption" ADD CONSTRAINT "PointsRedemption_orderId_fkey" FOREIGN KEY ("orderId") REFERENCES "Order"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "PointsRedemptionItem" ADD CONSTRAINT "PointsRedemptionItem_redemptionId_fkey" FOREIGN KEY ("redemptionId") REFERENCES "PointsRedemption"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "PointsRedemptionItem" ADD CONSTRAINT "PointsRedemptionItem_accrualId_fkey" FOREIGN KEY ("accrualId") REFERENCES "PointsAccrual"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "PointsSuggestion" ADD CONSTRAINT "PointsSuggestion_clientId_fkey" FOREIGN KEY ("clientId") REFERENCES "Client"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
|
||||
-- номер заказа уникален среди неотменённых начислений; автоначисление — один раз на заказ
|
||||
CREATE UNIQUE INDEX "PointsAccrual_orderRef_live_key" ON "PointsAccrual"("orderRef") WHERE "orderRef" IS NOT NULL AND "status" <> 'REVERSED';
|
||||
CREATE UNIQUE INDEX "PointsAccrual_orderId_live_key" ON "PointsAccrual"("orderId") WHERE "orderId" IS NOT NULL AND "status" <> 'REVERSED';
|
||||
|
||||
-- категории кэшбека (ставки по ТЗ; Elite = Barev+ +2)
|
||||
INSERT INTO "PointsCategory" ("id", "code", "name", "rateBarev", "ratePlus", "rateElite", "sortOrder") VALUES
|
||||
('pc_cleaning', 'cleaning', '{"ru":"Клининг","en":"Cleaning","zh":"保洁","hy":"Մաքրում","es":"Limpieza"}', 5, 8, 10, 1),
|
||||
('pc_documents', 'documents', '{"ru":"Документы","en":"Documents","zh":"证件","hy":"Փաստաթղթեր","es":"Documentos"}', 5, 10, 12, 2),
|
||||
('pc_learning', 'learning', '{"ru":"Обучение и карьера","en":"Learning and career","zh":"学习与职业","hy":"Ուսում և կարիերա","es":"Formación y carrera"}', 3, 4, 6, 3),
|
||||
('pc_repair', 'repair', '{"ru":"Ремонт","en":"Repairs","zh":"维修","hy":"Վերանորոգում","es":"Reparaciones"}', 2, 4, 6, 4),
|
||||
('pc_transfer', 'transfer', '{"ru":"Трансфер","en":"Transfer","zh":"接送","hy":"Տրանսֆեր","es":"Traslado"}', 2, 4, 6, 5);
|
||||
|
||||
UPDATE "Service" SET "pointsCategoryId" = 'pc_cleaning' WHERE "code" = 'cleaning';
|
||||
UPDATE "Service" SET "pointsCategoryId" = 'pc_repair' WHERE "code" = 'repair';
|
||||
UPDATE "Service" SET "pointsCategoryId" = 'pc_transfer' WHERE "code" = 'transfer';
|
||||
UPDATE "Service" s SET "pointsCategoryId" = 'pc_documents' FROM "Category" c WHERE c."id" = s."categoryId" AND c."code" = 'DOCS';
|
||||
UPDATE "Service" s SET "pointsCategoryId" = 'pc_learning' FROM "Category" c WHERE c."id" = s."categoryId" AND c."code" = 'LEARNING';
|
||||
|
||||
-- типы бонусов
|
||||
INSERT INTO "PointsBonusType" ("id", "code", "name", "defaultAmount", "ttlDays", "sortOrder") VALUES
|
||||
('pb_housewarming', 'housewarming', '{"ru":"Новоселье","en":"Housewarming","zh":"乔迁之喜","hy":"Բնակարանամուտ","es":"Mudanza"}', 5000, 60, 1),
|
||||
('pb_route', 'first_month_route', '{"ru":"Маршрут первого месяца","en":"First-month route","zh":"首月路线","hy":"Առաջին ամսվա երթուղի","es":"Ruta del primer mes"}', 3000, NULL, 2),
|
||||
('pb_ref_inviter', 'referral_inviter', '{"ru":"Пригласил друга","en":"Invited a friend","zh":"邀请好友","hy":"Հրավիրել է ընկերոջ","es":"Invitó a un amigo"}', 3000, NULL, 3),
|
||||
('pb_ref_invitee', 'referral_invitee', '{"ru":"По приглашению друга","en":"Invited by a friend","zh":"好友邀请","hy":"Ընկերոջ հրավերով","es":"Invitado por un amigo"}', 3000, NULL, 4),
|
||||
('pb_photo', 'photo_review', '{"ru":"Отзыв с фото","en":"Review with a photo","zh":"带图评价","hy":"Կարծիք լուսանկարով","es":"Reseña con foto"}', 500, NULL, 5),
|
||||
('pb_lease', 'lease_renewal', '{"ru":"Продление аренды","en":"Lease renewal","zh":"续租","hy":"Վարձակալության երկարաձգում","es":"Renovación del alquiler"}', 2000, 60, 6),
|
||||
('pb_complaint', 'complaint', '{"ru":"Компенсация","en":"Compensation","zh":"补偿","hy":"Փոխհատուցում","es":"Compensación"}', 1000, NULL, 7),
|
||||
('pb_promo', 'promo', '{"ru":"Промо","en":"Promo","zh":"促销","hy":"Պրոմո","es":"Promoción"}', 1000, 30, 8);
|
||||
Reference in new issue
Block a user