Skip to content
Closed
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
12 changes: 5 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
</details>

</br>
The Mentor building block enables effective mentoring interactions between mentors and mentees. The capability aims to create a transparent eco-system to learn, connect, solve, and share within communities. Mentor is an open-source mentoring application that facilitates peer learning and professional development by creating a community of mentors and mentees.
The User service block enables secure and highly extensible user management and organization management capabilities - User registration, Live and JWT basesd session management, Delete user, Forgot password with email notifications.

</div>
<br>
Expand Down Expand Up @@ -742,13 +742,11 @@ npm test

# Used in

This project was built to be used with [Mentor Service](https://github.com/ELEVATE-Project/mentoring.git).
This project was built to be used with [Mentoring Service](https://github.com/ELEVATE-Project/mentoring.git), [Project Service](https://github.com/ELEVATE-Project/project-service.git), [Survey Service](https://github.com/ELEVATE-Project/samiksha-service.git), [User Service](https://github.com/ELEVATE-Project/user.git).

Notification service repo can be found [here](https://github.com/ELEVATE-Project/notification.git).
The frontend/mobile application for Mentoring [repo](https://github.com/ELEVATE-Project/mentoring-mobile-app) and Projects and Survey [repo](https://github.com/ELEVATE-Project/observation-survey-projects-pwa)

The PWA [repo](https://github.com/ELEVATE-Project/mentoring-mobile-app).

You can learn more about the full implementation of Mentor [here](https://elevate-docs.shikshalokam.org/.mentorEd/intro) .
You can learn more about the full implementation of various capabilities of ELEVATE [here](https://elevate-docs.shikshalokam.org) .
<br>

# Team
Expand All @@ -761,7 +759,7 @@ You can learn more about the full implementation of Mentor [here](https://elevat

# Open Source Dependencies

Several open source dependencies that have aided user service development:
Several open-source dependencies have aided user service development:

![NodeJS](https://img.shields.io/badge/node.js-6DA55F?style=for-the-badge&logo=node.js&logoColor=white)
![MongoDB](https://img.shields.io/badge/MongoDB-%234ea94b.svg?style=for-the-badge&logo=mongodb&logoColor=white)
Expand Down
6 changes: 6 additions & 0 deletions src/database/models/organization.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ module.exports = (sequelize, DataTypes) => {
sourceKey: 'code',
as: 'organizationRegistrationCodes',
})

Organization.hasMany(models.Organization, {
as: 'relatedOrgsDetails',
foreignKey: 'id',
constraints: false,
})
}

return Organization
Expand Down
32 changes: 20 additions & 12 deletions src/database/queries/organization.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,24 +52,32 @@ exports.create = async (data) => {
}
exports.findOne = async (filter, options = {}) => {
try {
let includes = [...(options.include || [])]
if (options?.isAdmin) {
options = {
...options,
include: [
{
model: OrganizationRegistrationCode,
as: 'organizationRegistrationCodes',
attributes: ['registration_code'],
where: { status: 'ACTIVE', deleted_at: null, tenant_code: filter.tenant_code },
required: false,
},
],
}
includes.push({
model: OrganizationRegistrationCode,
as: 'organizationRegistrationCodes',
attributes: ['registration_code'],
where: { status: 'ACTIVE', deleted_at: null, tenant_code: filter.tenant_code },
required: false,
})
}

if (options?.getRelatedOrgIdAndCode) {
includes.push({
model: Organization,
as: 'relatedOrgsDetails',
attributes: ['id', 'code'],
required: false,
on: sequelize.literal(`"relatedOrgsDetails"."id" = ANY("Organization"."related_orgs")`),
})
}
delete options.isAdmin
delete options?.getRelatedOrgIdAndCode
let organization = await Organization.findOne({
where: filter,
...options,
include: includes,
nest: true,
})
if (!organization) return null
Expand Down
4 changes: 2 additions & 2 deletions src/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
"elevate-migrations": "module/migrations/bin/migrations.js",
"integration": "node app.js",
"test:integration": "jest --verbose ./integration-test --config=integrationJest.config.js --runInBand",
"db:init": "sequelize-cli db:create && sequelize-cli db:migrate ",
"db:seed:all": "sequelize-cli db:seed:all"
"db:init": "sequelize-cli db:create || echo 'Database already exists or some issue while creating db, Please check' && sequelize-cli db:migrate ",
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix the conditional logic in db:init script.

The current script has incorrect operator precedence. Due to && having higher precedence than ||, migrations will only run when db:create fails, not when it succeeds.

Apply this diff to fix the logic:

-		"db:init": "sequelize-cli db:create || echo 'Database already exists or some issue while creating db, Please check' && sequelize-cli db:migrate ",
+		"db:init": "(sequelize-cli db:create || echo 'Database already exists or some issue while creating db, Please check') && sequelize-cli db:migrate",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"db:init": "sequelize-cli db:create || echo 'Database already exists or some issue while creating db, Please check' && sequelize-cli db:migrate ",
"db:init": "(sequelize-cli db:create || echo 'Database already exists or some issue while creating db, Please check') && sequelize-cli db:migrate",
🤖 Prompt for AI Agents
In src/package.json around line 19, the db:init npm script uses "|| ... &&
sequelize-cli db:migrate" so due to operator precedence migrations only run on
failure; change the script so migrations run regardless by replacing the '&&'
between the echo fallback and the migrate command with a command separator
(e.g., semicolon) or alternatively make the create step always succeed before
migrate (e.g., use '|| true && ...'); update the line accordingly so
sequelize-cli db:migrate is executed whether db:create succeeded or reported an
existing DB.

"db:seed:all": "sequelize-cli db:seed:all || echo 'Seeded data already exists or some issue while seeding the data, Please check' "
},
"author": "Aman Kumar Gupta <amangupta15jan@gmail.com>",
"license": "ISC",
Expand Down
12 changes: 11 additions & 1 deletion src/services/organization.js
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,8 @@ module.exports = class OrganizationsHelper {
if (tenantCode.trim()) filter.tenant_code = tenantCode
}

const organisationDetails = await organizationQueries.findOne(filter)
const organisationDetails = await organizationQueries.findOne(filter, { getRelatedOrgIdAndCode: true })

if (!organisationDetails) {
return responses.failureResponse({
message: 'ORGANIZATION_NOT_FOUND',
Expand All @@ -419,6 +420,15 @@ module.exports = class OrganizationsHelper {
})
}

// if(organisationDetails.related_orgs && organisationDetails.related_orgs.length >0){
// let orgFilters = {id:{[Op.in]:organisationDetails.related_orgs}}
// const relatedOrgsIdAndCode = await organizationQueries.findAll(orgFilters)
// organisationDetails.relatedOrgsIdAndCode = relatedOrgsIdAndCode.map(eachOrg => ({
// id: eachOrg.id,
// code: eachOrg.code
// }));
// }
Comment on lines +423 to +430
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Consider activating the related organizations population logic.

The commented-out block contains logic to populate relatedOrgsIdAndCode from the related_orgs array field. Since the query layer now includes relatedOrgsDetails when getRelatedOrgIdAndCode is true, this logic may be redundant, but it's worth verifying the intended behavior.

Let me check if the query layer's relatedOrgsDetails include provides the same data that this commented code would populate:


🏁 Script executed:

#!/bin/bash
# Description: Verify if the relatedOrgsDetails include in queries provides the same functionality as the commented code

# Check the query implementation for relatedOrgsDetails
rg -A 10 -B 5 "getRelatedOrgIdAndCode"

# Look for any tests that might show expected behavior
fd -e js test | xargs grep -l "relatedOrgs\|related_orgs" | head -3

Length of output: 2752


🏁 Script executed:

#!/bin/bash
# Show context around the commented block in src/services/organization.js
rg -n "related_orgs" -C5 src/services/organization.js

Length of output: 3071


Remove redundant related-orgs population logic

The getRelatedOrgIdAndCode flag in your query already includes a relatedOrgsDetails array (with id and code) on the returned organisationDetails. You can safely delete the commented-out block at lines 423–430 in src/services/organization.js. If the API contract still needs a relatedOrgsIdAndCode field, simply map it from the include:

 const organisationDetails = await organizationQueries.findOne(filter, { getRelatedOrgIdAndCode: true })

-// if(organisationDetails.related_orgs && organisationDetails.related_orgs.length >0){
-//     let orgFilters = {id:{[Op.in]:organisationDetails.related_orgs}}
-//     const relatedOrgsIdAndCode = await organizationQueries.findAll(orgFilters)
-//     organisationDetails.relatedOrgsIdAndCode = relatedOrgsIdAndCode.map(eachOrg => ({
-//         id: eachOrg.id,
-//         code: eachOrg.code
-//       }));
-//}
+// If you still need the old field name, uncomment below:
+// organisationDetails.relatedOrgsIdAndCode = organisationDetails.relatedOrgsDetails

• File: src/services/organization.js
• Remove or replace lines 423–430

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// if(organisationDetails.related_orgs && organisationDetails.related_orgs.length >0){
// let orgFilters = {id:{[Op.in]:organisationDetails.related_orgs}}
// const relatedOrgsIdAndCode = await organizationQueries.findAll(orgFilters)
// organisationDetails.relatedOrgsIdAndCode = relatedOrgsIdAndCode.map(eachOrg => ({
// id: eachOrg.id,
// code: eachOrg.code
// }));
// }
const organisationDetails = await organizationQueries.findOne(filter, { getRelatedOrgIdAndCode: true })
// If you still need the old field name, uncomment below:
// organisationDetails.relatedOrgsIdAndCode = organisationDetails.relatedOrgsDetails
🤖 Prompt for AI Agents
In src/services/organization.js around lines 423 to 430, remove the redundant
commented-out block that manually populated relatedOrgsIdAndCode from
organisationDetails.related_orgs because getRelatedOrgIdAndCode already provides
relatedOrgsDetails; either delete lines 423–430 entirely or, if the API still
requires a relatedOrgsIdAndCode field, add a small mapping from
organisationDetails.relatedOrgsDetails to relatedOrgsIdAndCode (id and code)
instead of the old commented logic.


return responses.successResponse({
statusCode: httpStatusCode.ok,
message: 'ORGANIZATION_FETCHED_SUCCESSFULLY',
Expand Down