From e025496595c3769b9e9afddf1a2c38341ce40871 Mon Sep 17 00:00:00 2001 From: Mahdi Date: Sun, 9 Aug 2026 17:42:50 +0330 Subject: [PATCH] feat: bump appVersion when branding changes to invalidate get_user cache Appearance/avatar/name/uiVariant updates auto-increment Tenant.appVersion so clients refetch get_user only after get_version changes. Co-authored-by: Cursor --- src/tenants/tenants.service.ts | 35 ++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/tenants/tenants.service.ts b/src/tenants/tenants.service.ts index 475ad5d..253434f 100644 --- a/src/tenants/tenants.service.ts +++ b/src/tenants/tenants.service.ts @@ -118,6 +118,24 @@ export class TenantsService { throw new NotFoundException('نسخه یافت نشد'); } + const brandingChanged = + (dto.avatarUrl !== undefined && dto.avatarUrl !== before.avatarUrl) || + (dto.primaryColor !== undefined && dto.primaryColor !== before.primaryColor) || + (dto.secondaryColor !== undefined && + dto.secondaryColor !== before.secondaryColor) || + (dto.backgroundColor !== undefined && + dto.backgroundColor !== before.backgroundColor) || + dto.appUiConfig !== undefined || + (dto.uiVariant !== undefined && dto.uiVariant !== before.uiVariant) || + (dto.nameFa !== undefined && dto.nameFa !== before.nameFa) || + (dto.nameEn !== undefined && dto.nameEn !== before.nameEn); + + const explicitVersion = + dto.appVersion !== undefined ? dto.appVersion.trim() || '1' : undefined; + const nextAppVersion = + explicitVersion ?? + (brandingChanged ? this.bumpAppVersion(before.appVersion) : undefined); + try { const tenant = await this.prisma.tenant.update({ where: { id }, @@ -150,8 +168,8 @@ export class TenantsService { appUiConfig: dto.appUiConfig as Prisma.InputJsonValue, }), ...(dto.uiVariant !== undefined && { uiVariant: dto.uiVariant }), - ...(dto.appVersion !== undefined && { - appVersion: dto.appVersion.trim() || '1', + ...(nextAppVersion !== undefined && { + appVersion: nextAppVersion, }), ...(dto.isActive !== undefined && { isActive: dto.isActive }), ...(dto.notes !== undefined && { notes: dto.notes }), @@ -231,6 +249,19 @@ export class TenantsService { .replace(/\/$/, ''); } + /** با تغییر برندینگ، get_user کش فرانت با get_version باطل شود */ + private bumpAppVersion(current?: string | null): string { + const v = String(current || '1').trim() || '1'; + if (/^\d+$/.test(v)) { + return String(Number(v) + 1); + } + const semver = v.match(/^(\d+)\.(\d+)\.(\d+)$/); + if (semver) { + return `${semver[1]}.${semver[2]}.${Number(semver[3]) + 1}`; + } + return `${Date.now()}`; + } + private handleUnique(error: unknown) { if ( error instanceof Prisma.PrismaClientKnownRequestError &&