@@ -252,7 +252,7 @@ ${systemRows.map((r) => ` ${JSON.stringify(r.key)},`).join('\n')}
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* کلیدهایی که سوپرادمین مالکشان نیست (مالک: دیتابیس هر نصب).
|
* کلیدهایی که سوپرادمین مالکشان نیست (مالک: دیتابیس هر نصب).
|
||||||
* در هر بوت با purgeEditableFromSuperAdmin از قالب و ردیف همهٔ پروژهها حذف میشوند.
|
* در هر بوت از قالب حذف میشوند؛ از ردیف هر پروژه فقط با دکمهٔ صفحهٔ تنظیمات همان پروژه.
|
||||||
*/
|
*/
|
||||||
export const DEPLOY_SETTING_EDITABLE_KEYS = new Set<string>([
|
export const DEPLOY_SETTING_EDITABLE_KEYS = new Set<string>([
|
||||||
${editableRows.map((r) => ` ${JSON.stringify(r.key)},`).join('\n')}
|
${editableRows.map((r) => ` ${JSON.stringify(r.key)},`).join('\n')}
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ export const DEPLOY_SETTING_CATALOG_KEYS = new Set<string>([
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* کلیدهایی که سوپرادمین مالکشان نیست (مالک: دیتابیس هر نصب).
|
* کلیدهایی که سوپرادمین مالکشان نیست (مالک: دیتابیس هر نصب).
|
||||||
* در هر بوت با purgeEditableFromSuperAdmin از قالب و ردیف همهٔ پروژهها حذف میشوند.
|
* در هر بوت از قالب حذف میشوند؛ از ردیف هر پروژه فقط با دکمهٔ
|
||||||
|
* «حذف تنظیمات غیر دسترسی» در صفحهٔ تنظیمات همان پروژه.
|
||||||
*/
|
*/
|
||||||
export const DEPLOY_SETTING_EDITABLE_KEYS = new Set<string>([
|
export const DEPLOY_SETTING_EDITABLE_KEYS = new Set<string>([
|
||||||
"about_software",
|
"about_software",
|
||||||
|
|||||||
@@ -46,4 +46,14 @@ export class ProgramSettingsController {
|
|||||||
user.id,
|
user.id,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* بعد از restore لوکال: فقط کلیدهای «دسترسی مشتری به قابلیتها» روی این پروژه
|
||||||
|
* در سوپرادمین میمانند؛ بقیه از جدول settings همین tenant حذف میشوند.
|
||||||
|
*/
|
||||||
|
@Post('purge-non-owned')
|
||||||
|
@RequirePermissions('khanegi:write')
|
||||||
|
purgeNonOwned(@Param('tenantId') tenantId: string, @CurrentUser() user: { id: string }) {
|
||||||
|
return this.programSettings.purgeNonOwnedFromTenant(tenantId, user.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,11 +70,10 @@ export class ProgramSettingsService implements OnModuleInit {
|
|||||||
if (result.seeded) {
|
if (result.seeded) {
|
||||||
this.logger.log(`setting_templates seeded (${result.count} keys)`);
|
this.logger.log(`setting_templates seeded (${result.count} keys)`);
|
||||||
}
|
}
|
||||||
const purged = await this.purgeEditableFromSuperAdmin();
|
// فقط قالب: حذف ردیف پروژهها دونه به دونه با دکمهٔ صفحهٔ تنظیمات همان پروژه
|
||||||
if (purged.templates || purged.settings) {
|
const purged = await this.purgeNonOwnedTemplates();
|
||||||
this.logger.log(
|
if (purged.templates) {
|
||||||
`purged can_edit=1 from superadmin (templates=${purged.templates}, settings=${purged.settings})`,
|
this.logger.log(`purged non-owned keys from setting_templates (templates=${purged.templates})`);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
await this.seedEmptyKhanegiTenants();
|
await this.seedEmptyKhanegiTenants();
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
@@ -599,25 +598,79 @@ export class ProgramSettingsService implements OnModuleInit {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** حذف can_edit=1 از قالب و همهٔ پروژههای خانگی در DB سوپرادمین */
|
/**
|
||||||
async purgeEditableFromSuperAdmin() {
|
* قالب سوپرادمین فقط کلیدهای مالکیت سوپرادمین (دسترسی مشتری) میماند.
|
||||||
const keys = [...DEPLOY_SETTING_EDITABLE_KEYS];
|
* ردیف پروژهها را پاک نمیکند — آن کار با purgeNonOwnedFromTenant است.
|
||||||
if (!keys.length) return { templates: 0, settings: 0 };
|
*/
|
||||||
|
async purgeNonOwnedTemplates() {
|
||||||
|
const keep = [...DEPLOY_SETTING_CATALOG_KEYS];
|
||||||
|
if (!keep.length) return { templates: 0 };
|
||||||
|
|
||||||
const result = await this.prisma.$transaction(async (tx: any) => {
|
const templates = await this.prisma.settingTemplate.deleteMany({
|
||||||
const templates = await tx.settingTemplate.deleteMany({
|
where: { NOT: { key: { in: keep } } },
|
||||||
where: { key: { in: keys } },
|
|
||||||
});
|
|
||||||
const settings = await tx.setting.deleteMany({
|
|
||||||
where: { key: { in: keys } },
|
|
||||||
});
|
|
||||||
return { templates: templates.count, settings: settings.count };
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result.templates || result.settings) {
|
if (templates.count) {
|
||||||
this.replicaWatch.kick();
|
this.replicaWatch.kick();
|
||||||
}
|
}
|
||||||
return result;
|
return { templates: templates.count };
|
||||||
|
}
|
||||||
|
|
||||||
|
/** سازگاری با اندپوینت قدیمی seed/purge-editable — فقط قالب */
|
||||||
|
async purgeEditableFromSuperAdmin() {
|
||||||
|
const templates = await this.purgeNonOwnedTemplates();
|
||||||
|
return { templates: templates.templates, settings: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* بعد از restore لوکال روی همان نصب: همهٔ تنظیمات این پروژه در DB سوپرادمین
|
||||||
|
* که خارج از «دسترسی مشتری به قابلیتها»اند حذف میشوند.
|
||||||
|
*/
|
||||||
|
async purgeNonOwnedFromTenant(tenantId: string, userId?: string) {
|
||||||
|
const tenant = await this.requireKhanegiTenant(tenantId);
|
||||||
|
const keep = [...DEPLOY_SETTING_CATALOG_KEYS];
|
||||||
|
|
||||||
|
const before = await this.prisma.setting.findMany({
|
||||||
|
where: {
|
||||||
|
tenantId,
|
||||||
|
NOT: { key: { in: keep } },
|
||||||
|
},
|
||||||
|
select: { key: true },
|
||||||
|
});
|
||||||
|
const removedKeys = before.map((row: { key: string }) => row.key).sort();
|
||||||
|
|
||||||
|
const deleted = await this.prisma.setting.deleteMany({
|
||||||
|
where: {
|
||||||
|
tenantId,
|
||||||
|
NOT: { key: { in: keep } },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.audit.log({
|
||||||
|
action: 'tenant.program_settings.purge_non_owned',
|
||||||
|
entityType: 'tenant_program_settings',
|
||||||
|
entityId: tenantId,
|
||||||
|
tenantId,
|
||||||
|
userId,
|
||||||
|
after: {
|
||||||
|
removed: deleted.count,
|
||||||
|
keys: removedKeys,
|
||||||
|
kept: keep,
|
||||||
|
} as Prisma.InputJsonValue,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (deleted.count) {
|
||||||
|
this.replicaWatch.kick();
|
||||||
|
}
|
||||||
|
|
||||||
|
const items = await this.listTenantRows(tenantId);
|
||||||
|
return {
|
||||||
|
tenant: this.tenantMeta(tenant),
|
||||||
|
removed: deleted.count,
|
||||||
|
removedKeys,
|
||||||
|
items,
|
||||||
|
count: items.length,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private deployCatalogCanEditMap() {
|
private deployCatalogCanEditMap() {
|
||||||
|
|||||||
Reference in New Issue
Block a user