export type SettingSubsectionDef = { id: string title: string match: (key: string) => boolean } export type SettingGroupDef = { id: string title: string icon: string match: (key: string) => boolean subsections?: SettingSubsectionDef[] } /** گروه‌های تنظیمات دیپلوی خانگی (can_edit=0) — هم‌تراز پنل ادمین. * کلید جدید برای همهٔ نسخه‌ها: اول `controlpanel_server/.../program-setting-catalog.ts` * بعد این‌جا گروه را مشخص کن تا در «متفرقه» نماند. */ export const KHANEGI_SYSTEM_SETTING_GROUPS: SettingGroupDef[] = [ { id: 'customer_features', title: 'دسترسی مشتری به قابلیت‌ها', icon: 'TeamOutlined', match: (k) => /^(enable_automation|enable_conditional_order|enable_product_funds|enable_remittance|has_page_price_trigger|has_page_notification|has_page_gift_card|enable_customer_level_profit|banner_enabled|jibit_enabled|customer_direct_sms|has_page_earn_money|group_sms|customer_special_pricing|enable_gold_credit|tracking_systems_enabled|permision__enabled|show_to_users_chat|has_landing|has_charts)$/.test( k, ), }, { id: 'support_chat', title: 'چت پشتیبانی', icon: 'MessageOutlined', match: (k) => /^(chat_api|chat_api_key|chat_upload_url|chat_download_url)$/.test(k), }, { id: 'general', title: 'عمومی و برند', icon: 'HomeOutlined', match: (k) => /^(name_fa|name_en|app_url|admin_url|apk_download_link|bace_url|server_url|logo_|title_pwa|title_fav|metal_type|main_metal|unit$|open_register|auto_active_customer|store_status|key$|is_store|sms_panel|main_wallet_products|enamad_url|enamad_logo)/.test( k, ), }, { id: 'chart', title: 'نمودار قیمت', icon: 'LineChartOutlined', match: (k) => /^chart_/.test(k), }, { id: 'pricing', title: 'منبع قیمت و تابلو', icon: 'DollarOutlined', match: (k) => /^(price_provider|zaarbox_|main_product$)/.test(k) || k.includes('charge_percentage'), }, { id: 'montzar', title: 'Montzar', icon: 'LinkOutlined', match: (k) => /^montzar_/.test(k) || k === 'display_montzar', }, { id: 'store', title: 'اتصال فروشگاه', icon: 'ShopOutlined', match: (k) => /^node_/.test(k) || k === 'montify_name' || k === 'external_order_api_enabled', }, { id: 'deposit_methods', title: 'روش‌های واریز', icon: 'CreditCardOutlined', match: (k) => k.startsWith('external_payment_') || k === 'wallet_payment_provider', subsections: [ { id: 'gateway', title: 'درگاه فروشگاه / پرداخت آنلاین', match: (k) => k.startsWith('external_payment_') || k === 'wallet_payment_provider', }, ], }, { id: 'payping', title: 'درگاه Payping', icon: 'WalletOutlined', match: (k) => k.startsWith('payping_'), }, { id: 'accounting_provider', title: 'انتخاب سیستم حسابداری', icon: 'AccountBookOutlined', match: (k) => k === 'accounting_provider', }, { id: 'accounting_zarin', title: 'حسابداری زرین', icon: 'BankOutlined', match: (k) => k.startsWith('zarin_'), }, { id: 'accounting_tahesab', title: 'حسابداری ته‌حساب', icon: 'CalculatorOutlined', match: (k) => k.startsWith('tahesab_') || k === 'send_to_tahesab', }, { id: 'accounting_pargar', title: 'حسابداری پرگار', icon: 'FileTextOutlined', match: (k) => k.startsWith('pargar_') || k === 'send_to_pargar', }, { id: 'price_channel', title: 'ارسال قیمت به کانال', icon: 'SendOutlined', match: (k) => /^price_channel_/.test(k) || /^(telegram_bot|bale_bot|rubika_bot)/.test(k) || k === 'change_mesghal', }, { id: 'infra', title: 'زیرساخت', icon: 'ClusterOutlined', match: (k) => /^(wss_enabled|sse_path|profit_gold_api_enabled)$/.test(k), }, { id: 'misc', title: 'سایر', icon: 'EllipsisOutlined', match: () => true, }, ] export function getKhanegiSystemGroupId(key: string): string { for (const group of KHANEGI_SYSTEM_SETTING_GROUPS) { if (group.id === 'misc') continue if (group.match(key)) return group.id } return 'misc' } export function getKhanegiSubsectionId(key: string, group: SettingGroupDef | undefined): string | null { if (!group?.subsections?.length) return null for (const sub of group.subsections) { if (sub.match(key)) return sub.id } return null } export function isSecretSettingKey(key: string): boolean { return /(password|secret|token|api_key|apikey|private_key|shared_secret)/i.test(key) } export function isSwitchSetting(type: string | null | undefined, value: unknown): boolean { const t = String(type || '').toLowerCase() if (t === 'switch' || t === 'boolean' || t === 'bool') return true if (typeof value === 'boolean') return true const v = String(value ?? '').trim().toLowerCase() return v === 'true' || v === 'false' } export function isSettingOn(value: unknown): boolean { if (value === true || value === 1) return true const v = String(value ?? '').trim().toLowerCase() return v === 'true' || v === '1' || v === 'on' }