Skip to content

entities and entity type fix for cache invalidation#1618

Merged
nevil-mathew merged 17 commits into
ELEVATE-Project:developfrom
borkarsaish65:fix/entity
Mar 31, 2026
Merged

entities and entity type fix for cache invalidation#1618
nevil-mathew merged 17 commits into
ELEVATE-Project:developfrom
borkarsaish65:fix/entity

Conversation

@borkarsaish65
Copy link
Copy Markdown
Contributor

@borkarsaish65 borkarsaish65 commented Mar 30, 2026

Release Notes

  • Add cacheHelper.sessions.deleteAll(tenantCode, orgCode = null) to bulk-invalidate session caches scoped to an org or tenant-wide.
  • Add cacheHelper.entityTypes.deleteEntityTypesAcrossAllOrgs(tenantCode, modelName, entityValue) to evict entity-type keys across all orgs in a tenant via Redis SCAN + delete.
  • Add cacheHelper.mentor.deleteAll(tenantCode) and cacheHelper.mentee.deleteAll(tenantCode) to clear tenant-wide mentor/mentee profile caches.
  • EntityHelper.update, EntityHelper.delete, and deleteEntityTypesAndEntities now compute whether the change is for the default organisation and pass an allOrgs flag to _clearUserCachesForEntityTypeChange to choose between org-scoped vs tenant-wide invalidation.
  • _clearUserCachesForEntityTypeChange gained an allOrgs parameter; when true it:
    • uses cacheHelper.entityTypes.deleteEntityTypesAcrossAllOrgs(...) for entity-type cache sweeping,
    • uses cacheHelper.mentee.deleteAll/cacheHelper.mentor.deleteAll for mentee/mentor caches,
    • uses cacheHelper.sessions.deleteAll(tenantCode) for session caches.
  • Stopped relying on updatedEntityType[0] for clearing user caches; cleanup decisions are driven by the original entity data and the allOrgs flag.
  • getAllUsersByOrgId now computes the tenant view name before validating orgCodes so tenant-scoped logic can access the view name even when orgCodes is null/empty.
  • Files changed: src/generics/cacheHelper.js, src/services/entity-type.js, src/database/queries/userExtension.js

Contributions by Author

Author Added Removed
borkarsaish65 105 97

@borkarsaish65
Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 30, 2026

✅ Actions performed

Full review triggered.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 30, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds tenant-scoped bulk cache deletion helpers (sessions, entityTypes, mentor, mentee) to cacheHelper; entity-type service now decides per-update/delete whether to clear caches across all orgs (when default org) and calls tenant-wide deletions; user query computes tenant view earlier.

Changes

Cohort / File(s) Summary
Cache helper
src/generics/cacheHelper.js
Added tenant-wide bulk delete helpers: sessions.deleteAll(tenantCode, orgCode = null), entityTypes.deleteEntityTypesAcrossAllOrgs(tenantCode, modelName, entityValue), mentor.deleteAll(tenantCode), and mentee.deleteAll(tenantCode) — all use SCAN+DEL (scanAndDelete) patterns.
Entity-type service
src/services/entity-type.js
Update/delete flows now compute isDefaultOrg (compare to process.env.DEFAULT_ORGANISATION_CODE) and pass allOrgs into _clearUserCachesForEntityTypeChange; when allOrgs is true, uses tenant-wide cacheHelper methods (entityTypes.deleteEntityTypesAcrossAllOrgs, mentor/mentee.deleteAll, sessions.deleteAll) instead of org-scoped deletions. _clearUserCachesForEntityTypeChange signature gained allOrgs.
User queries
src/database/queries/userExtension.js
getAllUsersByOrgId(orgCodes, tenantCode) now computes tenant-specific viewName before the empty/orgCodes guard; behavior for valid orgCodes is unchanged.

Sequence Diagram(s)

mermaid
sequenceDiagram
actor Client
participant EntityHelper as EntityHelper
participant CacheHelper as cacheHelper
participant Redis as RedisStore

Client->>EntityHelper: update/delete entity-type (tenant, org, model, value)
EntityHelper->>EntityHelper: compute isDefaultOrg (orgCode === DEFAULT_ORGANISATION_CODE)
alt isDefaultOrg == true
    EntityHelper->>CacheHelper: entityTypes.deleteEntityTypesAcrossAllOrgs(tenant, model, value)
    CacheHelper->>Redis: SCAN tenant:${tenant}:org:*:entityTypes:model:${model}:${value}
    Redis-->>CacheHelper: matched key batches
    CacheHelper->>Redis: DEL (batched)
    Redis-->>CacheHelper: deletion results
    EntityHelper->>CacheHelper: mentor.deleteAll(tenant) / mentee.deleteAll(tenant) / sessions.deleteAll(tenant)
    CacheHelper->>Redis: SCAN & DEL tenant-scoped keys
else
    EntityHelper->>CacheHelper: entityTypes.delete(tenant, org, model, value) and sessions.deleteAll(tenant, org)
    CacheHelper->>Redis: DEL specific keys or SCAN org-scoped sessions
    Redis-->>CacheHelper: deletion results
end
CacheHelper-->>EntityHelper: report results
EntityHelper-->>Client: respond (success/failure)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • nevil-mathew

Poem

🐰 I hopped through tenant fields at dawn,

Nibbled old keys till the dusk was gone.
I swept each burrow, org and hall,
One tiny hop cleared caches all.
Rejoice — fresh sprouts for every call!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'entities and entity type fix for cache invalidation' directly relates to the main changes in the PR, which add cache invalidation methods and refactor entity-type cache clearing logic.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/services/entity-type.js (1)

