Skip to content

Conversation

@nevil-mathew
Copy link
Collaborator

@nevil-mathew nevil-mathew commented Sep 26, 2025

Summary by CodeRabbit

  • New Features

    • Added clearer localized messages for organization deactivation: not found, already inactive, and deactivation failure.
  • Bug Fixes

    • Prevents deactivation attempts for non-existent or already inactive organizations by performing pre-checks.
    • Adds input validation for organization and tenant identifiers to reduce errors and improve reliability.

@coderabbitai
Copy link

coderabbitai bot commented Sep 26, 2025

Walkthrough

Adds three new English locale strings for organization deactivation errors, introduces a new validator for deactivateOrg that checks route param and tenant header, and updates the admin service deactivateOrg flow to pre-check org existence/status and use updated error keys while keeping downstream deactivation steps unchanged.

Changes

Cohort / File(s) Summary
Locales updates
src/locales/en.json
Added ORG_DEACTIVATION_FAILED, ORG_NOT_FOUND, ORG_ALREADY_INACTIVE strings; no removals or modifications to existing keys.
Admin service logic
src/services/admin.js
deactivateOrg now looks up org by code+tenant and returns ORG_NOT_FOUND if missing or ORG_ALREADY_INACTIVE if already inactive before attempting update; on update failure returns ORG_DEACTIVATION_FAILED; downstream steps (deactivate users, end sessions, broadcast event, success) unchanged.
Validators
src/validators/v1/admin.js
Added deactivateOrg(req) validator: validates req.params.id and req.headers['tenant-id'] for non-empty and lowercase alphanumeric with underscores pattern; exported in validators.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant C as Client
  participant V as Validator (v1/admin)
  participant S as AdminService.deactivateOrg
  participant O as OrgRepo
  participant U as UserService
  participant SS as SessionService
  participant E as EventBus

  C->>V: Request: deactivateOrg(id, tenant-id)
  V-->>C: 400 if params/headers invalid
  V->>S: Valid request

  rect rgba(230,240,255,0.6)
    note over S,O: Pre-checks (new)
    S->>O: findByCodeAndTenant(id, tenant-id)
    O-->>S: org | null
    alt org not found
      S-->>C: Error: ORG_NOT_FOUND
    else org inactive
      S-->>C: Error: ORG_ALREADY_INACTIVE
    else proceed
      S->>O: update status -> inactive
      O-->>S: ok | fail
      alt update failed
        S-->>C: Error: ORG_DEACTIVATION_FAILED
      else success
        S->>U: Deactivate users in org
        U-->>S: ok
        S->>SS: End active sessions
        SS-->>S: ok
        S->>E: Broadcast deactivation event
        E-->>S: ack
        S-->>C: Success
      end
    end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

I hop through code with tiny paws,
I check the burrow’s fields and laws.
“Not found?” I blink; “Already still?” I nod.
I mark the change, I send the prod.
A tidy hop — deactivation done! 🐇✨

Pre-merge checks and finishing touches

✅ 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 succinctly describes the primary change—adding validation and error messaging for organization deactivation—and clearly conveys the fix being introduced without veering into unrelated details.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch org-deactivate-validation

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bc01cc7 and 049ac72.

