|
|
|
@@ -70,11 +70,10 @@ export class ProgramSettingsService implements OnModuleInit {
|
|
|
|
|
if (result.seeded) {
|
|
|
|
|
this.logger.log(`setting_templates seeded (${result.count} keys)`);
|
|
|
|
|
}
|
|
|
|
|
const purged = await this.purgeEditableFromSuperAdmin();
|
|
|
|
|
if (purged.templates || purged.settings) {
|
|
|
|
|
this.logger.log(
|
|
|
|
|
`purged can_edit=1 from superadmin (templates=${purged.templates}, settings=${purged.settings})`,
|
|
|
|
|
);
|
|
|
|
|
// فقط قالب: حذف ردیف پروژهها دونه به دونه با دکمهٔ صفحهٔ تنظیمات همان پروژه
|
|
|
|
|
const purged = await this.purgeNonOwnedTemplates();
|
|
|
|
|
if (purged.templates) {
|
|
|
|
|
this.logger.log(`purged non-owned keys from setting_templates (templates=${purged.templates})`);
|
|
|
|
|
}
|
|
|
|
|
await this.seedEmptyKhanegiTenants();
|
|
|
|
|
} catch (error: any) {
|
|
|
|
@@ -599,25 +598,79 @@ export class ProgramSettingsService implements OnModuleInit {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** حذف can_edit=1 از قالب و همهٔ پروژههای خانگی در DB سوپرادمین */
|
|
|
|
|
async purgeEditableFromSuperAdmin() {
|
|
|
|
|
const keys = [...DEPLOY_SETTING_EDITABLE_KEYS];
|
|
|
|
|
if (!keys.length) return { templates: 0, settings: 0 };
|
|
|
|
|
/**
|
|
|
|
|
* قالب سوپرادمین فقط کلیدهای مالکیت سوپرادمین (دسترسی مشتری) میماند.
|
|
|
|
|
* ردیف پروژهها را پاک نمیکند — آن کار با purgeNonOwnedFromTenant است.
|
|
|
|
|
*/
|
|
|
|
|
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 tx.settingTemplate.deleteMany({
|
|
|
|
|
where: { key: { in: keys } },
|
|
|
|
|
});
|
|
|
|
|
const settings = await tx.setting.deleteMany({
|
|
|
|
|
where: { key: { in: keys } },
|
|
|
|
|
});
|
|
|
|
|
return { templates: templates.count, settings: settings.count };
|
|
|
|
|
const templates = await this.prisma.settingTemplate.deleteMany({
|
|
|
|
|
where: { NOT: { key: { in: keep } } },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (result.templates || result.settings) {
|
|
|
|
|
if (templates.count) {
|
|
|
|
|
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() {
|
|
|
|
|