From c687a60bb14c6efca14aae2f1f122468721d24e8 Mon Sep 17 00:00:00 2001 From: borkarsaish65 Date: Mon, 30 Mar 2026 15:23:07 +0530 Subject: [PATCH 01/14] entities and entity type fix for cache invalidation --- src/generics/cacheHelper.js | 11 +++++++++++ src/services/entity-type.js | 14 ++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/generics/cacheHelper.js b/src/generics/cacheHelper.js index 1bb287daa..66a667fb8 100644 --- a/src/generics/cacheHelper.js +++ b/src/generics/cacheHelper.js @@ -611,6 +611,17 @@ const entityTypes = { return del(cacheKey, { useInternal }) }, + /** + * Invalidate a specific entity type across ALL orgs in a tenant. + * Used when the default org updates an entity type — other orgs may have cached + * the default org's data under their own org key via fallback logic. + */ + async deleteAcrossAllOrgs(tenantCode, modelName, entityValue) { + const pattern = `tenant:${tenantCode}:org:*:entityTypes:model:${modelName}:${entityValue}` + const result = await scanAndDelete(pattern) + return result + }, + // Clear all entityTypes cache for a tenant/org (useful after cache key format changes) async clearAll(tenantCode, orgCode) { return await evictNamespace({ tenantCode, orgCode: orgCode, ns: 'entityTypes' }) diff --git a/src/services/entity-type.js b/src/services/entity-type.js index 31dd46142..75967af7c 100644 --- a/src/services/entity-type.js +++ b/src/services/entity-type.js @@ -107,9 +107,19 @@ module.exports = class EntityHelper { // Cache invalidation after successful update: just delete using original entity data try { if (originalEntity && originalEntity.model_names && originalEntity.value) { - // Delete cache entries using original entity's model_names and value + const isDefaultOrg = orgCode === process.env.DEFAULT_ORGANISATION_CODE for (const modelName of originalEntity.model_names) { - await cacheHelper.entityTypes.delete(tenantCode, orgCode, modelName, originalEntity.value) + if (isDefaultOrg) { + // Default org update: other orgs may have cached this entity type via fallback + // under their own org key — sweep all of them + await cacheHelper.entityTypes.deleteAcrossAllOrgs( + tenantCode, + modelName, + originalEntity.value + ) + } else { + await cacheHelper.entityTypes.delete(tenantCode, orgCode, modelName, originalEntity.value) + } } } } catch (cacheError) { From 9417332b3cc5b140fe4630a974427441106dee12 Mon Sep 17 00:00:00 2001 From: borkarsaish65 Date: Mon, 30 Mar 2026 16:51:09 +0530 Subject: [PATCH 02/14] changed naming convention --- src/generics/cacheHelper.js | 2 +- src/services/entity-type.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/generics/cacheHelper.js b/src/generics/cacheHelper.js index 66a667fb8..4aadfb94a 100644 --- a/src/generics/cacheHelper.js +++ b/src/generics/cacheHelper.js @@ -616,7 +616,7 @@ const entityTypes = { * Used when the default org updates an entity type — other orgs may have cached * the default org's data under their own org key via fallback logic. */ - async deleteAcrossAllOrgs(tenantCode, modelName, entityValue) { + async deleteEntityTypesAcrossAllOrgs(tenantCode, modelName, entityValue) { const pattern = `tenant:${tenantCode}:org:*:entityTypes:model:${modelName}:${entityValue}` const result = await scanAndDelete(pattern) return result diff --git a/src/services/entity-type.js b/src/services/entity-type.js index 75967af7c..0eef17f7c 100644 --- a/src/services/entity-type.js +++ b/src/services/entity-type.js @@ -112,7 +112,7 @@ module.exports = class EntityHelper { if (isDefaultOrg) { // Default org update: other orgs may have cached this entity type via fallback // under their own org key — sweep all of them - await cacheHelper.entityTypes.deleteAcrossAllOrgs( + await cacheHelper.entityTypes.deleteEntityTypesAcrossAllOrgs( tenantCode, modelName, originalEntity.value From dc88da2deaf99ce1c04306d17bcd4fdced6e8780 Mon Sep 17 00:00:00 2001 From: borkarsaish65 Date: Mon, 30 Mar 2026 17:49:33 +0530 Subject: [PATCH 03/14] addressed pr comments --- src/services/entity-type.js | 41 ++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/src/services/entity-type.js b/src/services/entity-type.js index 0eef17f7c..5be65f1b3 100644 --- a/src/services/entity-type.js +++ b/src/services/entity-type.js @@ -316,17 +316,26 @@ module.exports = class EntityHelper { } // THIRD: Remove individual entity type from cache + const isDefaultOrg = organizationCode === process.env.DEFAULT_ORGANISATION_CODE try { // For each model this entity belonged to if (entityToDelete.model_names && Array.isArray(entityToDelete.model_names)) { for (const modelName of entityToDelete.model_names) { // Remove the specific entity type cache - await cacheHelper.entityTypes.delete( - tenantCode, - organizationCode, - modelName, - entityToDelete.value - ) + if (isDefaultOrg) { + await cacheHelper.entityTypes.deleteEntityTypesAcrossAllOrgs( + tenantCode, + modelName, + entityToDelete.value + ) + } else { + await cacheHelper.entityTypes.delete( + tenantCode, + organizationCode, + modelName, + entityToDelete.value + ) + } } } } catch (cacheError) { @@ -336,12 +345,20 @@ module.exports = class EntityHelper { if (entityToDelete.model_names && Array.isArray(entityToDelete.model_names)) { for (const modelName of entityToDelete.model_names) { try { - await cacheHelper.entityTypes.delete( - tenantCode, - organizationCode, - modelName, - entityToDelete.value - ) + if (isDefaultOrg) { + await cacheHelper.entityTypes.deleteEntityTypesAcrossAllOrgs( + tenantCode, + modelName, + entityToDelete.value + ) + } else { + await cacheHelper.entityTypes.delete( + tenantCode, + organizationCode, + modelName, + entityToDelete.value + ) + } } catch (retryError) { // Failed to retry clear cache - continue operation } From 054fcc8b21c27cb2dc53d91e298de0355c59a2cf Mon Sep 17 00:00:00 2001 From: borkarsaish65 Date: Mon, 30 Mar 2026 19:02:39 +0530 Subject: [PATCH 04/14] code added to clear user cache across orgs when default entity type is updated --- src/database/queries/userExtension.js | 10 ++++++++-- src/services/entity-type.js | 21 +++++++++++++++------ 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/database/queries/userExtension.js b/src/database/queries/userExtension.js index 27c5f52ea..cc72f9a5d 100644 --- a/src/database/queries/userExtension.js +++ b/src/database/queries/userExtension.js @@ -712,11 +712,17 @@ module.exports = class MenteeExtensionQueries { static async getAllUsersByOrgId(orgCodes, tenantCode) { try { + const viewName = utils.getTenantViewName(tenantCode, MenteeExtension.tableName) + + // null orgCodes = all orgs (used for default-org cross-org cache invalidation) + if (orgCodes === null) { + const query = `SELECT user_id FROM ${viewName} WHERE tenant_code = :tenantCode` + return await Sequelize.query(query, { type: QueryTypes.SELECT, replacements: { tenantCode } }) + } + if (!Array.isArray(orgCodes) || orgCodes.length === 0) { return [] } - const viewName = utils.getTenantViewName(tenantCode, MenteeExtension.tableName) - const query = ` SELECT user_id FROM ${viewName} diff --git a/src/services/entity-type.js b/src/services/entity-type.js index 5be65f1b3..55974f1b0 100644 --- a/src/services/entity-type.js +++ b/src/services/entity-type.js @@ -105,9 +105,9 @@ module.exports = class EntityHelper { } // Cache invalidation after successful update: just delete using original entity data + const isDefaultOrg = orgCode === process.env.DEFAULT_ORGANISATION_CODE try { if (originalEntity && originalEntity.model_names && originalEntity.value) { - const isDefaultOrg = orgCode === process.env.DEFAULT_ORGANISATION_CODE for (const modelName of originalEntity.model_names) { if (isDefaultOrg) { // Default org update: other orgs may have cached this entity type via fallback @@ -132,7 +132,8 @@ module.exports = class EntityHelper { orgCode, tenantCode, updatedEntity.model_names ? updatedEntity.model_names[0] : null, - updatedEntity.value + updatedEntity.value, + isDefaultOrg ) return responses.successResponse({ @@ -371,7 +372,8 @@ module.exports = class EntityHelper { organizationCode, tenantCode, entityToDelete.model_names ? entityToDelete.model_names[0] : null, - entityToDelete.value + entityToDelete.value, + isDefaultOrg ) return responses.successResponse({ @@ -546,7 +548,8 @@ module.exports = class EntityHelper { organizationCode, tenantCode, modelName = null, - entityValue = null + entityValue = null, + allOrgs = false ) { try { const logContext = modelName ? `${modelName}:${entityValue}` : 'global' @@ -592,7 +595,10 @@ module.exports = class EntityHelper { if (modelName === menteeModelName) { // Clear all mentee caches for this organization try { - const users = await menteeExtensionQueries.getAllUsersByOrgId([organizationCode], tenantCode) + const users = await menteeExtensionQueries.getAllUsersByOrgId( + allOrgs ? null : [organizationCode], + tenantCode + ) const menteeUserIds = users.map((user) => user.user_id) // Clear mentee caches for all users in organization @@ -611,7 +617,10 @@ module.exports = class EntityHelper { // Clear all mentor caches for this organization try { // Get all users who might be mentors in this organization - const users = await menteeExtensionQueries.getAllUsersByOrgId([organizationCode], tenantCode) + const users = await menteeExtensionQueries.getAllUsersByOrgId( + allOrgs ? null : [organizationCode], + tenantCode + ) const mentorUserIds = users.map((user) => user.user_id) // Clear mentor caches for all users in organization (users can be both mentee and mentor) From c18ead99c7ef351f750ce9796280c7ba20ec976c Mon Sep 17 00:00:00 2001 From: borkarsaish65 Date: Mon, 30 Mar 2026 19:10:18 +0530 Subject: [PATCH 05/14] correct function arguments --- src/services/entity-type.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/services/entity-type.js b/src/services/entity-type.js index 55974f1b0..56a8c2177 100644 --- a/src/services/entity-type.js +++ b/src/services/entity-type.js @@ -300,11 +300,15 @@ module.exports = class EntityHelper { } // Clear cache for affected models before deletion - await this._clearUserCachesForEntityTypeChange(organizationCode, tenantCode, { - id: entityToDelete.id, - value: entityToDelete.value, - modelNames: entityToDelete.model_names, - }) + const isDefaultOrg = organizationCode === process.env.DEFAULT_ORGANISATION_CODE + + await this._clearUserCachesForEntityTypeChange( + organizationCode, + tenantCode, + entityToDelete.model_names ? entityToDelete.model_names[0] : null, + entityToDelete.value, + isDefaultOrg + ) // SECOND: Delete from database const deleteCount = await entityTypeQueries.deleteOneEntityType(id, organizationCode, tenantCode) @@ -317,7 +321,6 @@ module.exports = class EntityHelper { } // THIRD: Remove individual entity type from cache - const isDefaultOrg = organizationCode === process.env.DEFAULT_ORGANISATION_CODE try { // For each model this entity belonged to if (entityToDelete.model_names && Array.isArray(entityToDelete.model_names)) { From ba25ae70e2341e472aef2d6a481cdd8b24cbde7d Mon Sep 17 00:00:00 2001 From: borkarsaish65 Date: Mon, 30 Mar 2026 21:00:41 +0530 Subject: [PATCH 06/14] removed console logs. --- src/generics/cacheHelper.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/generics/cacheHelper.js b/src/generics/cacheHelper.js index 47f034867..093b0896c 100644 --- a/src/generics/cacheHelper.js +++ b/src/generics/cacheHelper.js @@ -948,9 +948,7 @@ const mentor = { async deleteAll(tenantCode) { const pattern = `tenant:${tenantCode}:mentor:*` - console.log(`[MentorCache] deleteAll - scanning and deleting pattern: ${pattern}`) const result = await scanAndDelete(pattern) - console.log(`[MentorCache] deleteAll - deleted ${result} key(s)`) return result }, @@ -1195,9 +1193,7 @@ const mentee = { async deleteAll(tenantCode) { const pattern = `tenant:${tenantCode}:mentee:*` - console.log(`[MenteeCache] deleteAll - scanning and deleting pattern: ${pattern}`) const result = await scanAndDelete(pattern) - console.log(`[MenteeCache] deleteAll - deleted ${result} key(s)`) return result }, From 717331aaa915c8422c2173d523afb1eb6717030d Mon Sep 17 00:00:00 2001 From: borkarsaish65 Date: Mon, 30 Mar 2026 21:19:32 +0530 Subject: [PATCH 07/14] code updated --- src/services/entity-type.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/services/entity-type.js b/src/services/entity-type.js index b6cb31d34..f64623d09 100644 --- a/src/services/entity-type.js +++ b/src/services/entity-type.js @@ -296,6 +296,7 @@ module.exports = class EntityHelper { } // SECOND: Delete from database + const isDefaultOrg = organizationCode === process.env.DEFAULT_ORGANISATION_CODE const deleteCount = await entityTypeQueries.deleteOneEntityType(id, organizationCode, tenantCode) if (deleteCount === 0) { return responses.failureResponse({ @@ -311,7 +312,8 @@ module.exports = class EntityHelper { organizationCode, tenantCode, modelName, - entityToDelete.value + entityToDelete.value, + isDefaultOrg ) } From a2d80e101f60cc9040f6a13d8ba85214a3ce9d08 Mon Sep 17 00:00:00 2001 From: borkarsaish65 Date: Mon, 30 Mar 2026 22:47:11 +0530 Subject: [PATCH 08/14] feat: savepoint resolved pr comment: --- src/services/entity-type.js | 150 +++++++++--------------------------- 1 file changed, 35 insertions(+), 115 deletions(-) diff --git a/src/services/entity-type.js b/src/services/entity-type.js index f64623d09..1508bbd58 100644 --- a/src/services/entity-type.js +++ b/src/services/entity-type.js @@ -106,30 +106,16 @@ module.exports = class EntityHelper { // Cache invalidation after successful update: just delete using original entity data const isDefaultOrg = orgCode === process.env.DEFAULT_ORGANISATION_CODE - try { - if (originalEntity && originalEntity.model_names && originalEntity.value) { - for (const modelName of originalEntity.model_names) { - if (isDefaultOrg) { - // Default org update: other orgs may have cached this entity type via fallback - // under their own org key — sweep all of them - await cacheHelper.entityTypes.deleteEntityTypesAcrossAllOrgs( - tenantCode, - modelName, - originalEntity.value - ) - } else { - await cacheHelper.entityTypes.delete(tenantCode, orgCode, modelName, originalEntity.value) - } - } + if (originalEntity && originalEntity.model_names) { + for (const modelName of originalEntity.model_names) { + await this._clearUserCachesForEntityTypeChange( + orgCode, + tenantCode, + modelName, + originalEntity.value, + isDefaultOrg + ) } - } catch (cacheError) { - // Failed to invalidate entity type cache - continue operation - } - - // Clear user caches since entity types affect user profiles - const updatedEntity = updatedEntityType[0] - for (const modelName of updatedEntity.model_names) { - await this._clearUserCachesForEntityTypeChange(orgCode, tenantCode, modelName, updatedEntity.value) } return responses.successResponse({ @@ -317,56 +303,6 @@ module.exports = class EntityHelper { ) } - // THIRD: Remove individual entity type from cache - try { - // For each model this entity belonged to - if (entityToDelete.model_names && Array.isArray(entityToDelete.model_names)) { - for (const modelName of entityToDelete.model_names) { - // Remove the specific entity type cache - if (isDefaultOrg) { - await cacheHelper.entityTypes.deleteEntityTypesAcrossAllOrgs( - tenantCode, - modelName, - entityToDelete.value - ) - } else { - await cacheHelper.entityTypes.delete( - tenantCode, - organizationCode, - modelName, - entityToDelete.value - ) - } - } - } - } catch (cacheError) { - // Failed to perform selective cache removal - continue operation - - // Fallback: retry removing only this specific entity's cache - if (entityToDelete.model_names && Array.isArray(entityToDelete.model_names)) { - for (const modelName of entityToDelete.model_names) { - try { - if (isDefaultOrg) { - await cacheHelper.entityTypes.deleteEntityTypesAcrossAllOrgs( - tenantCode, - modelName, - entityToDelete.value - ) - } else { - await cacheHelper.entityTypes.delete( - tenantCode, - organizationCode, - modelName, - entityToDelete.value - ) - } - } catch (retryError) { - // Failed to retry clear cache - continue operation - } - } - } - } - return responses.successResponse({ statusCode: httpStatusCode.accepted, message: 'ENTITY_TYPE_DELETED_SUCCESSFULLY', @@ -496,41 +432,18 @@ module.exports = class EntityHelper { // Clear cache for deleted entities try { const defaultOrgCode = process.env.DEFAULT_ORGANISATION_CODE - const affectedModelNames = new Set() - for (const entityToDelete of entitiesToDelete) { - const modelNames = entityToDelete.model_names || [] const isDefaultOrg = entityToDelete.organization_code === defaultOrgCode - for (const modelName of modelNames) { - if (isDefaultOrg) { - await cacheHelper.entityTypes.deleteEntityTypesAcrossAllOrgs( - tenantCode, - modelName, - entityToDelete.value - ) - } else { - await cacheHelper.entityTypes.delete( - tenantCode, - entityToDelete.organization_code, - modelName, - entityToDelete.value - ) - } - affectedModelNames.add(modelName) + for (const modelName of entityToDelete.model_names || []) { + await this._clearUserCachesForEntityTypeChange( + entityToDelete.organization_code, + tenantCode, + modelName, + entityToDelete.value, + isDefaultOrg + ) } } - - // Clear user profile caches for affected models - const [menteeModelName, mentorModelName] = await Promise.all([ - menteeExtensionQueries.getModelName(), - mentorExtensionQueries.getModelName(), - ]) - if (affectedModelNames.has(menteeModelName)) { - await cacheHelper.mentee.deleteAll(tenantCode).catch(() => {}) - } - if (affectedModelNames.has(mentorModelName)) { - await cacheHelper.mentor.deleteAll(tenantCode).catch(() => {}) - } } catch (cacheError) { console.log('Failed to clear cache for deleted entities:', cacheError.message) } @@ -587,13 +500,19 @@ module.exports = class EntityHelper { // 2. Clear entity type cache for the specific model + value if (modelName) { - clearPromises.push( - cacheHelper.entityTypes - .delete(tenantCode, organizationCode, modelName, entityValue) - .catch((error) => { - /* Failed to clear entity type cache - continue operation */ - }) - ) + if (allOrgs) { + clearPromises.push( + cacheHelper.entityTypes + .deleteEntityTypesAcrossAllOrgs(tenantCode, modelName, entityValue) + .catch(() => {}) + ) + } else { + clearPromises.push( + cacheHelper.entityTypes + .delete(tenantCode, organizationCode, modelName, entityValue) + .catch(() => {}) + ) + } } // 3. Clear model-specific user caches based on the entity type model @@ -649,10 +568,11 @@ module.exports = class EntityHelper { } if (modelName === sessionModelName) { - // For session model, we don't have session enumeration by org - // Session caches are typically cleared by individual session operations - // Entity types affecting sessions would be rare (custom session fields) - // Skip organization-wide session cache clearing to avoid performance impact + if (allOrgs) { + clearPromises.push(cacheHelper.sessions.deleteAll(tenantCode).catch(() => {})) + } else { + clearPromises.push(cacheHelper.sessions.deleteAll(tenantCode, organizationCode).catch(() => {})) + } } } From 7287c32c6794ede6c0406663cf7acede0b459022 Mon Sep 17 00:00:00 2001 From: borkarsaish65 Date: Mon, 30 Mar 2026 23:06:07 +0530 Subject: [PATCH 09/14] latest changes --- src/generics/cacheHelper.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/generics/cacheHelper.js b/src/generics/cacheHelper.js index 093b0896c..b0f70a490 100644 --- a/src/generics/cacheHelper.js +++ b/src/generics/cacheHelper.js @@ -369,6 +369,16 @@ const sessions = { return del(cacheKey, { useInternal }) }, + async deleteAll(tenantCode, orgCode = null) { + const pattern = orgCode + ? `tenant:${tenantCode}:org:${orgCode}:sessions:*` + : `tenant:${tenantCode}:org:*:sessions:*` + console.log(`[SessionCache] deleteAll - scanning and deleting pattern: ${pattern}`) + const result = await scanAndDelete(pattern) + console.log(`[SessionCache] deleteAll - deleted ${result} key(s)`) + return result + }, + async reset(tenantCode, sessionId, sessionData, customTtl = null) { return this.set(tenantCode, sessionId, sessionData, customTtl) }, From f30c8eea6167734d0a91fa39e2a32051d730caa6 Mon Sep 17 00:00:00 2001 From: borkarsaish65 Date: Tue, 31 Mar 2026 13:03:04 +0530 Subject: [PATCH 10/14] PR comments addressed --- src/generics/cacheHelper.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/generics/cacheHelper.js b/src/generics/cacheHelper.js index b0f70a490..2e37a67af 100644 --- a/src/generics/cacheHelper.js +++ b/src/generics/cacheHelper.js @@ -373,9 +373,7 @@ const sessions = { const pattern = orgCode ? `tenant:${tenantCode}:org:${orgCode}:sessions:*` : `tenant:${tenantCode}:org:*:sessions:*` - console.log(`[SessionCache] deleteAll - scanning and deleting pattern: ${pattern}`) const result = await scanAndDelete(pattern) - console.log(`[SessionCache] deleteAll - deleted ${result} key(s)`) return result }, From 8bbc969215d2bc5f31c51cb99fcbafc6fcfc165b Mon Sep 17 00:00:00 2001 From: borkarsaish65 Date: Tue, 31 Mar 2026 14:41:57 +0530 Subject: [PATCH 11/14] PR comments addressed --- src/database/queries/userExtension.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/database/queries/userExtension.js b/src/database/queries/userExtension.js index cc582b5db..9082a455b 100644 --- a/src/database/queries/userExtension.js +++ b/src/database/queries/userExtension.js @@ -712,11 +712,12 @@ module.exports = class MenteeExtensionQueries { static async getAllUsersByOrgId(orgCodes, tenantCode) { try { - const viewName = utils.getTenantViewName(tenantCode, MenteeExtension.tableName) - if (!Array.isArray(orgCodes) || orgCodes.length === 0) { return [] } + + const viewName = utils.getTenantViewName(tenantCode, MenteeExtension.tableName) + const query = ` SELECT user_id FROM ${viewName} From 8ccf5290aa87fe26970cecc65b256e7d2ffef2f2 Mon Sep 17 00:00:00 2001 From: borkarsaish65 Date: Tue, 31 Mar 2026 15:15:08 +0530 Subject: [PATCH 12/14] PR comments addressed --- src/generics/cacheHelper.js | 6 ++---- src/services/entity-type.js | 7 ++----- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/generics/cacheHelper.js b/src/generics/cacheHelper.js index 2e37a67af..5ac496167 100644 --- a/src/generics/cacheHelper.js +++ b/src/generics/cacheHelper.js @@ -369,10 +369,8 @@ const sessions = { return del(cacheKey, { useInternal }) }, - async deleteAll(tenantCode, orgCode = null) { - const pattern = orgCode - ? `tenant:${tenantCode}:org:${orgCode}:sessions:*` - : `tenant:${tenantCode}:org:*:sessions:*` + async deleteAll(tenantCode) { + const pattern = `tenant:${tenantCode}:sessions:*` const result = await scanAndDelete(pattern) return result }, diff --git a/src/services/entity-type.js b/src/services/entity-type.js index 1508bbd58..ed52acf5b 100644 --- a/src/services/entity-type.js +++ b/src/services/entity-type.js @@ -568,11 +568,8 @@ module.exports = class EntityHelper { } if (modelName === sessionModelName) { - if (allOrgs) { - clearPromises.push(cacheHelper.sessions.deleteAll(tenantCode).catch(() => {})) - } else { - clearPromises.push(cacheHelper.sessions.deleteAll(tenantCode, organizationCode).catch(() => {})) - } + // Session keys have no org scope, so always sweep all sessions for the tenant + clearPromises.push(cacheHelper.sessions.deleteAll(tenantCode).catch(() => {})) } } From 53c6b91725ca88617e3c95d921138d66638aca52 Mon Sep 17 00:00:00 2001 From: borkarsaish65 Date: Tue, 31 Mar 2026 18:19:51 +0530 Subject: [PATCH 13/14] deleting display properties logic added --- src/generics/cacheHelper.js | 8 ++++++++ src/services/entity-type.js | 10 +++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/generics/cacheHelper.js b/src/generics/cacheHelper.js index 5ac496167..242f14e3c 100644 --- a/src/generics/cacheHelper.js +++ b/src/generics/cacheHelper.js @@ -1587,6 +1587,14 @@ const displayProperties = { await del(orgKey, { useInternal }) await del(tenantKey, { useInternal }) }, + async deleteAll(tenantCode) { + // Delete all org-level displayProperties + const pattern = `tenant:${tenantCode}:org:*:displayProperties` + await scanAndDelete(pattern) + // Optional: delete tenant-level fallback + const tenantPattern = `tenant:${tenantCode}:org::displayProperties` + await scanAndDelete(tenantPattern) + }, } /** diff --git a/src/services/entity-type.js b/src/services/entity-type.js index ed52acf5b..e92bf8074 100644 --- a/src/services/entity-type.js +++ b/src/services/entity-type.js @@ -492,11 +492,11 @@ module.exports = class EntityHelper { const clearPromises = [] // 1. Clear display properties cache (affects all users in org) - clearPromises.push( - cacheHelper.displayProperties.delete(tenantCode, organizationCode).catch((error) => { - /* Failed to clear display properties cache - continue operation */ - }) - ) + if (allOrgs) { + clearPromises.push(cacheHelper.displayProperties.deleteAll(tenantCode).catch(() => {})) + } else { + clearPromises.push(cacheHelper.displayProperties.delete(tenantCode, organizationCode).catch(() => {})) + } // 2. Clear entity type cache for the specific model + value if (modelName) { From b6d543f47a03d7dc98ea7eb95d3faea70d13bb25 Mon Sep 17 00:00:00 2001 From: borkarsaish65 Date: Tue, 31 Mar 2026 18:37:45 +0530 Subject: [PATCH 14/14] addressed PR comment --- src/generics/cacheHelper.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/generics/cacheHelper.js b/src/generics/cacheHelper.js index 242f14e3c..1a7969621 100644 --- a/src/generics/cacheHelper.js +++ b/src/generics/cacheHelper.js @@ -1591,9 +1591,6 @@ const displayProperties = { // Delete all org-level displayProperties const pattern = `tenant:${tenantCode}:org:*:displayProperties` await scanAndDelete(pattern) - // Optional: delete tenant-level fallback - const tenantPattern = `tenant:${tenantCode}:org::displayProperties` - await scanAndDelete(tenantPattern) }, }