feat(settings): store Khanegi keys in settings tables instead of tenant JSON
Template defaults seed from deploy_settings_const; new tenants copy them, import decides per key, and /get_settings reads the per-tenant rows. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
-- Drop legacy JSON snapshot on tenants
|
||||
ALTER TABLE "tenants" DROP COLUMN IF EXISTS "setting";
|
||||
|
||||
-- Template defaults (copied onto new tenants)
|
||||
CREATE TABLE "setting_templates" (
|
||||
"id" TEXT NOT NULL,
|
||||
"key" VARCHAR(50) NOT NULL,
|
||||
"title_fa" VARCHAR(255),
|
||||
"can_edit" SMALLINT DEFAULT 0,
|
||||
"value" TEXT,
|
||||
"description" TEXT,
|
||||
"type" VARCHAR(50),
|
||||
"type_data" VARCHAR(255),
|
||||
"is_exist" BOOLEAN NOT NULL DEFAULT true,
|
||||
"is_active" SMALLINT DEFAULT 1,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
"deleted_at" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "setting_templates_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX "setting_templates_key_key" ON "setting_templates"("key");
|
||||
|
||||
-- Per-tenant settings (cascade on tenant delete)
|
||||
CREATE TABLE "settings" (
|
||||
"id" TEXT NOT NULL,
|
||||
"tenant_id" TEXT NOT NULL,
|
||||
"key" VARCHAR(50) NOT NULL,
|
||||
"title_fa" VARCHAR(255),
|
||||
"can_edit" SMALLINT DEFAULT 0,
|
||||
"value" TEXT,
|
||||
"description" TEXT,
|
||||
"type" VARCHAR(50),
|
||||
"type_data" VARCHAR(255),
|
||||
"is_exist" BOOLEAN NOT NULL DEFAULT true,
|
||||
"is_active" SMALLINT DEFAULT 1,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
"deleted_at" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "settings_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX "settings_tenant_id_key_key" ON "settings"("tenant_id", "key");
|
||||
CREATE INDEX "settings_key_idx" ON "settings"("key");
|
||||
CREATE INDEX "settings_tenant_id_idx" ON "settings"("tenant_id");
|
||||
|
||||
ALTER TABLE "settings" ADD CONSTRAINT "settings_tenant_id_fkey"
|
||||
FOREIGN KEY ("tenant_id") REFERENCES "tenants"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
+46
-2
@@ -69,8 +69,6 @@ model Tenant {
|
||||
/// Legacy cache from older sync attempts — SuperAdmin SMS account is now source of truth
|
||||
smsSettingsCache Json? @map("sms_settings_cache")
|
||||
smsSyncedAt DateTime? @map("sms_synced_at")
|
||||
/// Khanegi deploy settings snapshot (can_edit=0) imported via admin login + get_settings.
|
||||
setting Json?
|
||||
/// Full Khanegi UI JSON (theme, navigation, pages). Hamkar: unused for now.
|
||||
appUiConfig Json? @map("app_ui_config")
|
||||
/// Khanegi only: which appearance editor / get_user payload shape to use.
|
||||
@@ -90,12 +88,58 @@ model Tenant {
|
||||
serverAccounts ServerAccount[]
|
||||
pluginSubscriptions PluginSubscription[]
|
||||
supportSubscriptions SupportSubscription[]
|
||||
settings Setting[]
|
||||
|
||||
@@index([product])
|
||||
@@index([isActive])
|
||||
@@map("tenants")
|
||||
}
|
||||
|
||||
/// قالب پیشفرض تنظیمات (از deploy_settings_const). نسخهٔ جدید از اینجا کپی میشود.
|
||||
model SettingTemplate {
|
||||
id String @id @default(cuid())
|
||||
key String @unique @db.VarChar(50)
|
||||
titleFa String? @map("title_fa") @db.VarChar(255)
|
||||
canEdit Int? @default(0) @map("can_edit") @db.SmallInt
|
||||
value String? @db.Text
|
||||
description String? @db.Text
|
||||
type String? @db.VarChar(50)
|
||||
/// ستون همکار — برای سازگاری آینده
|
||||
typeData String? @map("type_data") @db.VarChar(255)
|
||||
isExist Boolean @default(true) @map("is_exist")
|
||||
isActive Int? @default(1) @map("is_active") @db.SmallInt
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
deletedAt DateTime? @map("deleted_at")
|
||||
|
||||
@@map("setting_templates")
|
||||
}
|
||||
|
||||
/// تنظیمات هر نسخه — مثل جدول settings خانگی + tenant_id
|
||||
model Setting {
|
||||
id String @id @default(cuid())
|
||||
tenantId String @map("tenant_id")
|
||||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||||
key String @db.VarChar(50)
|
||||
titleFa String? @map("title_fa") @db.VarChar(255)
|
||||
canEdit Int? @default(0) @map("can_edit") @db.SmallInt
|
||||
value String? @db.Text
|
||||
description String? @db.Text
|
||||
type String? @db.VarChar(50)
|
||||
/// ستون همکار — برای سازگاری آینده
|
||||
typeData String? @map("type_data") @db.VarChar(255)
|
||||
isExist Boolean @default(true) @map("is_exist")
|
||||
isActive Int? @default(1) @map("is_active") @db.SmallInt
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
deletedAt DateTime? @map("deleted_at")
|
||||
|
||||
@@unique([tenantId, key])
|
||||
@@index([key])
|
||||
@@index([tenantId])
|
||||
@@map("settings")
|
||||
}
|
||||
|
||||
/// SuperAdmin-owned SMS wallet + gateway config per sold version.
|
||||
/// Does NOT replace Hamkar/Khanegi internal SMS panels yet.
|
||||
model SmsAccount {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user