Backoffice stage 5: products, broadcasts, activity log, settings
- Products: services with full setup — content (name, description, extras names in 5 languages via text overrides), price tiers and extras, booking window, late-cancel fee, on/off, checklist; category discounts by membership level; membership plan prices; promo codes; relocation steps and documents. - Text overrides: TextOverride table on top of the i18n files; API, bots and the worker reload them every minute, mini apps fetch public.texts at start. - Promo codes applied to orders (admin new-order form and client API): not stacked with membership discount — the larger wins; once per client; validity, limit and categories. - Broadcasts to the client bot by any client filter, per-language texts with Russian fallback, test to yourself, ~25 msg/s, per-recipient status, resume after worker restart, history with progress and stop. - Activity log (who/when/what, filters, details) and Settings page with all owner settings grouped, plus payment methods. - Tests for promo codes and text overrides. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
ac786cc5cc
commit
0edc6432b7
34 files changed
+2704
-26
No files matched your search
@@ -0,0 +1,60 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "BroadcastStatus" AS ENUM ('SENDING', 'DONE', 'CANCELLED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "BroadcastRecipientStatus" AS ENUM ('PENDING', 'SENT', 'BLOCKED', 'FAILED');
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "PromoCode" ADD COLUMN "categories" "CategoryCode"[] DEFAULT ARRAY[]::"CategoryCode"[],
|
||||
ADD COLUMN "note" TEXT;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "TextOverride" (
|
||||
"key" TEXT NOT NULL,
|
||||
"locale" "Locale" NOT NULL,
|
||||
"value" TEXT NOT NULL,
|
||||
"updatedById" TEXT,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "TextOverride_pkey" PRIMARY KEY ("key","locale")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Broadcast" (
|
||||
"id" TEXT NOT NULL,
|
||||
"texts" JSONB NOT NULL,
|
||||
"appButton" BOOLEAN NOT NULL DEFAULT true,
|
||||
"filters" JSONB NOT NULL,
|
||||
"status" "BroadcastStatus" NOT NULL DEFAULT 'SENDING',
|
||||
"total" INTEGER NOT NULL DEFAULT 0,
|
||||
"sent" INTEGER NOT NULL DEFAULT 0,
|
||||
"blocked" INTEGER NOT NULL DEFAULT 0,
|
||||
"failed" INTEGER NOT NULL DEFAULT 0,
|
||||
"createdById" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"finishedAt" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "Broadcast_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "BroadcastRecipient" (
|
||||
"id" TEXT NOT NULL,
|
||||
"broadcastId" TEXT NOT NULL,
|
||||
"clientId" TEXT NOT NULL,
|
||||
"status" "BroadcastRecipientStatus" NOT NULL DEFAULT 'PENDING',
|
||||
"error" TEXT,
|
||||
"sentAt" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "BroadcastRecipient_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "BroadcastRecipient_broadcastId_status_idx" ON "BroadcastRecipient"("broadcastId", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "BroadcastRecipient_broadcastId_clientId_key" ON "BroadcastRecipient"("broadcastId", "clientId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "BroadcastRecipient" ADD CONSTRAINT "BroadcastRecipient_broadcastId_fkey" FOREIGN KEY ("broadcastId") REFERENCES "Broadcast"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
Reference in new issue
Block a user