📒 Files selected for processing (1)
  • src/services/admin.js (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/services/admin.js

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

@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 (1)
src/validators/v1/admin.js (1)

8-10: Fix runtime ReferenceError: import body from express-validator

The login validator chains use body(...) but it is not imported. This will throw at runtime.

Apply this diff:

 const filterRequestBody = require('../common')
 const { admin } = require('@constants/blacklistConfig')
+const { body } = require('express-validator')
🧹 Nitpick comments (3)
src/validators/v1/admin.js (2)

101-107: Align phone pattern used in conditional with the one used above

You validate phone as 7–15 digits earlier but use 6–15 digits here for the conditional. Make them consistent:

-  .if(body('identifier').custom((value) => /^\d{6,15}$/.test(value))) // Apply only for phone identifiers
+  .if(body('identifier').custom((value) => /^\d{7,15}$/.test(value))) // Apply only for phone identifiers

151-157: Unify tenant-id header validation across validators

addOrgAdmin checks only isString, while deactivateOrg additionally pattern-matches. Consider extracting a shared helper to validate tenant-id once to avoid drift.

Example:

  • helpers/validators.js: export validateTenantId(req) that applies isString + /^[a-z0-9_-]+$/.
  • Use in all validators that touch tenant-id.
src/locales/en.json (1)

88-90: Standardize spelling: use “Organization” consistently

Elsewhere keys predominantly use “Organization”. Recommend updating new strings for consistency.

Apply this diff:

-  "ORG_DEACTIVATION_FAILED": "Failed to deactivate organisation.",
-  "ORG_NOT_FOUND": "Organisation not found.",
-  "ORG_ALREADY_INACTIVE": "Organisation is already inactive.",
+  "ORG_DEACTIVATION_FAILED": "Failed to deactivate organization.",
+  "ORG_NOT_FOUND": "Organization not found.",
+  "ORG_ALREADY_INACTIVE": "Organization is already inactive.",
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e5b1348 and bc01cc7.

📒 Files selected for processing (3)
  • src/locales/en.json (1 hunks)
  • src/services/admin.js (2 hunks)
  • src/validators/v1/admin.js (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
src/validators/**

⚙️ CodeRabbit configuration file

Validate all incoming data thoroughly. Check for missing or incomplete validation rules.

Files:

  • src/validators/v1/admin.js
src/services/**

⚙️ CodeRabbit configuration file

This is core business logic. Please check for correctness, efficiency, and potential edge cases.

Files:

  • src/services/admin.js
🧠 Learnings (3)
📓 Common learnings
Learnt from: praveenKDass
PR: ELEVATE-Project/user#816
File: src/services/admin.js:704-704
Timestamp: 2025-09-12T10:35:28.285Z
Learning: In the ELEVATE-Project/user codebase, when organizationQueries.update is called with { returning: true, raw: true }, it returns an object { rowsAffected, updatedRows }, not just a number. The validation logic in admin.js deactivateOrg method checking 'if (orgRowsAffected === 0)' is incorrect and should be 'if (orgRowsAffected.rowsAffected === 0)' to properly validate successful updates.
Learnt from: praveenKDass
PR: ELEVATE-Project/user#816
File: src/services/admin.js:704-704
Timestamp: 2025-09-12T10:35:28.285Z
Learning: In ELEVATE-Project/user admin.js, there's an inconsistency in organizationQueries.update usage: addOrgAdmin calls it without options (returns number), while deactivateOrg calls it with { returning: true, raw: true } (returns object). The validation logic 'if (orgRowsAffected === 0)' only works for the first case - the second case needs 'if (orgRowsAffected.rowsAffected === 0)' to properly validate updates.
📚 Learning: 2025-09-12T10:35:28.285Z
Learnt from: praveenKDass
PR: ELEVATE-Project/user#816
File: src/services/admin.js:704-704
Timestamp: 2025-09-12T10:35:28.285Z
Learning: In ELEVATE-Project/user admin.js, there's an inconsistency in organizationQueries.update usage: addOrgAdmin calls it without options (returns number), while deactivateOrg calls it with { returning: true, raw: true } (returns object). The validation logic 'if (orgRowsAffected === 0)' only works for the first case - the second case needs 'if (orgRowsAffected.rowsAffected === 0)' to properly validate updates.

Applied to files:

  • src/validators/v1/admin.js
  • src/services/admin.js
📚 Learning: 2025-09-12T10:35:28.285Z
Learnt from: praveenKDass
PR: ELEVATE-Project/user#816
File: src/services/admin.js:704-704
Timestamp: 2025-09-12T10:35:28.285Z
Learning: In the ELEVATE-Project/user codebase, when organizationQueries.update is called with { returning: true, raw: true }, it returns an object { rowsAffected, updatedRows }, not just a number. The validation logic in admin.js deactivateOrg method checking 'if (orgRowsAffected === 0)' is incorrect and should be 'if (orgRowsAffected.rowsAffected === 0)' to properly validate successful updates.

Applied to files:

  • src/validators/v1/admin.js
  • src/services/admin.js
🔇 Additional comments (2)
src/validators/v1/admin.js (2)

167-179: Broaden id and tenant-id validation

  • id: allow numbers or lowercase slug with hyphens/underscores (^(?:\d+|[a-z0-9_-]+)$) and update the message to “id must be a number or lowercase alphanumeric string with hyphens/underscores.”
  • tenant-id: enforce .isString(), allow hyphens/underscores (/^[a-z0-9_-]+$/), and update its message.
  • Verify if numeric org IDs are ever passed to deactivateOrg; if they aren’t, adjust the message to reference org codes only.

167-179: deactivateOrg update result check is correct The organizationQueries.update call in deactivateOrg doesn’t use {returning: true, raw: true}, so it returns a numeric count and if (orgRowsAffected === 0) correctly handles failures.

@aks30 aks30 merged commit f055147 into develop Sep 29, 2025
1 of 2 checks passed
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.

3 participants