From 71f1fa1092bbf56a2d3795ac966ac81ed7237f72 Mon Sep 17 00:00:00 2001 From: adonis Date: Tue, 18 Aug 2026 18:52:31 +0330 Subject: [PATCH] feat(settings): import can_edit=0 values from khanegi settings table Co-authored-by: Cursor --- .../program-settings.service.ts | 36 +++++++++---------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/src/program-settings/program-settings.service.ts b/src/program-settings/program-settings.service.ts index 4ea4070..0635042 100644 --- a/src/program-settings/program-settings.service.ts +++ b/src/program-settings/program-settings.service.ts @@ -212,13 +212,15 @@ export class ProgramSettingsService implements OnModuleInit { }> = []; for (const [key, row] of remoteByKey) { - if (!this.isNewKhanegiCatalogKey(key, catalogKeys)) continue; const localRow = localByKey.get(key); + const khanegiValue = String(row.value ?? ''); + const superadminValue = localRow ? String(localRow.value ?? '') : null; + if (localRow && khanegiValue === superadminValue) continue; decisionsNeeded.push({ key, title_fa: String(row.title_fa || localRow?.title_fa || key), - khanegi_value: String(row.value ?? ''), - superadmin_value: localRow ? String(localRow.value ?? '') : null, + khanegi_value: khanegiValue, + superadmin_value: superadminValue, status: localRow ? 'both' : 'new_in_khanegi', }); } @@ -230,9 +232,9 @@ export class ProgramSettingsService implements OnModuleInit { apiBase, decisionsNeeded, onlySuperAdminKeys: onlySuperAdmin, - skippedCatalogCount: [...remoteByKey.keys()].filter((key) => catalogKeys.has(key)).length, + importableCount: remoteByKey.size, note: - 'فقط کلیدهایی که در قالب سوپرادمین نیستند. کلیدهای deploy_settings_const از قبل در قالب‌اند و از خانگی بازنویسی نمی‌شوند. کلیدهای فقط-سوپرادمین روی این پروژه با پیش‌فرض قالب تکمیل می‌شوند.', + 'مقدار کلیدهای can_edit=0 خانگی روی همین پروژه نوشته می‌شود. اگر تصمیم نفرستی، پیش‌فرض «فقط این پروژه» است.', }; } @@ -251,12 +253,10 @@ export class ProgramSettingsService implements OnModuleInit { const { apiBase, token } = await this.loginKhanegiAdmin(tenant, mobileNorm, password); await this.ensureTemplatesSeeded(); const remote = await this.fetchSystemSettings(apiBase, token); - const catalogKeys = await this.catalogKeySet(); const remoteByKey = new Map( remote .map((row) => this.normalizeIncoming(row)) .filter((row) => row.key && !isRuntimeProgramSettingKey(row.key)) - .filter((row) => this.isNewKhanegiCatalogKey(row.key, catalogKeys)) .map((row) => [row.key, row]), ); @@ -283,7 +283,7 @@ export class ProgramSettingsService implements OnModuleInit { await this.ensureTemplateDefaultsForTenant(tx, tenantId); for (const [key, row] of remoteByKey) { - const scope = decisionMap.get(key) ?? 'none'; + const scope = decisionMap.get(key) ?? 'this'; if (scope === 'none') continue; const targetIds = scope === 'all' ? khanegiTenantIds : [tenantId]; @@ -525,13 +525,6 @@ export class ProgramSettingsService implements OnModuleInit { return keys; } - private isNewKhanegiCatalogKey(key: string, catalogKeys: Set) { - if (!key || catalogKeys.has(key)) return false; - if (isRuntimeProgramSettingKey(key)) return false; - if (isSecretOrServerOnlySettingKey(key)) return false; - return true; - } - private async seedEmptyKhanegiTenants() { const tenants = await this.prisma.tenant.findMany({ where: { product: ProductType.khanegi }, @@ -804,11 +797,10 @@ export class ProgramSettingsService implements OnModuleInit { private async fetchSystemSettings(apiBase: string, token: string) { const headers = { Authorization: `Bearer ${token}` }; - const url = this.joinUrl(apiBase, '/admin/get_settings'); + const url = this.joinUrl(apiBase, '/admin/settings/table'); try { const { data } = await axios.get(url, { headers, - params: { system_only: 1 }, timeout: 25000, }); const items = this.asSettingsArray(data) @@ -819,19 +811,23 @@ export class ProgramSettingsService implements OnModuleInit { const status = axios.isAxiosError(error) ? error.response?.status : undefined; if (status === 401 || status === 403) { throw new BadRequestException( - this.axiosMessage(error, 'توکن ادمین خانگی برای get_settings رد شد'), + this.axiosMessage(error, 'توکن ادمین خانگی برای settings/table رد شد'), ); } } try { - const { data } = await axios.get(url, { headers, timeout: 25000 }); + const { data } = await axios.get(this.joinUrl(apiBase, '/admin/get_settings'), { + headers, + params: { system_only: 1, skip_overlay: 1 }, + timeout: 25000, + }); return this.asSettingsArray(data) .filter((row) => this.isSystemSetting(row)) .filter((row) => !isRuntimeProgramSettingKey(String(row.key || ''))); } catch (error) { throw new BadGatewayException( - this.axiosMessage(error, 'خواندن get_settings از اپ خانگی ناموفق بود'), + this.axiosMessage(error, 'خواندن جدول settings از اپ خانگی ناموفق بود'), ); } }