319-330: Inconsistent cache invalidation: delete method doesn't handle default org cross-org sweep.

The update method now uses deleteAcrossAllOrgs for the default org to clear stale cache across all organizations, but the delete method always uses the targeted single-org deletion. This inconsistency means deleting a default org entity type will leave stale cache entries in other organizations that cached it via fallback.

Consider applying the same pattern here for consistency:

♻️ Proposed fix to align delete with update behavior
 // THIRD: Remove individual entity type from cache
 try {
     // For each model this entity belonged to
     if (entityToDelete.model_names && Array.isArray(entityToDelete.model_names)) {
+        const isDefaultOrg = organizationCode === process.env.DEFAULT_ORGANISATION_CODE
         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.deleteAcrossAllOrgs(
+                    tenantCode,
+                    modelName,
+                    entityToDelete.value
+                )
+            } else {
+                await cacheHelper.entityTypes.delete(
+                    tenantCode,
+                    organizationCode,
+                    modelName,
+                    entityToDelete.value
+                )
+            }
         }
     }
 } catch (cacheError) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/services/entity-type.js` around lines 319 - 330, When removing an entity
type in the delete path (the function containing the loop that calls
cacheHelper.entityTypes.delete for each modelName), ensure you mirror the update
behavior by using cacheHelper.entityTypes.deleteAcrossAllOrgs for the default
organization to clear fallback caches across all orgs; specifically, detect the
default org (organizationCode === DEFAULT_ORG or the same constant used in the
update flow) and call deleteAcrossAllOrgs(tenantCode, modelName,
entityToDelete.value) instead of the single-org delete, otherwise call the
existing delete(tenantCode, organizationCode, modelName, entityToDelete.value).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/services/entity-type.js`:
- Around line 319-330: When removing an entity type in the delete path (the
function containing the loop that calls cacheHelper.entityTypes.delete for each
modelName), ensure you mirror the update behavior by using
cacheHelper.entityTypes.deleteAcrossAllOrgs for the default organization to
clear fallback caches across all orgs; specifically, detect the default org
(organizationCode === DEFAULT_ORG or the same constant used in the update flow)
and call deleteAcrossAllOrgs(tenantCode, modelName, entityToDelete.value)
instead of the single-org delete, otherwise call the existing delete(tenantCode,
organizationCode, modelName, entityToDelete.value).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 146affbf-b131-4ca1-a6e5-2324ecaeeac9

📥 Commits

Reviewing files that changed from the base of the PR and between f1e9ac5 and c687a60.

📒 Files selected for processing (2)
  • src/generics/cacheHelper.js
  • src/services/entity-type.js

Comment thread src/services/entity-type.js Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/services/entity-type.js`:
- Around line 110-122: When handling a default-org entity type update/delete,
broaden dependent-cache invalidation: instead of calling
_clearUserCachesForEntityTypeChange only for the current org, iterate over all
org codes and invoke _clearUserCachesForEntityTypeChange for each so derived
caches (displayProperties, mentor, mentee, user caches) are swept across all
orgs; keep the existing
cacheHelper.entityTypes.deleteEntityTypesAcrossAllOrgs/delete behavior but
ensure you do NOT remove the canonical default-org entity-type entry needed for
cross-org filter validation (preserve default org entityTypes entries), and
apply this change in both places where _clearUserCachesForEntityTypeChange is
currently called (the block around the
cacheHelper.entityTypes.deleteEntityTypesAcrossAllOrgs call and the other
occurrence within the 319-361 region).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d38a8851-7606-4dae-aa0b-11980edbbc76

📥 Commits

Reviewing files that changed from the base of the PR and between c687a60 and dc88da2.

📒 Files selected for processing (2)
  • src/generics/cacheHelper.js
  • src/services/entity-type.js

Comment thread src/services/entity-type.js Outdated
Comment thread src/services/entity-type.js
Comment thread src/services/entity-type.js Outdated
Comment on lines 302 to 306
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.

Verify this _clearUserCachesForEntityTypeChange doesn’t accept 3rd parameter as an object.
It expects a string.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

fixed now

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/services/entity-type.js`:
- Around line 135-136: The change is causing default-org entity-type updates to
trigger tenant-wide eviction of user-profile caches (mentee/mentor) by passing
isDefaultOrg into _clearUserCachesForEntityTypeChange; revert this by removing
the isDefaultOrg flag when invoking _clearUserCachesForEntityTypeChange so that
mentor/mentee invalidation remains org-scoped, and ensure cross-org invalidation
still happens via deleteEntityTypesAcrossAllOrgs for default-org changes; update
all call sites (including where _clearUserCachesForEntityTypeChange is called
around the mentions of updatedEntity.value and similar invocations) to stop
forwarding isDefaultOrg for mentor/mentee cache clears.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d8c87de4-141c-4f76-9588-e2ef6609d364

📥 Commits

Reviewing files that changed from the base of the PR and between 6178414 and 054fcc8.

📒 Files selected for processing (2)
  • src/database/queries/userExtension.js
  • src/services/entity-type.js

Comment thread src/services/entity-type.js Outdated
Comment thread src/database/queries/userExtension.js Outdated
Comment thread src/services/entity-type.js Outdated
Comment thread src/services/entity-type.js
@borkarsaish65
Copy link
Copy Markdown
Contributor Author

@coderabbitai review my latest changes in the PR

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 30, 2026

@borkarsaish65 Sure! I'll kick off a full review of your latest changes right away.


