From 3588c3cfa4013a1b04a02b8e37a7e3adb1a08842 Mon Sep 17 00:00:00 2001 From: MallanagoudaB Date: Wed, 18 Sep 2024 13:06:36 +0530 Subject: [PATCH 1/6] "added-validation" --- src/databaseQueries/entityTypes.js | 9 --------- src/module/entities/helper.js | 7 ++++++- src/module/userRoleExtension/helper.js | 19 +++++++++++++++++++ 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/databaseQueries/entityTypes.js b/src/databaseQueries/entityTypes.js index 5578273..83a0284 100644 --- a/src/databaseQueries/entityTypes.js +++ b/src/databaseQueries/entityTypes.js @@ -82,7 +82,6 @@ module.exports = class EntityTypes { }) } - /** * find entityType documents. * @method @@ -119,12 +118,6 @@ module.exports = class EntityTypes { // Find one document matching the queryObject with specified projection and return as plain JavaScript object let document = await database.models.entityTypes.findOne(queryObject, projection).lean() - if (!document) { - return reject({ - status: 404, - message: CONSTANTS.apiResponses.DOCUMENT_NOT_FOUND, - }) - } return resolve(document) } catch (error) { @@ -137,8 +130,6 @@ module.exports = class EntityTypes { }) } - - /** * Update entityTypes documents. * @method diff --git a/src/module/entities/helper.js b/src/module/entities/helper.js index 651cc31..b56da1c 100644 --- a/src/module/entities/helper.js +++ b/src/module/entities/helper.js @@ -605,7 +605,12 @@ module.exports = class UserProjectsHelper { toBeMappedToParentEntities: 1, } ) - + if (!checkParentEntitiesMappedValue) { + return reject({ + status: HTTP_STATUS_CODE.bad_request.status, + message: CONSTANTS.apiResponses.DOCUMENT_NOT_FOUND, + }) + } // Update entityTypeMap with the updateParentHierarchy status if (checkParentEntitiesMappedValue.toBeMappedToParentEntities) { updateParentHierarchy = true diff --git a/src/module/userRoleExtension/helper.js b/src/module/userRoleExtension/helper.js index 72538b6..ad94c20 100644 --- a/src/module/userRoleExtension/helper.js +++ b/src/module/userRoleExtension/helper.js @@ -9,6 +9,7 @@ const { result } = require('lodash') // Dependencies const userRoleExtensionQueries = require(DB_QUERY_BASE_PATH + '/userRoleExtension') +const entityTypeQueries = require(DB_QUERY_BASE_PATH + '/entityTypes') module.exports = class userRoleExtensionHelper { /** @@ -19,6 +20,24 @@ module.exports = class userRoleExtensionHelper { static create(body) { return new Promise(async (resolve, reject) => { try { + // Using map to handle validation + await Promise.all( + body.entityTypes.map(async (entityTypeData) => { + // Validate that both entityType and entityTypeId exist in the entityType DB + let existingEntityType = await entityTypeQueries.findOne({ + name: entityTypeData.entityType, + _id: ObjectId(entityTypeData.entityTypeId), + }) + + if (!existingEntityType) { + // If any entityType is invalid, reject the request + throw { + status: HTTP_STATUS_CODE.bad_request.status, + message: `EntityType '${entityTypeData.entityType}' with ID '${entityTypeData.entityTypeId}' does not exist.`, + } + } + }) + ) // Call the queries function to create a new user role extension with the provided body data let newUserRole = await userRoleExtensionQueries.create(body) From b02080f264e60a868acab37d43bebbabb51015cf Mon Sep 17 00:00:00 2001 From: MallanagoudaB Date: Wed, 18 Sep 2024 13:39:47 +0530 Subject: [PATCH 2/6] "added-validations" --- src/databaseQueries/entities.js | 6 ------ src/module/entities/helper.js | 17 +++++++++++++++-- src/module/entities/validator/v1.js | 8 ++++++-- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/databaseQueries/entities.js b/src/databaseQueries/entities.js index 2059b34..4d0816d 100644 --- a/src/databaseQueries/entities.js +++ b/src/databaseQueries/entities.js @@ -134,12 +134,6 @@ module.exports = class entities { // Find one document matching the queryObject with specified projection and return as plain JavaScript object let document = await database.models.entities.findOne(queryObject, projection).lean() - if (!document) { - return reject({ - status: 404, - message: CONSTANTS.apiResponses.DOCUMENT_NOT_FOUND, - }) - } return resolve(document) } catch (error) { diff --git a/src/module/entities/helper.js b/src/module/entities/helper.js index 651cc31..aad432e 100644 --- a/src/module/entities/helper.js +++ b/src/module/entities/helper.js @@ -512,7 +512,12 @@ module.exports = class UserProjectsHelper { childHierarchyPath: 1, } ) - + if (!childEntity) { + return reject({ + status: 404, + message: CONSTANTS.apiResponses.DOCUMENT_NOT_FOUND, + }) + } if (childEntity.entityType) { let parentEntityQueryObject = { _id: ObjectId(parentEntityId), @@ -1027,7 +1032,15 @@ module.exports = class UserProjectsHelper { for (let pointer = 0; pointer < dataArray.length; pointer++) { let singleEntity = dataArray[pointer] - + // Check if an entity with the same name exists in the database + let existingEntity = await entitiesQueries.findOne({ 'metaInformation.name': singleEntity.name }) + if (existingEntity) { + // Throw 400 error if the name already exists + return reject({ + status: HTTP_STATUS_CODE.bad_request.status, + message: `Entity with name '${singleEntity.name}' already exists.`, + }) + } if (singleEntity.createdByProgramId) { singleEntity.createdByProgramId = ObjectId(singleEntity.createdByProgramId) } diff --git a/src/module/entities/validator/v1.js b/src/module/entities/validator/v1.js index 0d851cf..9b33f3b 100644 --- a/src/module/entities/validator/v1.js +++ b/src/module/entities/validator/v1.js @@ -9,9 +9,13 @@ module.exports = (req) => { let entitiesValidator = { add: function () { req.checkQuery('type').exists().withMessage('required type') - req.checkBody('entityTypeId').exists().withMessage('required entityTypeId ') req.checkBody('externalId').exists().withMessage('required externalId ') - req.checkBody('name').exists().withMessage('required name ') + req.checkBody('name') + .exists() + .withMessage('The name field is required.') + .trim() // Removes leading and trailing spaces + .notEmpty() + .withMessage('The name field cannot be empty.') }, update: function () { req.checkParams('_id').exists().withMessage('required _id') From 64d71789c19bbc82d8764fc2663b72664446d45c Mon Sep 17 00:00:00 2001 From: MallanagoudaB Date: Wed, 18 Sep 2024 15:43:17 +0530 Subject: [PATCH 3/6] "Updated-DOC" --- src/api-doc/api-doc.yaml | 110 +++++++++++++++++++++++++-------------- 1 file changed, 70 insertions(+), 40 deletions(-) diff --git a/src/api-doc/api-doc.yaml b/src/api-doc/api-doc.yaml index 16bf406..f1b5bbb 100644 --- a/src/api-doc/api-doc.yaml +++ b/src/api-doc/api-doc.yaml @@ -975,8 +975,6 @@ paths: schema: type: object properties: - entityTypeId: - type: string externalId: type: string entityType: @@ -992,7 +990,6 @@ paths: examples: sampleBodyData: value: - entityTypeId: 663335e2a766490014aead0a externalId: entity123 childHierarchyPath: - district @@ -1193,23 +1190,25 @@ paths: examples: SuccessResponse: value: - message: ASSETS_FETCHED_SUCCESSFULLY + message: ENTITY_UPDATATED status: 200 result: metaInformation: - externalId: entity123 + externalId: SCH + name: school + registryDetails: + locationId: rajAPSTATEDummy4 + code: rajAPSTATEDummy4 childHierarchyPath: [] - allowedRoles: - - role1 - - role2 + allowedRoles: [] createdBy: user123 updatedBy: user123 deleted: false - _id: 662f856a4b41910591c2fde9 - entityTypeId: 627a13928ce12806f5803f57 - entityType: block - updatedAt: '2024-04-30T13:16:23.597Z' - createdAt: '2024-04-29T11:32:58.439Z' + _id: 66ea64fa68cd063346a10365 + entityTypeId: 6672ce0fc05aa58f89ba12f1 + entityType: state + updatedAt: '2024-09-18T10:07:39.407Z' + createdAt: '2024-09-18T05:28:26.148Z' __v: 0 '400': description: Bad Request. @@ -1233,18 +1232,14 @@ paths: schema: type: object properties: - externalId: + metaInformation.externalId: type: string - name: + metaInformation.name: type: string childHierarchyPath: type: array items: type: string - allowedRoles: - type: array - items: - type: string createdBy: type: string updatedBy: @@ -1252,12 +1247,9 @@ paths: examples: sampleBodyData: value: - externalId: entity123 - name: ' school' + metaInformation.externalId: SCH + metaInformation.name: school childHierarchyPath: [] - allowedRoles: - - role1 - - role2 createdBy: user123 updatedBy: user123 /v1/entities/mappingUpload: @@ -1495,9 +1487,11 @@ paths: sampleBodyData: value: query: - metaInformation.externalId: PBS + metaInformation.externalId: rajAP projection: - - _id + - metaInformation.externalId + - metaInformation.name + - registryDetails.locationId responses: '200': description: created @@ -1517,16 +1511,30 @@ paths: properties: _id: type: string - required: - - _id + registryDetails: + type: object + properties: + locationId: + type: string + metaInformation: + type: object + properties: + externalId: + type: string + name: + type: string examples: SuccessResponse: value: message: ASSETS_FETCHED_SUCCESSFULLY status: 200 result: - - _id: 6613b8142c7d9408449474bf - - _id: 6613b8f32c7d9408449474c2 + - _id: 66e2b4bd7165395fcea49814 + registryDetails: + locationId: rajAP + metaInformation: + externalId: rajAP + name: RAJANDHRA '400': description: Bad Request. content: @@ -2100,7 +2108,7 @@ paths: param: _id msg: required _id /v1/entities/listByIds: - get: + post: summary: List the entities based on entity id tags: - entities-API's @@ -2169,6 +2177,28 @@ paths: - location: body param: entities msg: required entities + requestBody: + description: '' + content: + application/json: + schema: + type: object + properties: + entities: + type: array + items: + type: string + fields: + type: array + items: + type: string + examples: + sampleBodyData: + value: + entities: + - 66738b75c05aa58f89ba1300 + fields: + - entityType /v1/entities/entityListBasedOnEntityType?entityType={entity_Type}: get: summary: List all the entities based on entity type. @@ -2361,7 +2391,7 @@ paths: * Mandatory parameter cannot be empty or null operationId: '' - tags: &ref_9 + tags: &ref_10 - userRoleExtension-API's parameters: - in: header @@ -2369,7 +2399,7 @@ paths: description: >- You require an X-auth-token to use this API. This token is available in the login API Response. - schema: &ref_10 + schema: &ref_11 type: string required: false requestBody: @@ -2530,14 +2560,14 @@ paths: * Mandatory parameter cannot be empty or null operationId: '' - tags: *ref_9 + tags: *ref_10 parameters: - in: header name: X-auth-token description: >- You require an X-auth-token to use this API. This token is available in the login API Response. - schema: *ref_10 + schema: *ref_11 required: false requestBody: content: @@ -2667,19 +2697,19 @@ paths: * Mandatory parameter cannot be empty or null operationId: '' - tags: *ref_9 + tags: *ref_10 parameters: - in: header name: X-auth-token description: >- You require an X-auth-token to use this API. This token is available in the login API Response. - schema: *ref_10 + schema: *ref_11 required: false - in: header name: internal-access-token description: '' - schema: &ref_15 + schema: type: string required: true requestBody: @@ -2783,14 +2813,14 @@ paths: * Mandatory parameter cannot be empty or null operationId: '' - tags: *ref_9 + tags: *ref_10 parameters: - in: header name: X-auth-token description: >- You require an X-auth-token to use this API. This token is available in the login API Response. - schema: *ref_10 + schema: *ref_11 required: true responses: '200': From 57b032a229a04758b4af48b6b40fc837f6559146 Mon Sep 17 00:00:00 2001 From: MallanagoudaB Date: Mon, 23 Sep 2024 09:48:13 +0530 Subject: [PATCH 4/6] "added_status" --- src/module/entities/helper.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/module/entities/helper.js b/src/module/entities/helper.js index aad432e..05b8f20 100644 --- a/src/module/entities/helper.js +++ b/src/module/entities/helper.js @@ -514,7 +514,7 @@ module.exports = class UserProjectsHelper { ) if (!childEntity) { return reject({ - status: 404, + status: HTTP_STATUS_CODE.not_found.status, message: CONSTANTS.apiResponses.DOCUMENT_NOT_FOUND, }) } From 055d550cbc3426f96ce88cb4963b462d6dc5717e Mon Sep 17 00:00:00 2001 From: MallanagoudaB Date: Mon, 23 Sep 2024 17:41:45 +0530 Subject: [PATCH 5/6] "readME-entity-management" --- README.md | 250 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 247 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ba78c7d..e885ac2 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,247 @@ -# elevate-entity-service -Elevate entity service -# entity-management +
+ +# Entity Management + + + + + +[![CircleCI](https://dl.circleci.com/status-badge/img/gh/ELEVATE-Project/notification/tree/master.svg?style=shield)](https://dl.circleci.com/status-badge/redirect/gh/ELEVATE-Project/notification/tree/master) +[![Duplicated Lines (%)](https://sonarcloud.io/api/project_badges/measure?project=ELEVATE-Project_notification&metric=duplicated_lines_density)](https://sonarcloud.io/summary/new_code?id=ELEVATE-Project_notification) +[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=ELEVATE-Project_notification&metric=coverage)](https://sonarcloud.io/summary/new_code?id=ELEVATE-Project_notification) +[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=ELEVATE-Project_notification&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=ELEVATE-Project_notification) +[![Prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://prettier.io) +[![Docs](https://img.shields.io/badge/Docs-success-informational)](https://elevate-docs.shikshalokam.org/mentorEd/intro) +[![Docs](https://img.shields.io/badge/API-docs-informational)](https://dev.elevate-apis.shikshalokam.org/notification/api-doc) +![GitHub package.json version (subfolder of monorepo)](https://img.shields.io/github/package-json/v/ELEVATE-Project/notification?filename=src%2Fpackage.json) +[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT) + +
CircleCI insights + +[![CircleCI](https://dl.circleci.com/insights-snapshot/gh/ELEVATE-Project/notification/master/buil-and-test/badge.svg?window=30d)](https://app.circleci.com/insights/github/ELEVATE-Project/notification/workflows/buil-and-test/overview?branch=master&reporting-window=last-30-days&insights-snapshot=true) + +
+ + +
+This Service enables the creation and management of various entities and entityType .It + provides functionalities for entities, ensuring seamless integration and + maintenance of entity-related data across the platform. +
+ +
+ +# System Requirements + +- **Operating System:** Ubuntu 22 +- **Node.js:** v20 +- **mongoDb:** v4 + +# Setup Options + +Elevate entity-management services can be setup in local using two methods: + +
Dockerized service with local dependencies(Intermediate) + +## A. Dockerized Service With Local Dependencies + +**Expectation**: Run single docker containerized service with existing local (in host) or remote dependencies. + +### Local Dependencies Steps + +1. Build the docker image. + ``` + /ELEVATE/entity-management$ docker build -t elevate/entity-management:1.0 . + ``` +2. Run the docker container. + + - For Mac & Windows with docker v18.03+: + + ``` + $ docker run --name entity-management elevate/entity-management:1.0 + ``` + + - For Linux: + ``` + $ docker run --name entity-management --add-host=host.docker.internal:host-gateway elevate/entity-management:1.0` + ``` + Refer [this](https://stackoverflow.com/a/24326540) for more information. + +### Remote Dependencies Steps + +1. Build the docker image. + ``` + /ELEVATE/entity-management$ docker build -t elevate/entity-management:1.0 . + ``` +2. Run the docker container. + + ``` + $ docker run --name entity-management elevate/entity-management:1.0 + ``` + +
+ +
Local Service with local dependencies(Hardest) + +## B. Local Service With Local Dependencies + +**Expectation**: Run single service with existing local dependencies in host (**Non-Docker Implementation**). + +## Installations + +### Install Node.js LTS + +Refer to the [NodeSource distributions installation scripts](https://github.com/nodesource/distributions#installation-scripts) for Node.js installation. + +```bash +$ curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash - &&\ +sudo apt-get install -y nodejs +``` + +### Install PM2 + +Refer to [How To Set Up a Node.js Application for Production on Ubuntu 22.04](https://www.digitalocean.com/community/tutorials/how-to-set-up-a-node-js-application-for-production-on-ubuntu-22-04). + +**Run the following command** + +```bash +$ sudo npm install pm2@latest -g +``` + +## Setting up Repository + +### Clone the entity-management repository to /opt/backend directory + +```bash +opt/backend$ git clone -b develop-2.5 --single-branch "https://github.com/ELEVATE-Project/entity-management" +``` + +### Install Npm packages from src directory + +```bash +backend/entity-management/src$ sudo npm i +``` + +### Create .env file in src directory + +```bash +entity-management/src$ sudo nano .env +``` + +Copy-paste the following env variables to the `.env` file: + +```env +# entity-management Service Config + +# Port on which service runs +APPLICATION_PORT=5001 + +# Application environment +APPLICATION_ENV=development + +# Route after the base URL +APPLICATION_BASE_URL=/entity/ + +# Api doc URL +API_DOC_URL= "https://project-dev.elevate-apis.shikshalokam.org/entity-management/api-doc" + +#User service URL +USER_SERVICE_URL = http://localhost:3001/user + + +INTERNAL_ACCESS_TOKEN="internal_access_token" + +#DB URL +MONGODB_URL=mongodb://localhost:27017/elevate-entity-management + +#service name +SERVICE_NAME = elevate-entity-service + +version=8 +``` + +Save and exit. + +## Setting up Databases + +**Start MongoDB Service** + +```bash +sudo systemctl start mongod +``` + +**Verify MongoDB is running** + +```bash +sudo systemctl status mongod + +``` + +## Start the Service + +Navigate to the src folder of entity-management service and run pm2 start command: + +```bash +entity-management/src$ pm2 start app.js -i 2 --name elevate-entity-management +``` + +#### Run pm2 ls command + +```bash +$ pm2 ls +``` + +
+ +
+ +# Run tests + +## Integration tests + +``` +npm run test:integration +``` + +To know more about integration tests and their implementation refer to the project [Wiki](https://github.com/ELEVATE-Project/user/wiki/Integration-and-Unit-testing). + +## Unit tests + +``` +npm test +``` + +# Used in + +This project was built to be used with [Project Service](https://github.com/ELEVATE-Project/project-service) and [User Service](https://github.com/ELEVATE-Project/user.git). + +The frontend/mobile application [repo](https://github.com/ELEVATE-Project/observation-survey-projects-pwa). + +You can learn more about the full implementation of project-service [here](https://elevate-docs.shikshalokam.org/.project/intro) . + +# Team + + + + + +
+ +# Open Source Dependencies + +Several open source dependencies that have aided Mentoring's 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) +![Git](https://img.shields.io/badge/git-%23F05033.svg?style=for-the-badge&logo=git&logoColor=white) From 2d14391fe80769f0d0c1457c7077b08cf6a26c17 Mon Sep 17 00:00:00 2001 From: MallanagoudaB Date: Tue, 24 Sep 2024 14:43:52 +0530 Subject: [PATCH 6/6] "added-docker-functionality" --- README.md | 21 ++++++++------------- docker-compose.yml | 37 ++++++++++++------------------------- 2 files changed, 20 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index e885ac2..cca11f0 100644 --- a/README.md +++ b/README.md @@ -60,34 +60,29 @@ Elevate entity-management services can be setup in local using two methods: ### Local Dependencies Steps -1. Build the docker image. - ``` - /ELEVATE/entity-management$ docker build -t elevate/entity-management:1.0 . - ``` + +1. **Download Docker Compose File:** Retrieve the **[docker-compose.yml](https://raw.githubusercontent.com/ELEVATE-Project/entity-management/refs/heads/develop/docker-compose.yml)** file from the entity-management service repository and save it to the entity-management directory. + 2. Run the docker container. - For Mac & Windows with docker v18.03+: ``` - $ docker run --name entity-management elevate/entity-management:1.0 + $ docker run --name entity-management shikshalokamqa/elevate-entity-management:1.0.0 ``` - For Linux: ``` - $ docker run --name entity-management --add-host=host.docker.internal:host-gateway elevate/entity-management:1.0` + $ docker run --name entity-management --add-host=host.docker.internal:host-gateway shikshalokamqa/elevate-entity-management:1.0.0` ``` Refer [this](https://stackoverflow.com/a/24326540) for more information. ### Remote Dependencies Steps -1. Build the docker image. - ``` - /ELEVATE/entity-management$ docker build -t elevate/entity-management:1.0 . - ``` -2. Run the docker container. +1. Run the docker container. ``` - $ docker run --name entity-management elevate/entity-management:1.0 + $ docker run --name entity-management shikshalokamqa/elevate-entity-management:1.0.0 ``` @@ -163,7 +158,7 @@ USER_SERVICE_URL = http://localhost:3001/user INTERNAL_ACCESS_TOKEN="internal_access_token" #DB URL -MONGODB_URL=mongodb://localhost:27017/elevate-entity-management +MONGODB_URL=mongodb://mongo:27017/elevate-entity-management #service name SERVICE_NAME = elevate-entity-service diff --git a/docker-compose.yml b/docker-compose.yml index e14117e..7edb5db 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,46 +1,33 @@ version: '3' services: mongo: - image: 'mongo:4.1.4' - container_name: mongo + image: 'mongo:4.4.14' restart: 'always' - command: - - '--logpath' - - '/var/log/mongodb/mongod.log' ports: - '27017:27017' networks: - - elevate_net - volumes: - - mongo-data:/data/db - - logs:/var/log/mongodb - redis: - image: 'redis:7.0.0' - container_name: redis - restart: 'always' - ports: - - '6379:6379' - networks: - - elevate_net + - entity_net + # volumes: + # - mongo-data:/data/db logging: driver: none - entity-mangement: - build: './' - container_name: entity-management - volumes: - - ./src/:/var/src + entity_management: + image: shikshalokamqa/elevate-entity-management:1.0.0 ports: - '5001:5001' command: ['nodemon', 'app.js'] environment: - - MONGODB_URL=mongodb://mongo:27017/elevate-diksha + - MONGO_URL=mongo:27017 + env_file: + - src/.env depends_on: - mongo networks: - - elevate_net + - entity_net networks: - elevate_net: + entity_net: + # external: false volumes: mongo-data: logs: