Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 9 additions & 14 deletions src/generics/cacheHelper.js
Comment thread
sumanvpacewisdom marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ const sessions = {
try {
// Handle single session ID case
if (typeof sessionIds === 'string') {
return await this.get(tenantCode, organizationCode, sessionIds)
return await this.get(tenantCode, sessionIds)
}

// Handle array case - smart caching with immediate DB fetch
Expand Down Expand Up @@ -485,7 +485,7 @@ const sessions = {

if (sessionDetails) {
// Cache the session data directly
await this.set(tenantCode, organizationCode, sessionId, sessionDetails)
await this.set(tenantCode, sessionId, sessionDetails)
dbFetchedSessions.push(sessionDetails)
console.log(`✅ [getSessionKafka] Session ${sessionId} fetched and cached`)
}
Expand All @@ -509,7 +509,7 @@ const sessions = {
const fallbackResults = []
for (const sessionId of Array.isArray(sessionIds) ? sessionIds : [sessionIds]) {
try {
const session = await this.get(tenantCode, organizationCode, sessionId)
const session = await this.get(tenantCode, sessionId)
if (session) fallbackResults.push(session)
} catch (fallbackError) {
console.error(
Expand Down Expand Up @@ -1045,7 +1045,7 @@ const mentor = {
try {
// Handle single user ID case
if (typeof userIds === 'string') {
return await this.get(tenantCode, organizationCode, userIds)
return await this.get(tenantCode, userIds)
}

// Handle array case - smart caching with immediate DB fetch
Expand Down Expand Up @@ -1073,7 +1073,7 @@ const mentor = {

// Step 4: Fetch missing users from DB immediately using getUsersByUserIds
const dbFetchedUsers = []
const userMentorEntries = []
let userMentorEntries = []
if (missingUserIds.length > 0) {
try {
const usersFromDb = await userQueries.getUsersByUserIds(missingUserIds, {}, tenantCode, false)
Expand Down Expand Up @@ -1114,7 +1114,7 @@ const mentor = {
const fallbackResults = []
for (const userId of Array.isArray(userIds) ? userIds : [userIds]) {
try {
const user = await this.get(tenantCode, organizationCode, userId)
const user = await this.get(tenantCode, userId)
if (user) fallbackResults.push(user)
} catch (fallbackError) {
console.error(`❌ [getMenteeKafka] Fallback failed for user ${userId}:`, fallbackError.message)
Expand Down Expand Up @@ -1292,7 +1292,7 @@ const mentee = {
try {
// Handle single user ID case
if (typeof userIds === 'string') {
return await this.get(tenantCode, organizationCode, userIds)
return await this.get(tenantCode, userIds)
}

// Handle array case - smart caching with immediate DB fetch
Expand Down Expand Up @@ -1320,7 +1320,6 @@ const mentee = {

// Step 3: Fetch missing users from DB immediately using getUsersByUserIds
const dbFetchedUsers = []
let userMentorEntries = []
if (missingUserIds.length > 0) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The getMenteeKafka method has no equivalent call to this._sendToKafkaBackground() to getMentorKafka. What is the use of getMenteeKafka?

Copy link
Copy Markdown
Collaborator Author

@sumanvpacewisdom sumanvpacewisdom Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be done later as discussion

try {
console.log(`🔄 [getMenteeKafka] Fetching ${missingUserIds.length} users from database`)
Expand All @@ -1334,16 +1333,12 @@ const mentee = {
if (usersFromDb && usersFromDb.length > 0) {
// Cache each fetched user individually
for (const user of usersFromDb) {
await this.set(tenantCode, organizationCode, user.user_id, user)
await this.set(tenantCode, user.user_id, user)
}

// Add fetched users to result
dbFetchedUsers.push(...usersFromDb)

// Create user ID to is_mentor mapping using map
const userMentorEntries = usersFromDb.map((user) => [user.user_id, user.is_mentor || false])
Object.assign(userIsMentorMap, Object.fromEntries(userMentorEntries))

console.log(`✅ [getMenteeKafka] ${usersFromDb.length} users fetched from DB and cached`)
}
} catch (dbError) {
Expand All @@ -1361,7 +1356,7 @@ const mentee = {
const fallbackResults = []
for (const userId of Array.isArray(userIds) ? userIds : [userIds]) {
try {
const user = await this.get(tenantCode, organizationCode, userId)
const user = await this.get(tenantCode, userId)
if (user) fallbackResults.push(user)
} catch (fallbackError) {
console.error(`❌ [getMenteeKafka] Fallback failed for user ${userId}:`, fallbackError.message)
Expand Down
4 changes: 2 additions & 2 deletions src/services/admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -676,9 +676,9 @@ module.exports = class AdminService {
if (unenrollDetails && unenrollDetails.deletedCount > 0 && Array.isArray(unenrollDetails.deletedRecords)) {
for (const menteeData of unenrollDetails.deletedRecords) {
try {
await cacheHelper.mentee.delete(tenantCode, menteeData.organization_code, menteeData.mentee_id)
await cacheHelper.mentee.delete(tenantCode, menteeData.mentee_id)
} catch (cacheError) {
console.error(`Cache deletion failed for mentee ${menteeId}:`, cacheError)
console.error(`Cache deletion failed for mentee ${menteeData.mentee_id}:`, cacheError)
}
}
}
Expand Down
40 changes: 16 additions & 24 deletions src/services/entity-type.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,9 @@ module.exports = class EntityHelper {

// Clear user caches since entity types affect user profiles
const updatedEntity = updatedEntityType[0]
await this._clearUserCachesForEntityTypeChange(
orgCode,
tenantCode,
updatedEntity.model_names ? updatedEntity.model_names[0] : null,
updatedEntity.value
)
for (const modelName of updatedEntity.model_names) {
await this._clearUserCachesForEntityTypeChange(orgCode, tenantCode, modelName, updatedEntity.value)
}

return responses.successResponse({
statusCode: httpStatusCode.accepted,
Expand Down Expand Up @@ -288,13 +285,6 @@ 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,
})

// SECOND: Delete from database
const deleteCount = await entityTypeQueries.deleteOneEntityType(id, organizationCode, tenantCode)
if (deleteCount === 0) {
Expand All @@ -305,6 +295,16 @@ module.exports = class EntityHelper {
})
}

// Clear user caches after successful deletion
for (const modelName of entityToDelete.model_names) {
await this._clearUserCachesForEntityTypeChange(
organizationCode,
tenantCode,
modelName,
entityToDelete.value
)
}

// THIRD: Remove individual entity type from cache
try {
// For each model this entity belonged to
Expand Down Expand Up @@ -339,14 +339,6 @@ module.exports = class EntityHelper {
}
}

// Clear user caches since entity types affect user profiles
await this._clearUserCachesForEntityTypeChange(
organizationCode,
tenantCode,
entityToDelete.model_names ? entityToDelete.model_names[0] : null,
entityToDelete.value
)

return responses.successResponse({
statusCode: httpStatusCode.accepted,
message: 'ENTITY_TYPE_DELETED_SUCCESSFULLY',
Expand Down Expand Up @@ -539,13 +531,13 @@ module.exports = class EntityHelper {
})
)

// 2. Clear entity type caches for unified model strategy
// 2. Clear entity type cache for the specific model + value
if (modelName) {
clearPromises.push(
cacheHelper.entityTypes
.delete(tenantCode, organizationCode, `model:${modelName}:__ALL__`)
.delete(tenantCode, organizationCode, modelName, entityValue)
.catch((error) => {
/* Failed to clear unified entity type cache - continue operation */
/* Failed to clear entity type cache - continue operation */
})
)
}
Expand Down
82 changes: 7 additions & 75 deletions src/services/entity.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,27 +50,6 @@ module.exports = class EntityHelper {
}
}

// Invalidate entity list caches after creation
if (entity && sanitizedData.entity_type_id) {
// Separate try-catch for each cache deletion to ensure all caches are cleared
try {
await cacheHelper.forms.delete(
tenantCode,
common.SYSTEM,
'entity_list',
sanitizedData.entity_type_id
)
} catch (cacheError) {
console.error(`❌ Failed to invalidate entity_list cache after creation:`, cacheError)
}

try {
await cacheHelper.forms.delete(tenantCode, common.SYSTEM, 'entity_list_all', 'all_entities')
} catch (cacheError) {
console.error(`❌ Failed to invalidate entity_list_all cache after creation:`, cacheError)
}
}

return responses.successResponse({
statusCode: httpStatusCode.created,
message: 'ENTITY_CREATED_SUCCESSFULLY',
Expand Down Expand Up @@ -163,23 +142,6 @@ module.exports = class EntityHelper {
}
}

// Invalidate entity list caches after update
if (updatedEntity && (updatedEntity.entity_type_id || sanitizedData.entity_type_id)) {
const entityTypeId = updatedEntity.entity_type_id || sanitizedData.entity_type_id
// Separate try-catch for each cache deletion to ensure all caches are cleared
try {
await cacheHelper.forms.delete(tenantCode, common.SYSTEM, 'entity_list', entityTypeId)
} catch (cacheError) {
console.error(`❌ Failed to invalidate entity_list cache after update:`, cacheError)
}

try {
await cacheHelper.forms.delete(tenantCode, common.SYSTEM, 'entity_list_all', 'all_entities')
} catch (cacheError) {
console.error(`❌ Failed to invalidate entity_list_all cache after update:`, cacheError)
}
}

return responses.successResponse({
statusCode: httpStatusCode.accepted,
message: 'ENTITY_UPDATED_SUCCESSFULLY',
Expand Down Expand Up @@ -387,14 +349,6 @@ module.exports = class EntityHelper {
}
}

// Invalidate entity list caches after deletion
try {
// Clear all entity list caches since we don't know the entity_type_id after deletion
await cacheHelper.forms.delete(tenantCode, common.SYSTEM, 'entity_list_all', 'all_entities')
} catch (cacheError) {
console.error(`❌ Failed to invalidate entity list cache after deletion:`, cacheError)
}

return responses.successResponse({
statusCode: httpStatusCode.accepted,
message: 'ENTITY_DELETED_SUCCESSFULLY',
Expand Down Expand Up @@ -441,35 +395,13 @@ module.exports = class EntityHelper {
filter['entity_type_id'] = entityType
}

// Try to get entities from cache first (only cache paginated lists without search)
const cacheKey = `${entityType || 'all'}_page${pageNo}_limit${pageSize}`
let entities = null

if (!searchText) {
entities = await cacheHelper.forms.get(tenantCode, common.SYSTEM, 'entity_list', cacheKey)
if (entities) {
}
}

if (!entities) {
// Optimized: Get entities with entity_type details included - eliminates N+1 queries for clients
entities = await entityQueries.getAllEntitiesWithEntityTypeDetails(
filter,
tenantCode,
pageNo,
pageSize,
searchText
)

// Cache the result if no search text (searchable results shouldn't be cached)
if (!searchText && entities) {
try {
await cacheHelper.forms.set(tenantCode, common.SYSTEM, 'entity_list', cacheKey, entities)
} catch (cacheError) {
console.error(`❌ Failed to cache entity list:`, cacheError)
}
}
}
const entities = await entityQueries.getAllEntitiesWithEntityTypeDetails(
filter,
tenantCode,
pageNo,
pageSize,
searchText
)
Comment thread
coderabbitai[bot] marked this conversation as resolved.

if (entities.rows == 0 || entities.count == 0) {
return responses.failureResponse({
Expand Down
2 changes: 1 addition & 1 deletion src/services/organization.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ module.exports = class OrganizationService {
mentor_feedback_question_set: bodyData.mentor_feedback_question_set,
updated_by: decodedToken.id,
}
const orgExtension = await organisationExtensionQueries.upsert(extensionData)
const orgExtension = await organisationExtensionQueries.upsert(extensionData, tenantCode)

// Update cache with fresh data after update
try {
Expand Down