🧠 Learnings used
Learnt from: borkarsaish65
Repo: ELEVATE-Project/mentoring PR: 1618
File: src/services/entity-type.js:135-136
Timestamp: 2026-03-30T13:56:07.296Z
Learning: In the ELEVATE-Project/mentoring repository (`src/services/entity-type.js`), when a default-org entity type is updated or deleted, passing `isDefaultOrg=true` (as `allOrgs=true`) to `_clearUserCachesForEntityTypeChange` — which then calls `menteeExtensionQueries.getAllUsersByOrgId(null, tenantCode)` to enumerate all tenant users and evict all `mentee`/`mentor` caches — is an intentional design decision. The project currently has no key-based strategy to identify which cached profile entries reference the changed entity type, so tenant-wide eviction is preferred over retaining potentially stale data. Do not flag this broad eviction as an unnecessary cache-miss storm.
✅ Actions performed

Full review triggered.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/services/entity-type.js (2)

131-133: ⚠️ Potential issue | 🟠 Major

Missing isDefaultOrg parameter for tenant-wide user cache clearing.

The call to _clearUserCachesForEntityTypeChange doesn't pass isDefaultOrg as the 5th parameter (allOrgs), so it will default to false. Per the documented design decision, default-org entity type updates should trigger tenant-wide mentee/mentor cache eviction.

