From 444f909baca8116949152476ac6d6325d84833e6 Mon Sep 17 00:00:00 2001 From: Akhil Meka Date: Tue, 23 Sep 2025 11:35:43 +0530 Subject: [PATCH] fix: bugs in taggedUsers filter --- src/notification/notification.service.ts | 41 +++++-------------- src/pagination.ts | 50 +++++++++++++++++++++++- src/permit/permit.service.ts | 41 +++++-------------- src/processed/processed.service.ts | 41 +++++-------------- src/rts/rts.service.ts | 41 +++++-------------- src/task/task.service.ts | 41 +++++-------------- src/utils/queryParser.ts | 2 +- 7 files changed, 100 insertions(+), 157 deletions(-) diff --git a/src/notification/notification.service.ts b/src/notification/notification.service.ts index 6a84504..8366e8b 100644 --- a/src/notification/notification.service.ts +++ b/src/notification/notification.service.ts @@ -1,7 +1,12 @@ import mongoose from "mongoose"; import { AuthenticatedUser } from "../auth"; import { orgModel } from "../organization/organization.schema"; -import { getFilterObject, getSortObject, PageQueryParams } from "../pagination"; +import { + getFilterObject, + getSortObject, + getTaggedUsersFilter, + PageQueryParams, +} from "../pagination"; import { userModel } from "../user/user.schema"; import { generateId } from "../utils/id"; import { @@ -125,38 +130,12 @@ export async function listNotifications( filterObj.push({ client: new mongoose.Types.ObjectId(user.orgId) }); } - const taggedUserFilterIndex = filterObj.findIndex((item) => - Object.keys(item).includes("taggedUsers") + let { taggedFilter, taggedUserFilterIndex } = getTaggedUsersFilter( + filterObj, + sortObj ); - let taggedFilter = []; - if (taggedUserFilterIndex != -1) { - const filterItem = filterObj[taggedUserFilterIndex].taggedUsers; - let filterValues = null; - - if (filterItem["$eq"]) filterValues = [filterItem["$eq"]]; - else filterValues = filterItem["$in"]; - - filterValues = filterValues.map((item) => item.toString()); - - taggedFilter = [ - { - $addFields: { - taggedUsers: { - $filter: { - input: "$taggedUsers", - as: "user", - cond: { $in: ["$$user.userId", filterValues] }, - }, - }, - }, - }, - { $match: { "taggedUsers.0": { $exists: true } } }, - { $sort: { "taggedUsers.taggedAt": sortObj.taggedUsers ?? -1 } }, - ]; - - filterObj.splice(taggedUserFilterIndex, 1); - } + if (taggedUserFilterIndex != -1) filterObj.splice(taggedUserFilterIndex, 1); const pipeline: any = [ { diff --git a/src/pagination.ts b/src/pagination.ts index 0248969..b4197c4 100644 --- a/src/pagination.ts +++ b/src/pagination.ts @@ -1,5 +1,5 @@ import { z } from "zod"; -import { parse } from "./utils/queryParser"; +import { MongoFilter, parse } from "./utils/queryParser"; export const pageMetadata = z.object({ count: z.number(), @@ -46,3 +46,51 @@ export function getFilterObject(params: PageQueryParams) { return parsedQuery; } } + +export function getTaggedUsersFilter( + filterObj: MongoFilter[], + sortObj: Record +) { + const taggedUserFilterIndex = filterObj.findIndex((item) => + Object.keys(item).includes("taggedUsers") + ); + + let taggedFilter = []; + if (taggedUserFilterIndex != -1) { + const filterItem = filterObj[taggedUserFilterIndex].taggedUsers; + let filterValues = null; + + let notFlag = false; + if (filterItem["$eq"]) { + filterValues = [filterItem["$eq"]]; + } else if (filterItem["$ne"]) { + filterValues = [filterItem["$ne"]]; + notFlag = true; + } else if (filterItem["$in"]) { + filterValues = filterItem["$in"]; + } else { + filterValues = filterItem["$nin"]; + notFlag = true; + } + + const condition = notFlag ? { $exists: false } : { $exists: true }; + + taggedFilter = [ + { + $addFields: { + taggedUsersFilter: { + $filter: { + input: "$taggedUsers", + as: "user", + cond: { $in: ["$$user.userId", filterValues] }, + }, + }, + }, + }, + { $match: { "taggedUsersFilter.0": condition } }, + { $sort: { "taggedUsersFilter.taggedAt": sortObj.taggedUsers ?? -1 } }, + ]; + } + + return { taggedFilter, taggedUserFilterIndex }; +} diff --git a/src/permit/permit.service.ts b/src/permit/permit.service.ts index e82ca08..33563a6 100644 --- a/src/permit/permit.service.ts +++ b/src/permit/permit.service.ts @@ -1,4 +1,9 @@ -import { getFilterObject, getSortObject, PageQueryParams } from "../pagination"; +import { + getFilterObject, + getSortObject, + getTaggedUsersFilter, + PageQueryParams, +} from "../pagination"; import { generateId } from "../utils/id"; import { CreatePermitInput, @@ -72,38 +77,12 @@ export async function listPermits( filterObj.push({ client: new mongoose.Types.ObjectId(user.orgId) }); } - const taggedUserFilterIndex = filterObj.findIndex((item) => - Object.keys(item).includes("taggedUsers") + let { taggedFilter, taggedUserFilterIndex } = getTaggedUsersFilter( + filterObj, + sortObj ); - let taggedFilter = []; - if (taggedUserFilterIndex != -1) { - const filterItem = filterObj[taggedUserFilterIndex].taggedUsers; - let filterValues = null; - - if (filterItem["$eq"]) filterValues = [filterItem["$eq"]]; - else filterValues = filterItem["$in"]; - - filterValues = filterValues.map((item) => item.toString()); - - taggedFilter = [ - { - $addFields: { - taggedUsers: { - $filter: { - input: "$taggedUsers", - as: "user", - cond: { $in: ["$$user.userId", filterValues] }, - }, - }, - }, - }, - { $match: { "taggedUsers.0": { $exists: true } } }, - { $sort: { "taggedUsers.taggedAt": sortObj.taggedUsers ?? -1 } }, - ]; - - filterObj.splice(taggedUserFilterIndex, 1); - } + if (taggedUserFilterIndex != -1) filterObj.splice(taggedUserFilterIndex, 1); const permitsList = await permitModel.aggregate([ { diff --git a/src/processed/processed.service.ts b/src/processed/processed.service.ts index f15ec87..a75c47e 100644 --- a/src/processed/processed.service.ts +++ b/src/processed/processed.service.ts @@ -1,6 +1,11 @@ import mongoose from "mongoose"; import { AuthenticatedUser } from "../auth"; -import { getFilterObject, getSortObject, PageQueryParams } from "../pagination"; +import { + getFilterObject, + getSortObject, + getTaggedUsersFilter, + PageQueryParams, +} from "../pagination"; import { processedFields, processedModel, @@ -86,38 +91,12 @@ export async function listProcessedPermits( filterObj.push({ client: new mongoose.Types.ObjectId(user.orgId) }); } - const taggedUserFilterIndex = filterObj.findIndex((item) => - Object.keys(item).includes("taggedUsers") + let { taggedFilter, taggedUserFilterIndex } = getTaggedUsersFilter( + filterObj, + sortObj ); - let taggedFilter = []; - if (taggedUserFilterIndex != -1) { - const filterItem = filterObj[taggedUserFilterIndex].taggedUsers; - let filterValues = null; - - if (filterItem["$eq"]) filterValues = [filterItem["$eq"]]; - else filterValues = filterItem["$in"]; - - filterValues = filterValues.map((item) => item.toString()); - - taggedFilter = [ - { - $addFields: { - taggedUsers: { - $filter: { - input: "$taggedUsers", - as: "user", - cond: { $in: ["$$user.userId", filterValues] }, - }, - }, - }, - }, - { $match: { "taggedUsers.0": { $exists: true } } }, - { $sort: { "taggedUsers.taggedAt": sortObj.taggedUsers ?? -1 } }, - ]; - - filterObj.splice(taggedUserFilterIndex, 1); - } + if (taggedUserFilterIndex != -1) filterObj.splice(taggedUserFilterIndex, 1); const pipeline: any = [ { diff --git a/src/rts/rts.service.ts b/src/rts/rts.service.ts index ec2fb6a..22f9584 100644 --- a/src/rts/rts.service.ts +++ b/src/rts/rts.service.ts @@ -7,7 +7,12 @@ import { } from "./rts.schema"; import { AuthenticatedUser } from "../auth"; import { generateId } from "../utils/id"; -import { getFilterObject, getSortObject, PageQueryParams } from "../pagination"; +import { + getFilterObject, + getSortObject, + getTaggedUsersFilter, + PageQueryParams, +} from "../pagination"; import { getUserWithoutPopulate } from "../user/user.service"; import mongoose from "mongoose"; import { rtsPipeline } from "../utils/pipeline"; @@ -79,38 +84,12 @@ export async function listRts( filterObj.push({ client: new mongoose.Types.ObjectId(user.orgId) }); } - const taggedUserFilterIndex = filterObj.findIndex((item) => - Object.keys(item).includes("taggedUsers") + let { taggedFilter, taggedUserFilterIndex } = getTaggedUsersFilter( + filterObj, + sortObj ); - let taggedFilter = []; - if (taggedUserFilterIndex != -1) { - const filterItem = filterObj[taggedUserFilterIndex].taggedUsers; - let filterValues = null; - - if (filterItem["$eq"]) filterValues = [filterItem["$eq"]]; - else filterValues = filterItem["$in"]; - - filterValues = filterValues.map((item) => item.toString()); - - taggedFilter = [ - { - $addFields: { - taggedUsers: { - $filter: { - input: "$taggedUsers", - as: "user", - cond: { $in: ["$$user.userId", filterValues] }, - }, - }, - }, - }, - { $match: { "taggedUsers.0": { $exists: true } } }, - { $sort: { "taggedUsers.taggedAt": sortObj.taggedUsers ?? -1 } }, - ]; - - filterObj.splice(taggedUserFilterIndex, 1); - } + if (taggedUserFilterIndex != -1) filterObj.splice(taggedUserFilterIndex, 1); const rtsList = await rtsModel.aggregate([ { diff --git a/src/task/task.service.ts b/src/task/task.service.ts index 821a0ba..b63a2b3 100644 --- a/src/task/task.service.ts +++ b/src/task/task.service.ts @@ -1,7 +1,12 @@ import { createAlert } from "../alert/alert.service"; import { AuthenticatedUser } from "../auth"; import { createNote } from "../note/note.service"; -import { getFilterObject, getSortObject, PageQueryParams } from "../pagination"; +import { + getFilterObject, + getSortObject, + getTaggedUsersFilter, + PageQueryParams, +} from "../pagination"; import { generateId } from "../utils/id"; import { taskPipeline } from "../utils/pipeline"; import { @@ -90,38 +95,12 @@ export async function listTasks( const sortObj = getSortObject(params, taskFields); let filterObj = getFilterObject(params) || []; - const taggedUserFilterIndex = filterObj.findIndex((item) => - Object.keys(item).includes("taggedUsers") + let { taggedFilter, taggedUserFilterIndex } = getTaggedUsersFilter( + filterObj, + sortObj ); - let taggedFilter = []; - if (taggedUserFilterIndex != -1) { - const filterItem = filterObj[taggedUserFilterIndex].taggedUsers; - let filterValues = null; - - if (filterItem["$eq"]) filterValues = [filterItem["$eq"]]; - else filterValues = filterItem["$in"]; - - filterValues = filterValues.map((item) => item.toString()); - - taggedFilter = [ - { - $addFields: { - taggedUsers: { - $filter: { - input: "$taggedUsers", - as: "user", - cond: { $in: ["$$user.userId", filterValues] }, - }, - }, - }, - }, - { $match: { "taggedUsers.0": { $exists: true } } }, - { $sort: { "taggedUsers.taggedAt": sortObj.taggedUsers ?? -1 } }, - ]; - - filterObj.splice(taggedUserFilterIndex, 1); - } + if (taggedUserFilterIndex != -1) filterObj.splice(taggedUserFilterIndex, 1); const taskList = await taskModel.aggregate([ { diff --git a/src/utils/queryParser.ts b/src/utils/queryParser.ts index f28f3e0..139fd3b 100644 --- a/src/utils/queryParser.ts +++ b/src/utils/queryParser.ts @@ -1,6 +1,6 @@ import mongoose from "mongoose"; -type MongoFilter = Record; +export type MongoFilter = Record; const objectIdConversion = ["taggedUsers"];