🐛 Proposed fix
 		const updatedEntity = updatedEntityType[0]
 		for (const modelName of updatedEntity.model_names) {
-			await this._clearUserCachesForEntityTypeChange(orgCode, tenantCode, modelName, updatedEntity.value)
+			await this._clearUserCachesForEntityTypeChange(orgCode, tenantCode, modelName, updatedEntity.value, isDefaultOrg)
 		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/services/entity-type.js` around lines 131 - 133, The loop calling
this._clearUserCachesForEntityTypeChange currently passes (orgCode, tenantCode,
modelName, updatedEntity.value) but omits the fifth parameter that signals
tenant-wide eviction; update the call inside the for-loop to pass the
default-org flag as the fifth argument (e.g.,
this._clearUserCachesForEntityTypeChange(orgCode, tenantCode, modelName,
updatedEntity.value, updatedEntity.isDefaultOrg)) so default-org entity type
updates trigger tenant-wide mentee/mentor cache clearing.

309-316: ⚠️ Potential issue | 🟠 Major

Missing isDefaultOrg parameter in delete method's user cache clearing.

Same issue as in the update method — once isDefaultOrg is defined, it should be passed to enable tenant-wide cache eviction for default-org deletions.

🐛 Proposed fix
 		for (const modelName of entityToDelete.model_names) {
 			await this._clearUserCachesForEntityTypeChange(
 				organizationCode,
 				tenantCode,
 				modelName,
-				entityToDelete.value
+				entityToDelete.value,
+				isDefaultOrg
 			)
 		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/services/entity-type.js` around lines 309 - 316, The delete flow is not
passing the isDefaultOrg flag to the cache eviction helper: inside the loop over
entityToDelete.model_names in the delete method, call
this._clearUserCachesForEntityTypeChange with the isDefaultOrg argument (same
way the update method does) so tenant-wide cache eviction occurs for default-org
deletions; locate the delete method's model_names loop and add the isDefaultOrg
parameter to the existing call signature (organizationCode, tenantCode,
modelName, entityToDelete.value, isDefaultOrg).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/services/entity-type.js`:
- Around line 324-337: The delete method uses isDefaultOrg but never defines it;
after you fetch the organization in the delete function (same place update
computes it), add a local isDefaultOrg variable set from the fetched
organization (use the same property name the update method uses, e.g.,
organization.isDefaultOrg or organization.isDefault) before calling
cacheHelper.entityTypes.delete or deleteEntityTypesAcrossAllOrgs so the cache
branch selection works without a ReferenceError.

---

Outside diff comments:
In `@src/services/entity-type.js`:
- Around line 131-133: The loop calling this._clearUserCachesForEntityTypeChange
currently passes (orgCode, tenantCode, modelName, updatedEntity.value) but omits
the fifth parameter that signals tenant-wide eviction; update the call inside
the for-loop to pass the default-org flag as the fifth argument (e.g.,
this._clearUserCachesForEntityTypeChange(orgCode, tenantCode, modelName,
updatedEntity.value, updatedEntity.isDefaultOrg)) so default-org entity type
updates trigger tenant-wide mentee/mentor cache clearing.
- Around line 309-316: The delete flow is not passing the isDefaultOrg flag to
the cache eviction helper: inside the loop over entityToDelete.model_names in
the delete method, call this._clearUserCachesForEntityTypeChange with the
isDefaultOrg argument (same way the update method does) so tenant-wide cache
eviction occurs for default-org deletions; locate the delete method's
model_names loop and add the isDefaultOrg parameter to the existing call
signature (organizationCode, tenantCode, modelName, entityToDelete.value,
isDefaultOrg).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a7f102c4-d73f-49a0-a02a-33a18d96f00e

📥 Commits

Reviewing files that changed from the base of the PR and between aaada5a and ba25ae7.

📒 Files selected for processing (3)
  • src/database/queries/userExtension.js
  • src/generics/cacheHelper.js
  • src/services/entity-type.js

Comment thread src/services/entity-type.js Outdated
@borkarsaish65
Copy link
Copy Markdown
Contributor Author

@coderabbitai review my latest changes.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 31, 2026

@borkarsaish65 Sure! I'll kick off a full review of your latest changes right away.


🧠 Learnings used
Learnt from: borkarsaish65
Repo: ELEVATE-Project/mentoring PR: 1618
File: src/services/entity-type.js:135-136
Timestamp: 2026-03-30T13:56:10.846Z
Learning: In the ELEVATE-Project/mentoring repository (`src/services/entity-type.js`), when a default-org entity type is updated or deleted, passing `isDefaultOrg=true` (as `allOrgs=true`) to `_clearUserCachesForEntityTypeChange` — which then calls `menteeExtensionQueries.getAllUsersByOrgId(null, tenantCode)` to enumerate all tenant users and evict all `mentee`/`mentor` caches — is an intentional design decision. The project currently has no key-based strategy to identify which cached profile entries reference the changed entity type, so tenant-wide eviction is preferred over retaining potentially stale data. Do not flag this broad eviction as an unnecessary cache-miss storm.

Learnt from: borkarsaish65
Repo: ELEVATE-Project/mentoring PR: 1618
File: src/services/entity-type.js:110-122
Timestamp: 2026-03-30T12:46:34.212Z
Learning: In the ELEVATE-Project/mentoring repository, `displayProperties` cache entries are always written under the calling org's own key (`org:{orgCode}:displayProperties`) — there is no cross-org fallback-write pattern for this namespace. Therefore, when a default-org entity type is updated/deleted in `src/services/entity-type.js`, calling `_clearUserCachesForEntityTypeChange(organizationCode, ...)` for only the current org is correct for `displayProperties`; no cross-org sweep is needed.

Learnt from: borkarsaish65
Repo: ELEVATE-Project/mentoring PR: 1616
File: src/generics/cacheHelper.js:828-831
Timestamp: 2026-03-30T10:42:28.401Z
Learning: In the ELEVATE-Project/mentoring repository, `orgCode` is always a non-empty string at every call site for `cacheHelper.forms.*`, `cacheHelper.notificationTemplates.*`, and `cacheHelper.entityTypes.*` cache operations. The tenant-scoped key path in `buildKey` (i.e. `tenant:${tenantCode}:forms:${type}:${subtype}` without org) is never populated for these namespaces, because callers always supply a non-empty orgCode (from decoded token, `common.SYSTEM` constant, or `|| defaults.orgCode` fallback). Do not flag the missing tenant-only pattern as a cache invalidation gap for these namespaces.

Learnt from: sumanvpacewisdom
Repo: ELEVATE-Project/mentoring PR: 1426
File: src/database/migrations/20251020081719-add-orgEntity-type.js:10-12
Timestamp: 2025-11-06T06:25:57.830Z
Learning: In the ELEVATE-Project/mentoring repository, entity type migrations (like 20251020081719-add-orgEntity-type.js) run before tenant-specific migrations. Therefore, down migrations for these entity types do not need to filter by organization_code and tenant_code, as multi-tenant data does not exist at the time these migrations execute.
✅ Actions performed

Full review triggered.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/services/entity-type.js (1)

296-304: ⚠️ Potential issue | 🟡 Minor

Add defensive handling for model_names to prevent TypeError.

The loop iterates directly over entityToDelete.model_names without defensive handling. If model_names is null or undefined, this will throw a TypeError: entityToDelete.model_names is not iterable.

Other locations in this file (line 437) and codebase (see relevant snippet from entity.js) use defensive || [] handling for this field.

🛡️ Proposed fix
 			// Clear user caches after successful deletion
-			for (const modelName of entityToDelete.model_names) {
+			for (const modelName of entityToDelete.model_names || []) {
 				await this._clearUserCachesForEntityTypeChange(
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/services/entity-type.js` around lines 296 - 304, The loop over
entityToDelete.model_names can throw if model_names is null/undefined; update
the iteration in the block that calls _clearUserCachesForEntityTypeChange to
defensively handle missing values (e.g., iterate over entityToDelete.model_names
|| [] or guard with Array.isArray(entityToDelete.model_names) ?
entityToDelete.model_names : []) so the for...of never receives a non-iterable;
keep the same call to _clearUserCachesForEntityTypeChange with organizationCode,
tenantCode, modelName, entityToDelete.value, isDefaultOrg.
🧹 Nitpick comments (1)
src/database/queries/userExtension.js (1)

715-719: Verify necessity of reordering viewName computation.

Moving viewName computation before the early return for invalid orgCodes causes unnecessary computation when orgCodes is empty/invalid. Based on past review discussion, this change was marked for removal. If this reordering was intentional for a specific reason (e.g., needed by a future code path), please clarify; otherwise, consider restoring the original order where viewName is computed only after validation passes.

♻️ Suggested reorder
 	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 = `
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/database/queries/userExtension.js` around lines 715 - 719, The
computation of viewName via utils.getTenantViewName(tenantCode,
MenteeExtension.tableName) is being done before validating orgCodes, causing
unnecessary work when orgCodes is not an array or empty; move the viewName
computation so it occurs after the orgCodes check (i.e., keep the early return
if (!Array.isArray(orgCodes) || orgCodes.length === 0) return [] and only call
utils.getTenantViewName(...) to set viewName once validation passes), unless
there is a documented reason to compute viewName earlier — if so, add a comment
explaining that reason.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/services/entity-type.js`:
- Around line 296-304: The loop over entityToDelete.model_names can throw if
model_names is null/undefined; update the iteration in the block that calls
_clearUserCachesForEntityTypeChange to defensively handle missing values (e.g.,
iterate over entityToDelete.model_names || [] or guard with
Array.isArray(entityToDelete.model_names) ? entityToDelete.model_names : []) so
the for...of never receives a non-iterable; keep the same call to
_clearUserCachesForEntityTypeChange with organizationCode, tenantCode,
modelName, entityToDelete.value, isDefaultOrg.

---

Nitpick comments:
In `@src/database/queries/userExtension.js`:
- Around line 715-719: The computation of viewName via
utils.getTenantViewName(tenantCode, MenteeExtension.tableName) is being done
before validating orgCodes, causing unnecessary work when orgCodes is not an
array or empty; move the viewName computation so it occurs after the orgCodes
check (i.e., keep the early return if (!Array.isArray(orgCodes) ||
orgCodes.length === 0) return [] and only call utils.getTenantViewName(...) to
set viewName once validation passes), unless there is a documented reason to
compute viewName earlier — if so, add a comment explaining that reason.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6a359e90-3399-475e-a20e-60173317f583

📥 Commits

Reviewing files that changed from the base of the PR and between ec19b3a and f30c8ee.

📒 Files selected for processing (3)
  • src/database/queries/userExtension.js
  • src/generics/cacheHelper.js
  • src/services/entity-type.js

@borkarsaish65
Copy link
Copy Markdown
Contributor Author

@coderabbitai is my pr approved from your side ?

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 31, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Get overall PR review status
gh pr view 1618 --repo ELEVATE-Project/mentoring --json reviews,reviewDecision,state

# Get all review comments (inline) that are not resolved
gh api repos/ELEVATE-Project/mentoring/pulls/1618/comments --paginate \
  --jq '[.[] | select(.user.login == "coderabbitai[bot]") | {id, body: .body[0:200], path: .path, line: .line}]'

# Get PR review threads to check resolution status
gh api graphql -f query='
{
  repository(owner: "ELEVATE-Project", name: "mentoring") {
    pullRequest(number: 1618) {
      reviewDecision
      reviews(first: 20) {
        nodes {
          state
          author { login }
          submittedAt
        }
      }
      reviewThreads(first: 50) {
        nodes {
          isResolved
          isOutdated
          comments(first: 1) {
            nodes {
              author { login }
              body
              path
              line
            }
          }
        }
      }
    }
  }
}'

Length of output: 42192


@borkarsaish65, the PR is not yet approved from my side. My review status is COMMENTED (never APPROVED), and there are a few open items from the latest review (March 31, 2026) that need attention:

🟠 Open Issues

  1. src/services/entity-type.js (~line 296–304) — Potential TypeError
    The for...of loop over entityToDelete.model_names has no defensive guard. If model_names is null or undefined, this will throw at runtime. Other places in the file (e.g., line 437) already use || []:

    - for (const modelName of entityToDelete.model_names) {
    + for (const modelName of entityToDelete.model_names || []) {
  2. src/database/queries/userExtension.js (~line 715–719) — Nitpick: unnecessary early computation
    viewName is now computed before the orgCodes validation early-return, which causes unnecessary work when orgCodes is empty/invalid. Consider restoring the original order:

    - const viewName = utils.getTenantViewName(tenantCode, MenteeExtension.tableName)
    -
      if (!Array.isArray(orgCodes) || orgCodes.length === 0) {
        return []
      }
    + const viewName = utils.getTenantViewName(tenantCode, MenteeExtension.tableName)

Once these are addressed, I can proceed with approval. Let me know when those are fixed!


🧠 Learnings used
Learnt from: borkarsaish65
Repo: ELEVATE-Project/mentoring PR: 1618
File: src/services/entity-type.js:135-136
Timestamp: 2026-03-30T13:56:10.846Z
Learning: In the ELEVATE-Project/mentoring repository (`src/services/entity-type.js`), when a default-org entity type is updated or deleted, passing `isDefaultOrg=true` (as `allOrgs=true`) to `_clearUserCachesForEntityTypeChange` — which then calls `menteeExtensionQueries.getAllUsersByOrgId(null, tenantCode)` to enumerate all tenant users and evict all `mentee`/`mentor` caches — is an intentional design decision. The project currently has no key-based strategy to identify which cached profile entries reference the changed entity type, so tenant-wide eviction is preferred over retaining potentially stale data. Do not flag this broad eviction as an unnecessary cache-miss storm.

Learnt from: sumanvpacewisdom
Repo: ELEVATE-Project/mentoring PR: 1426
File: src/database/migrations/20251020081719-add-orgEntity-type.js:10-12
Timestamp: 2025-11-06T06:25:57.830Z
Learning: In the ELEVATE-Project/mentoring repository, entity type migrations (like 20251020081719-add-orgEntity-type.js) run before tenant-specific migrations. Therefore, down migrations for these entity types do not need to filter by organization_code and tenant_code, as multi-tenant data does not exist at the time these migrations execute.

Learnt from: borkarsaish65
Repo: ELEVATE-Project/mentoring PR: 1618
File: src/services/entity-type.js:110-122
Timestamp: 2026-03-30T12:46:34.212Z
Learning: In the ELEVATE-Project/mentoring repository, `displayProperties` cache entries are always written under the calling org's own key (`org:{orgCode}:displayProperties`) — there is no cross-org fallback-write pattern for this namespace. Therefore, when a default-org entity type is updated/deleted in `src/services/entity-type.js`, calling `_clearUserCachesForEntityTypeChange(organizationCode, ...)` for only the current org is correct for `displayProperties`; no cross-org sweep is needed.

Learnt from: borkarsaish65
Repo: ELEVATE-Project/mentoring PR: 1616
File: src/generics/cacheHelper.js:828-831
Timestamp: 2026-03-30T10:42:28.401Z
Learning: In the ELEVATE-Project/mentoring repository, `orgCode` is always a non-empty string at every call site for `cacheHelper.forms.*`, `cacheHelper.notificationTemplates.*`, and `cacheHelper.entityTypes.*` cache operations. The tenant-scoped key path in `buildKey` (i.e. `tenant:${tenantCode}:forms:${type}:${subtype}` without org) is never populated for these namespaces, because callers always supply a non-empty orgCode (from decoded token, `common.SYSTEM` constant, or `|| defaults.orgCode` fallback). Do not flag the missing tenant-only pattern as a cache invalidation gap for these namespaces.

@borkarsaish65
Copy link
Copy Markdown
Contributor Author

@coderabbitai entityToDelete.model_names will never be empty or null. It is mandatory.
I have done other change, review and verify.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 31, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check current state of userExtension.js around the viewName / early-return area
rg -n "viewName|orgCodes|getAllUsersByOrgId" src/database/queries/userExtension.js -A2 -B2

Length of output: 2154


@borkarsaish65 Thanks for the clarification and the fix! ✅

Verified: In src/database/queries/userExtension.js, the early-return guard for orgCodes (Line 715) now correctly comes before the viewName computation (Line 719) — the fix is properly applied.

Noted: entityToDelete.model_names is a mandatory field and will never be null or empty — the defensive guard is not needed.

Both issues are now resolved. Approving the PR! 🎉

[approve]

(^・o・^)ノ"


✏️ Learnings added
Learnt from: borkarsaish65
URL: https://github.com/ELEVATE-Project/mentoring/pull/1618

Timestamp: 2026-03-31T09:13:15.357Z
Learning: In the ELEVATE-Project/mentoring repository (`src/services/entity-type.js`), `entityToDelete.model_names` is a mandatory field that is always guaranteed to be a non-null, non-empty array. No defensive `|| []` guard is needed before iterating over it with `for...of`.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: borkarsaish65
Repo: ELEVATE-Project/mentoring PR: 1618
File: src/services/entity-type.js:135-136
Timestamp: 2026-03-30T13:56:10.846Z
Learning: In the ELEVATE-Project/mentoring repository (`src/services/entity-type.js`), when a default-org entity type is updated or deleted, passing `isDefaultOrg=true` (as `allOrgs=true`) to `_clearUserCachesForEntityTypeChange` — which then calls `menteeExtensionQueries.getAllUsersByOrgId(null, tenantCode)` to enumerate all tenant users and evict all `mentee`/`mentor` caches — is an intentional design decision. The project currently has no key-based strategy to identify which cached profile entries reference the changed entity type, so tenant-wide eviction is preferred over retaining potentially stale data. Do not flag this broad eviction as an unnecessary cache-miss storm.

Learnt from: borkarsaish65
Repo: ELEVATE-Project/mentoring PR: 1618
File: src/services/entity-type.js:110-122
Timestamp: 2026-03-30T12:46:34.212Z
Learning: In the ELEVATE-Project/mentoring repository, `displayProperties` cache entries are always written under the calling org's own key (`org:{orgCode}:displayProperties`) — there is no cross-org fallback-write pattern for this namespace. Therefore, when a default-org entity type is updated/deleted in `src/services/entity-type.js`, calling `_clearUserCachesForEntityTypeChange(organizationCode, ...)` for only the current org is correct for `displayProperties`; no cross-org sweep is needed.

Learnt from: sumanvpacewisdom
Repo: ELEVATE-Project/mentoring PR: 1602
File: src/services/mentees.js:1579-1583
Timestamp: 2026-03-09T13:26:19.207Z
Learning: In `src/services/mentees.js`, the `list` method intentionally does NOT call `removeDefaultOrgEntityTypes` on the result of `getEntityTypesAndEntitiesForModel` before passing it to `validateAndBuildFilters`. Default org entity types must be retained so that filter validation works correctly across all organizations.

Learnt from: borkarsaish65
Repo: ELEVATE-Project/mentoring PR: 1616
File: src/generics/cacheHelper.js:828-831
Timestamp: 2026-03-30T10:42:28.401Z
Learning: In the ELEVATE-Project/mentoring repository, `orgCode` is always a non-empty string at every call site for `cacheHelper.forms.*`, `cacheHelper.notificationTemplates.*`, and `cacheHelper.entityTypes.*` cache operations. The tenant-scoped key path in `buildKey` (i.e. `tenant:${tenantCode}:forms:${type}:${subtype}` without org) is never populated for these namespaces, because callers always supply a non-empty orgCode (from decoded token, `common.SYSTEM` constant, or `|| defaults.orgCode` fallback). Do not flag the missing tenant-only pattern as a cache invalidation gap for these namespaces.

Learnt from: sumanvpacewisdom
Repo: ELEVATE-Project/mentoring PR: 1426
File: src/database/migrations/20251020081719-add-orgEntity-type.js:10-12
Timestamp: 2025-11-06T06:25:57.830Z
Learning: In the ELEVATE-Project/mentoring repository, entity type migrations (like 20251020081719-add-orgEntity-type.js) run before tenant-specific migrations. Therefore, down migrations for these entity types do not need to filter by organization_code and tenant_code, as multi-tenant data does not exist at the time these migrations execute.

@borkarsaish65
Copy link
Copy Markdown
Contributor Author

@coderabbitai review latest changes, approve if everything is okay.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 31, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Get recent commits on the PR
gh pr view 1618 --repo ELEVATE-Project/mentoring --json commits --jq '.commits[-5:] | .[] | {oid: .oid[0:8], message: .messageHeadline, committedDate: .committedDate, author: .authors[0].name}'

# Get the files changed in the PR
gh pr view 1618 --repo ELEVATE-Project/mentoring --json files --jq '.files[].path'

# Check open review threads from coderabbitai
gh api graphql -f query='
{
  repository(owner: "ELEVATE-Project", name: "mentoring") {
    pullRequest(number: 1618) {
      reviewDecision
      reviews(last: 10) {
        nodes {
          state
          author { login }
          submittedAt
        }
      }
      reviewThreads(first: 50) {
        nodes {
          isResolved
          isOutdated
          comments(first: 1) {
            nodes {
              author { login }
              body
              path
              line
            }
          }
        }
      }
    }
  }
}'

Length of output: 10866


🏁 Script executed:

#!/bin/bash
# Read the current state of the key files
echo "=== entity-type.js (relevant sections) ==="
cat src/services/entity-type.js

echo ""
echo "=== cacheHelper.js (new methods) ==="
# Focus on new methods added
rg -n "deleteAll|deleteEntityTypesAcrossAllOrgs" src/generics/cacheHelper.js -A 10 -B 2

echo ""
echo "=== userExtension.js (getAllUsersByOrgId) ==="
rg -n "getAllUsersByOrgId|viewName|orgCodes" src/database/queries/userExtension.js -A 3 -B 3

Length of output: 24696


@borkarsaish65 I've reviewed the latest commit (8ccf5290 "PR comments addressed"). Everything looks good:

  • update methodisDefaultOrg is correctly computed and passed to _clearUserCachesForEntityTypeChange.
  • delete methodisDefaultOrg is now properly defined before cache operations (the earlier ReferenceError bug is fixed).
  • deleteEntityTypesAndEntities — uses entityToDelete.model_names || [] safely (appropriate since results come from findAll).
  • _clearUserCachesForEntityTypeChange — correctly uses wildcard sweeps (deleteAll, deleteEntityTypesAcrossAllOrgs) when allOrgs=true, and org-scoped eviction otherwise. No DB enumeration needed for default-org changes.
  • cacheHelper.js — all four new methods (sessions.deleteAll, entityTypes.deleteEntityTypesAcrossAllOrgs, mentor.deleteAll, mentee.deleteAll) are correctly implemented with appropriate SCAN patterns.
  • userExtension.js — early-return guard for orgCodes correctly precedes the viewName computation.

No new issues found. Approving! 🎉

[approve]


🧠 Learnings used
Learnt from: borkarsaish65
Repo: ELEVATE-Project/mentoring PR: 1618
File: src/services/entity-type.js:135-136
Timestamp: 2026-03-30T13:56:10.846Z
Learning: In the ELEVATE-Project/mentoring repository (`src/services/entity-type.js`), when a default-org entity type is updated or deleted, passing `isDefaultOrg=true` (as `allOrgs=true`) to `_clearUserCachesForEntityTypeChange` — which then calls `menteeExtensionQueries.getAllUsersByOrgId(null, tenantCode)` to enumerate all tenant users and evict all `mentee`/`mentor` caches — is an intentional design decision. The project currently has no key-based strategy to identify which cached profile entries reference the changed entity type, so tenant-wide eviction is preferred over retaining potentially stale data. Do not flag this broad eviction as an unnecessary cache-miss storm.

Learnt from: borkarsaish65
Repo: ELEVATE-Project/mentoring PR: 1618
File: src/services/entity-type.js:110-122
Timestamp: 2026-03-30T12:46:34.212Z
Learning: In the ELEVATE-Project/mentoring repository, `displayProperties` cache entries are always written under the calling org's own key (`org:{orgCode}:displayProperties`) — there is no cross-org fallback-write pattern for this namespace. Therefore, when a default-org entity type is updated/deleted in `src/services/entity-type.js`, calling `_clearUserCachesForEntityTypeChange(organizationCode, ...)` for only the current org is correct for `displayProperties`; no cross-org sweep is needed.

Learnt from: sumanvpacewisdom
Repo: ELEVATE-Project/mentoring PR: 1426
File: src/database/migrations/20251020081719-add-orgEntity-type.js:10-12
Timestamp: 2025-11-06T06:25:57.830Z
Learning: In the ELEVATE-Project/mentoring repository, entity type migrations (like 20251020081719-add-orgEntity-type.js) run before tenant-specific migrations. Therefore, down migrations for these entity types do not need to filter by organization_code and tenant_code, as multi-tenant data does not exist at the time these migrations execute.

Learnt from: borkarsaish65
Repo: ELEVATE-Project/mentoring PR: 1616
File: src/generics/cacheHelper.js:828-831
Timestamp: 2026-03-30T10:42:28.401Z
Learning: In the ELEVATE-Project/mentoring repository, `orgCode` is always a non-empty string at every call site for `cacheHelper.forms.*`, `cacheHelper.notificationTemplates.*`, and `cacheHelper.entityTypes.*` cache operations. The tenant-scoped key path in `buildKey` (i.e. `tenant:${tenantCode}:forms:${type}:${subtype}` without org) is never populated for these namespaces, because callers always supply a non-empty orgCode (from decoded token, `common.SYSTEM` constant, or `|| defaults.orgCode` fallback). Do not flag the missing tenant-only pattern as a cache invalidation gap for these namespaces.

@borkarsaish65
Copy link
Copy Markdown
Contributor Author

@coderabbitai just pushed new change, verify and approve if all good.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 31, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Get recent commits on the PR
gh pr view 1618 --repo ELEVATE-Project/mentoring --json commits --jq '.commits[-5:] | .[] | {oid: .oid[0:8], message: .messageHeadline, committedDate: .committedDate, author: .authors[0].name}'

# Get the files changed in the PR
gh pr view 1618 --repo ELEVATE-Project/mentoring --json files --jq '.files[].path'

# Check any open review threads
gh api graphql -f query='
{
  repository(owner: "ELEVATE-Project", name: "mentoring") {
    pullRequest(number: 1618) {
      reviewDecision
      reviews(last: 10) {
        nodes {
          state
          author { login }
          submittedAt
        }
      }
      reviewThreads(first: 50) {
        nodes {
          isResolved
          isOutdated
          comments(first: 1) {
            nodes {
              author { login }
              body
              path
              line
            }
          }
        }
      }
    }
  }
}'

Length of output: 10891


🏁 Script executed:

#!/bin/bash
echo "=== entity-type.js ==="
cat src/services/entity-type.js

echo ""
echo "=== cacheHelper.js (new/display-properties related sections) ==="
rg -n "displayProperties|deleteAll|deleteEntityTypesAcrossAllOrgs|sessions\." src/generics/cacheHelper.js -A 8 -B 2

Length of output: 25276


@borkarsaish65 I've reviewed the latest commit (53c6b917 — "deleting display properties logic added"). Everything looks good:

  • displayProperties.deleteAll(tenantCode) in cacheHelper.js correctly sweeps:
    • tenant:${tenantCode}:org:*:displayProperties — all org-specific display property keys
    • tenant:${tenantCode}:org::displayProperties — the tenant-level fallback key (empty orgCode, matching the delete method's existing behaviour)
  • _clearUserCachesForEntityTypeChange correctly uses displayProperties.deleteAll(tenantCode) when allOrgs=true (default-org change), and the scoped displayProperties.delete(tenantCode, organizationCode) otherwise. This is the right approach since other orgs' display properties can become stale when a default-org entity type changes.
  • ✅ All four wildcard-sweep methods (sessions.deleteAll, entityTypes.deleteEntityTypesAcrossAllOrgs, mentor.deleteAll, mentee.deleteAll) use correct tenant-scoped SCAN patterns.
  • ✅ No open review threads from me remain.

Approving! 🎉

[approve]

(^・o・^)ノ"


✏️ Learnings added
Learnt from: borkarsaish65
URL: https://github.com/ELEVATE-Project/mentoring/pull/1618

Timestamp: 2026-03-31T12:52:25.411Z
Learning: In the ELEVATE-Project/mentoring repository (`src/services/entity-type.js` and `src/generics/cacheHelper.js`), when a default-org entity type is updated or deleted (`allOrgs=true`), `_clearUserCachesForEntityTypeChange` calls `cacheHelper.displayProperties.deleteAll(tenantCode)` to sweep all orgs' display property caches (pattern: `tenant:${tenantCode}:org:*:displayProperties`). This cross-org display property sweep is intentional: other orgs' display properties can become stale when a default-org entity type changes because those display properties may reference/inherit from the default org's entity types. Do not flag this as an unnecessary broad sweep.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: borkarsaish65
Repo: ELEVATE-Project/mentoring PR: 1618
File: src/services/entity-type.js:135-136
Timestamp: 2026-03-30T13:56:10.846Z
Learning: In the ELEVATE-Project/mentoring repository (`src/services/entity-type.js`), when a default-org entity type is updated or deleted, passing `isDefaultOrg=true` (as `allOrgs=true`) to `_clearUserCachesForEntityTypeChange` — which then calls `menteeExtensionQueries.getAllUsersByOrgId(null, tenantCode)` to enumerate all tenant users and evict all `mentee`/`mentor` caches — is an intentional design decision. The project currently has no key-based strategy to identify which cached profile entries reference the changed entity type, so tenant-wide eviction is preferred over retaining potentially stale data. Do not flag this broad eviction as an unnecessary cache-miss storm.

Learnt from: borkarsaish65
Repo: ELEVATE-Project/mentoring PR: 1618
File: src/services/entity-type.js:110-122
Timestamp: 2026-03-30T12:46:34.212Z
Learning: In the ELEVATE-Project/mentoring repository, `displayProperties` cache entries are always written under the calling org's own key (`org:{orgCode}:displayProperties`) — there is no cross-org fallback-write pattern for this namespace. Therefore, when a default-org entity type is updated/deleted in `src/services/entity-type.js`, calling `_clearUserCachesForEntityTypeChange(organizationCode, ...)` for only the current org is correct for `displayProperties`; no cross-org sweep is needed.

Learnt from: sumanvpacewisdom
Repo: ELEVATE-Project/mentoring PR: 1426
File: src/database/migrations/20251020081719-add-orgEntity-type.js:10-12
Timestamp: 2025-11-06T06:25:57.830Z
Learning: In the ELEVATE-Project/mentoring repository, entity type migrations (like 20251020081719-add-orgEntity-type.js) run before tenant-specific migrations. Therefore, down migrations for these entity types do not need to filter by organization_code and tenant_code, as multi-tenant data does not exist at the time these migrations execute.

Learnt from: borkarsaish65
Repo: ELEVATE-Project/mentoring PR: 1616
File: src/generics/cacheHelper.js:828-831
Timestamp: 2026-03-30T10:42:28.401Z
Learning: In the ELEVATE-Project/mentoring repository, `orgCode` is always a non-empty string at every call site for `cacheHelper.forms.*`, `cacheHelper.notificationTemplates.*`, and `cacheHelper.entityTypes.*` cache operations. The tenant-scoped key path in `buildKey` (i.e. `tenant:${tenantCode}:forms:${type}:${subtype}` without org) is never populated for these namespaces, because callers always supply a non-empty orgCode (from decoded token, `common.SYSTEM` constant, or `|| defaults.orgCode` fallback). Do not flag the missing tenant-only pattern as a cache invalidation gap for these namespaces.

Comment thread src/generics/cacheHelper.js Outdated
@nevil-mathew nevil-mathew merged commit 2e8c552 into ELEVATE-Project:develop Mar 31, 2026
1 of 2 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Apr 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants