Repository: UK-Export-Finance/dtfs2
Pull request #4270: feat(DTFS-7852): filter deals with amendment in progress only checker user
Author: login: rkontogianni
Created: 2025-03-20T14:15:33Z | Merged: 2025-03-29T08:54:07Z

## Introduction :pencil2:
This PR is about to get all amendements with status Ready for Checker's Approval and filter allDeals in the application and notices page for Checker user only

## Resolution :heavy_check_mark:
- Add DEALIDS_CHECKERS_APPROVAL_AMENDMENTS in libs common
- Add getAllAmendments layer in portal to get all amendments with submitted statuses
- Add getDealIdsCheckersApprovalAmendments function to transform allAmendments into an array of all ids with amendment in progress.
- Add in filtersQuery the DEALIDS_CHECKERS_APPROVAL_AMENDMENTS key
- Update escapeOperators file for DEALIDS_CHECKERS_APPROVAL_AMENDMENTS key
- Add unit tests
## Miscellaneous :heavy_plus_sign:
List any additional fixes or improvements.





Diff:
diff --git a/libs/common/src/constants/amendments.ts b/libs/common/src/constants/amendments.ts
index 6c230d51405..c2fee2b5c17 100644
--- a/libs/common/src/constants/amendments.ts
+++ b/libs/common/src/constants/amendments.ts
@@ -53,6 +53,8 @@ export const AMENDMENT_QUERIES = {
   LATEST: 'latest',
 } as const;
 
+export const CHECKERS_AMENDMENTS_DEAL_ID = 'checkersAmendmentDealId';
+
 export const AMENDMENT_TYPES = {
   PORTAL: 'PORTAL',
   TFM: 'TFM',
diff --git a/portal-api/src/v1/helpers/escapeOperators.js b/portal-api/src/v1/helpers/escapeOperators.js
index 97e723db57d..cbefe20b7e5 100644
--- a/portal-api/src/v1/helpers/escapeOperators.js
+++ b/portal-api/src/v1/helpers/escapeOperators.js
@@ -1,6 +1,7 @@
 /* eslint-disable no-param-reassign */
 const escapeStringRegexp = require('escape-string-regexp');
-const { FACILITY_STAGE } = require('@ukef/dtfs2-common');
+const { FACILITY_STAGE, CHECKERS_AMENDMENTS_DEAL_ID } = require('@ukef/dtfs2-common');
+const { ObjectId } = require('mongodb');
 
 /**
  * Objective:
@@ -60,13 +61,23 @@ const recursivelyReplaceEscapeOperators = (filters, result = {}) => {
     // This handles when there is an array -- ie in the case of AND and OR
     if (Array.isArray(filters[key])) {
       const newKeyName = getArrayKeyOperatorName(key);
-      if (!result[newKeyName]) {
-        result[newKeyName] = [];
+      /**
+       * This handles CHECKERS_AMENDMENTS_DEAL_ID  key
+       * When  key is present, transforms filter _id within the array of dealIds
+       */
+      if (newKeyName === CHECKERS_AMENDMENTS_DEAL_ID) {
+        result._id = { $in: filters[newKeyName].map((dealId) => new ObjectId(dealId)) };
+      } else {
+        if (!result[newKeyName]) {
+          result[newKeyName] = [];
+        }
+
+        filters[key].forEach((condition, i) => {
+          result[newKeyName][i] = {};
+          recursivelyReplaceEscapeOperators(condition, result[newKeyName][i]);
+        });
       }
-      filters[key].forEach((condition, i) => {
-        result[newKeyName][i] = {};
-        recursivelyReplaceEscapeOperators(condition, result[newKeyName][i]);
-      });
+
       // This handles nested objects ie {example: {REGEX: 'example'}}
     } else if (typeof filters[key] === 'object' && filters[key] !== null) {
       result[key] = {};
diff --git a/portal-api/src/v1/helpers/escapeOperators.test.js b/portal-api/src/v1/helpers/escapeOperators.test.js
index 5bcba79d136..38ac58a0796 100644
--- a/portal-api/src/v1/helpers/escapeOperators.test.js
+++ b/portal-api/src/v1/helpers/escapeOperators.test.js
@@ -1,4 +1,5 @@
-const { FACILITY_STAGE } = require('@ukef/dtfs2-common');
+const { FACILITY_STAGE, CHECKERS_AMENDMENTS_DEAL_ID } = require('@ukef/dtfs2-common');
+const { ObjectId } = require('mongodb');
 const CONSTANTS = require('../../constants');
 const { escapeOperators } = require('./escapeOperators');
 
@@ -233,6 +234,50 @@ describe('escapeOperators function', () => {
     expect(result).toEqual(expected);
   });
 
+  it(`should handle ${CHECKERS_AMENDMENTS_DEAL_ID} key inside OR operator`, () => {
+    // Arrange
+    const checkersApprovalAmendmentDealIds = ['123456789654', '123456789777'];
+    const filter = {
+      AND: [
+        {
+          'bank.id': '9',
+        },
+        {
+          OR: [
+            {
+              status: CONSTANTS.DEAL.DEAL_STATUS.READY_FOR_APPROVAL,
+            },
+            { [CHECKERS_AMENDMENTS_DEAL_ID]: checkersApprovalAmendmentDealIds },
+          ],
+        },
+      ],
+    };
+
+    // Act
+    const result = escapeOperators(filter);
+
+    // Assert
+    const expected = {
+      $and: [
+        {
+          'bank.id': { $eq: '9' },
+        },
+        {
+          $or: [
+            {
+              status: { $eq: CONSTANTS.DEAL.DEAL_STATUS.READY_FOR_APPROVAL },
+            },
+            {
+              _id: { $in: checkersApprovalAmendmentDealIds.map((dealId) => new ObjectId(dealId)) },
+            },
+          ],
+        },
+      ],
+    };
+
+    expect(result).toEqual(expected);
+  });
+
   it('should delete the AND operator key after escaping', () => {
     // Arrange
     const filter = { AND: [{ key: 'value' }] };
diff --git a/portal/server/api.js b/portal/server/api.js
index 6e7457396d1..74271eceb2b 100644
--- a/portal/server/api.js
+++ b/portal/server/api.js
@@ -142,6 +142,26 @@ const allFacilities = async (start, pagesize, filters, token, sort) => {
   return response.data;
 };
 
+/**
+ * @param {Object} param
+ * @param {import('@ukef/dtfs2-common').PortalAmendmentStatus[] | undefined} param.statuses
+ * @param {string} param.userToken
+ * @returns {Promise<(import('@ukef/dtfs2-common').PortalFacilityAmendmentWithUkefId[])>}>}
+ */
+const getAllAmendments = async ({ statuses, userToken }) => {
+  const response = await axios({
+    method: 'get',
+    url: `${PORTAL_API_URL}/v1/gef/facilities/amendments`,
+    headers: {
+      Authorization: userToken,
+      [HEADERS.CONTENT_TYPE.KEY]: HEADERS.CONTENT_TYPE.VALUES.JSON,
+    },
+    params: { statuses },
+  });
+
+  return response.data;
+};
+
 const createDeal = async (deal, token) => {
   const response = await axios({
     method: 'post',
@@ -1166,6 +1186,7 @@ const getCompletedFeeRecordCorrections = async (token, bankId) => {
 module.exports = {
   allDeals,
   allFacilities,
+  getAllAmendments,
   banks,
   cloneDeal,
   contractBond,
diff --git a/portal/server/api.test.js b/portal/server/api.test.js
index 6911ae76232..a49921d7da0 100644
--- a/portal/server/api.test.js
+++ b/portal/server/api.test.js
@@ -1,6 +1,6 @@
 const axios = require('axios');
 const { when } = require('jest-when');
-const { HEADERS, PORTAL_LOGIN_STATUS } = require('@ukef/dtfs2-common');
+const { HEADERS, PORTAL_LOGIN_STATUS, PORTAL_AMENDMENT_SUBMITTED_STATUSES } = require('@ukef/dtfs2-common');
 const api = require('./api');
 
 jest.mock('axios');
@@ -90,3 +90,57 @@ describe('api.loginWithSignInLink', () => {
     await expect(loginPromise).rejects.toEqual(error);
   });
 });
+
+describe('api.getAllAmendments', () => {
+  const userToken = 'test-token';
+  const mockResponseData = [
+    { dealId: 'deal1', amendmentId: 'amendment1' },
+    { dealId: 'deal2', amendmentId: 'amendment2' },
+  ];
+
+  it('should return all submitted amendments when the API call is successful', async () => {
+    when(axios)
+      .calledWith({
+        method: 'get',
+        url: `${PORTAL_API_URL}/v1/gef/facilities/amendments`,
+        headers: {
+          Authorization: userToken,
+          [HEADERS.CONTENT_TYPE.KEY]: HEADERS.CONTENT_TYPE.VALUES.JSON,
+        },
+        params: { statuses: PORTAL_AMENDMENT_SUBMITTED_STATUSES },
+      })
+      .mockResolvedValue({ data: mockResponseData });
+
+    const result = await api.getAllAmendments({ statuses: PORTAL_AMENDMENT_SUBMITTED_STATUSES, userToken });
+
+    expect(result).toEqual(mockResponseData);
+  });
+
+  it('should throw an error when the API call fails', async () => {
+    const error = new Error('API call failed');
+    axios.mockRejectedValueOnce(error);
+
+    const getAllAmendmentsPromise = api.getAllAmendments({ statuses: PORTAL_AMENDMENT_SUBMITTED_STATUSES, userToken });
+
+    await expect(getAllAmendmentsPromise).rejects.toThrow('API call failed');
+  });
+
+  it('should return all amendments when statuses are an empty array', async () => {
+    const emptyStatuses = [];
+    when(axios)
+      .calledWith({
+        method: 'get',
+        url: `${PORTAL_API_URL}/v1/gef/facilities/amendments`,
+        headers: {
+          Authorization: userToken,
+          [HEADERS.CONTENT_TYPE.KEY]: HEADERS.CONTENT_TYPE.VALUES.JSON,
+        },
+        params: { statuses: emptyStatuses },
+      })
+      .mockResolvedValue({ data: mockResponseData });
+
+    const result = await api.getAllAmendments({ statuses: emptyStatuses, userToken });
+
+    expect(result).toEqual(mockResponseData);
+  });
+});
diff --git a/portal/server/controllers/dashboard/deals/deals-filters-query.js b/portal/server/controllers/dashboard/deals/deals-filters-query.js
index cd124d57446..cb05e05d6d9 100644
--- a/portal/server/controllers/dashboard/deals/deals-filters-query.js
+++ b/portal/server/controllers/dashboard/deals/deals-filters-query.js
@@ -1,18 +1,19 @@
+const { CHECKERS_AMENDMENTS_DEAL_ID } = require('@ukef/dtfs2-common');
 const CONSTANTS = require('../../../constants');
 const CONTENT_STRINGS = require('../../../content-strings');
-const { getUserRoles, isSuperUser } = require('../../../helpers');
+const { getUserRoles, isSuperUser, getCheckersApprovalAmendmentDealIds } = require('../../../helpers');
 const keywordQuery = require('./deals-filters-keyword-query');
 
 /**
  * Generates an array of objects to be sent to API (for DB query)
  *
- * @param {string} createdByYou flag
  * @param {Array} custom filters
  * @param {Object} user
- * @example ( 'true', [ dealType: ['BSS/EWCS'] ], { _id: '123', firstName: 'Mock' } )
- * @returns { AND: [ { 'bank.id': '9'} ], OR: [{ dealType: 'BSS/EWCS' }] }
+ * @param {string} userToken
+ * @example ([ dealType: ['BSS/EWCS'] ], { _id: '123', firstName: 'Mock' }, 'token') )
+ * @returns { AND: [ { 'bank.id': '9'} ], OR: [{ dealType: 'BSS/EWCS' }, dealIdsWithAmendmentsInProgress: [{dealId: 'dealId1'}]] }
  */
-const dashboardDealsFiltersQuery = (filters, user) => {
+const dashboardDealsFiltersQuery = async (filters, user, userToken) => {
   const { isMaker, isChecker } = getUserRoles(user.roles);
   let dashboardFilters = filters;
 
@@ -23,10 +24,16 @@ const dashboardDealsFiltersQuery = (filters, user) => {
   }
 
   if (isChecker && !isMaker) {
-    query.AND.push({
-      [CONSTANTS.FIELD_NAMES.DEAL.STATUS]: CONSTANTS.STATUS.DEAL.READY_FOR_APPROVAL,
-    });
+    const checkersApprovalAmendmentDealIds = await getCheckersApprovalAmendmentDealIds(userToken);
+    const dealIdsQuery = checkersApprovalAmendmentDealIds?.length ? [{ [CHECKERS_AMENDMENTS_DEAL_ID]: checkersApprovalAmendmentDealIds }] : [];
+
+    const orQuery = {
+      OR: [{ [CONSTANTS.FIELD_NAMES.DEAL.STATUS]: CONSTANTS.STATUS.DEAL.READY_FOR_APPROVAL }, ...dealIdsQuery],
+    };
+
+    query.AND.push(orQuery);
   }
+
   const filtered = [];
   /* eslint-disable no-unused-vars */
   // eslint-disable-next-line no-restricted-syntax
diff --git a/portal/server/controllers/dashboard/deals/deals-filters-query.test.js b/portal/server/controllers/dashboard/deals/deals-filters-query.test.js
index 80710497775..8697b45065d 100644
--- a/portal/server/controllers/dashboard/deals/deals-filters-query.test.js
+++ b/portal/server/controllers/dashboard/deals/deals-filters-query.test.js
@@ -1,8 +1,11 @@
-import { ROLES } from '@ukef/dtfs2-common';
+import { PORTAL_AMENDMENT_STATUS, ROLES, CHECKERS_AMENDMENTS_DEAL_ID } from '@ukef/dtfs2-common';
 import { dashboardDealsFiltersQuery } from './deals-filters-query';
 import { STATUS, SUBMISSION_TYPE, FIELD_NAMES, ALL_BANKS_ID } from '../../../constants';
 import CONTENT_STRINGS from '../../../content-strings';
 import keywordQuery from './deals-filters-keyword-query';
+import getCheckersApprovalAmendmentDealIds from '../../../helpers/getCheckersApprovalAmendmentDealIds';
+
+jest.mock('../../../helpers/getCheckersApprovalAmendmentDealIds');
 
 const { MAKER, CHECKER } = ROLES;
 
@@ -13,10 +16,10 @@ describe('controllers/dashboard/deals - filters query', () => {
     bank: { id: '9' },
   };
 
-  it('should return bank.id filter', () => {
+  it('should return bank.id filter', async () => {
     const mockFilters = [];
 
-    const result = dashboardDealsFiltersQuery(mockFilters, mockUser);
+    const result = await dashboardDealsFiltersQuery(mockFilters, mockUser);
 
     const expected = {
       AND: [{ 'bank.id': mockUser.bank.id }],
@@ -26,10 +29,10 @@ describe('controllers/dashboard/deals - filters query', () => {
   });
 
   describe('when createdByYou is true', () => {
-    it('should return maker._id filter', () => {
+    it('should return maker._id filter', async () => {
       const mockFilters = [{ [FIELD_NAMES.DEAL.CREATED_BY]: ['Created by you'] }];
 
-      const result = dashboardDealsFiltersQuery(mockFilters, mockUser);
+      const result = await dashboardDealsFiltersQuery(mockFilters, mockUser);
 
       const expected = {
         AND: [{ 'bank.id': mockUser.bank.id }, { 'maker._id': mockUser._id }],
@@ -38,14 +41,14 @@ describe('controllers/dashboard/deals - filters query', () => {
       expect(result).toEqual(expected);
     });
 
-    it('should return maker._id filter and other filters if many selected', () => {
+    it('should return maker._id filter and other filters if many selected', async () => {
       const mockFilters = [
         { [FIELD_NAMES.DEAL.DEAL_TYPE]: ['BSS', 'EWCS'] },
         { [FIELD_NAMES.DEAL.SUBMISSION_TYPE]: [SUBMISSION_TYPE.AIN] },
         { [FIELD_NAMES.DEAL.CREATED_BY]: ['Created by you'] },
       ];
 
-      const result = dashboardDealsFiltersQuery(mockFilters, mockUser);
+      const result = await dashboardDealsFiltersQuery(mockFilters, mockUser);
 
       const expected = {
         AND: [
@@ -65,14 +68,41 @@ describe('controllers/dashboard/deals - filters query', () => {
   });
 
   describe('when user is a checker', () => {
-    it(`should return ${STATUS.DEAL.READY_FOR_APPROVAL} filter`, () => {
+    it(`should return ${STATUS.DEAL.READY_FOR_APPROVAL} filter`, async () => {
       const mockFilters = [];
       mockUser.roles = [CHECKER];
+      const mockDealIds = [];
+      getCheckersApprovalAmendmentDealIds.mockResolvedValue(mockDealIds);
 
-      const result = dashboardDealsFiltersQuery(mockFilters, mockUser);
+      const result = await dashboardDealsFiltersQuery(mockFilters, mockUser);
 
       const expected = {
-        AND: [{ 'bank.id': mockUser.bank.id }, { status: STATUS.DEAL.READY_FOR_APPROVAL }],
+        AND: [
+          { 'bank.id': mockUser.bank.id },
+          {
+            OR: [{ status: STATUS.DEAL.READY_FOR_APPROVAL }],
+          },
+        ],
+      };
+
+      expect(result).toEqual(expected);
+    });
+
+    it(`should return ${PORTAL_AMENDMENT_STATUS.READY_FOR_CHECKERS_APPROVAL} filter`, async () => {
+      const mockFilters = [];
+      mockUser.roles = [CHECKER];
+      const mockDealIds = ['deal1', 'deal2'];
+      getCheckersApprovalAmendmentDealIds.mockResolvedValue(mockDealIds);
+
+      const result = await dashboardDealsFiltersQuery(mockFilters, mockUser);
+
+      const expected = {
+        AND: [
+          { 'bank.id': mockUser.bank.id },
+          {
+            OR: [{ status: STATUS.DEAL.READY_FOR_APPROVAL }, { [CHECKERS_AMENDMENTS_DEAL_ID]: ['deal1', 'deal2'] }],
+          },
+        ],
       };
 
       expect(result).toEqual(expected);
@@ -80,12 +110,12 @@ describe('controllers/dashboard/deals - filters query', () => {
   });
 
   describe('when user is a super user', () => {
-    it('should not return any filters', () => {
+    it('should not return any filters', async () => {
       const mockFilters = [];
       mockUser.bank.id = ALL_BANKS_ID;
       mockUser.roles = [];
 
-      const result = dashboardDealsFiltersQuery(mockFilters, mockUser);
+      const result = await dashboardDealsFiltersQuery(mockFilters, mockUser);
 
       const expected = {};
 
@@ -93,7 +123,7 @@ describe('controllers/dashboard/deals - filters query', () => {
     });
   });
 
-  it('should add multiple custom filters to the query', () => {
+  it('should add multiple custom filters to the query', async () => {
     const mockKeyword = 'test';
     const mockFilters = [
       { [FIELD_NAMES.DEAL.DEAL_TYPE]: ['BSS', 'EWCS'] },
@@ -105,7 +135,7 @@ describe('controllers/dashboard/deals - filters query', () => {
     mockUser.bank.id = ALL_BANKS_ID;
     mockUser.roles = [];
 
-    const result = dashboardDealsFiltersQuery(mockFilters, mockUser);
+    const result = await dashboardDealsFiltersQuery(mockFilters, mockUser);
 
     const expected = {
       AND: [
@@ -124,12 +154,12 @@ describe('controllers/dashboard/deals - filters query', () => {
     expect(result).toEqual(expected);
   });
 
-  it(`should NOT add a filter to the query when the field value is ${CONTENT_STRINGS.DASHBOARD_FILTERS.BESPOKE_FILTER_VALUES.DEALS.ALL_STATUSES}`, () => {
+  it(`should NOT add a filter to the query when the field value is ${CONTENT_STRINGS.DASHBOARD_FILTERS.BESPOKE_FILTER_VALUES.DEALS.ALL_STATUSES}`, async () => {
     const mockFilters = [{ status: [CONTENT_STRINGS.DASHBOARD_FILTERS.BESPOKE_FILTER_VALUES.DEALS.ALL_STATUSES] }];
     mockUser.bank.id = ALL_BANKS_ID;
     mockUser.roles = [];
 
-    const result = dashboardDealsFiltersQuery(mockFilters, mockUser);
+    const result = await dashboardDealsFiltersQuery(mockFilters, mockUser);
 
     const expected = {};
 
diff --git a/portal/server/controllers/dashboard/deals/index.js b/portal/server/controllers/dashboard/deals/index.js
index bbf8027fcde..9baddbae44c 100644
--- a/portal/server/controllers/dashboard/deals/index.js
+++ b/portal/server/controllers/dashboard/deals/index.js
@@ -13,7 +13,7 @@ const { PAGE_SIZE } = CONSTANTS.DASHBOARD;
 const getAllDealsData = async (userToken, user, sessionFilters, currentPage, sortBy, res) => {
   const filtersArray = submittedFiltersArray(sessionFilters);
 
-  const filtersQuery = dashboardDealsFiltersQuery(filtersArray, user);
+  const filtersQuery = await dashboardDealsFiltersQuery(filtersArray, user, userToken);
 
   const sortQuery = dashboardSortQuery(sortBy);
 
diff --git a/portal/server/controllers/dashboard/deals/index.test.js b/portal/server/controllers/dashboard/deals/index.test.js
index bbaa628a1ff..a4ccf796168 100644
--- a/portal/server/controllers/dashboard/deals/index.test.js
+++ b/portal/server/controllers/dashboard/deals/index.test.js
@@ -76,7 +76,7 @@ describe('controllers/dashboard/deals', () => {
 
       const filtersArray = submittedFiltersArray(mockReq.session.dashboardFilters);
 
-      const expectedFilters = dashboardDealsFiltersQuery(filtersArray, mockReq.session.user);
+      const expectedFilters = await dashboardDealsFiltersQuery(filtersArray, mockReq.session.user);
 
       // empty object as default sort
       const sortQuery = {};
@@ -107,7 +107,7 @@ describe('controllers/dashboard/deals', () => {
 
       const filtersArray = submittedFiltersArray(mockReq.session.dashboardFilters);
 
-      const expectedFilters = dashboardDealsFiltersQuery(filtersArray, mockReq.session.user);
+      const expectedFilters = await dashboardDealsFiltersQuery(filtersArray, mockReq.session.user);
 
       // empty object as default sort
       const sortQuery = {};
diff --git a/portal/server/helpers/getCheckersApprovalAmendmentDealIds.js b/portal/server/helpers/getCheckersApprovalAmendmentDealIds.js
new file mode 100644
index 00000000000..c8546222b40
--- /dev/null
+++ b/portal/server/helpers/getCheckersApprovalAmendmentDealIds.js
@@ -0,0 +1,23 @@
+const { PORTAL_AMENDMENT_STATUS } = require('@ukef/dtfs2-common');
+const api = require('../api');
+
+/**
+ * Retrieves deal IDs that have amendments status ready for checker's approval.
+ * @param {string} userToken - A valid user token.
+ * @returns {Promise<Array<string>>} A promise that resolves to an array of deal IDs with amendments in progress.
+ */
+const getCheckersApprovalAmendmentDealIds = async (userToken) => {
+  try {
+    const statuses = [PORTAL_AMENDMENT_STATUS.READY_FOR_CHECKERS_APPROVAL];
+
+    const amendments = await api.getAllAmendments({ statuses, userToken });
+    const dealIds = (amendments || []).map((amendment) => amendment.dealId);
+
+    return dealIds;
+  } catch (error) {
+    console.error("Failed to get amendments for checker's approval %o", error);
+    throw new Error(error);
+  }
+};
+
+module.exports = getCheckersApprovalAmendmentDealIds;
diff --git a/portal/server/helpers/getCheckersApprovalAmendmentDealIds.test.js b/portal/server/helpers/getCheckersApprovalAmendmentDealIds.test.js
new file mode 100644
index 00000000000..85cb771b340
--- /dev/null
+++ b/portal/server/helpers/getCheckersApprovalAmendmentDealIds.test.js
@@ -0,0 +1,45 @@
+const getCheckersApprovalAmendmentDealIds = require('./getCheckersApprovalAmendmentDealIds');
+const api = require('../api');
+
+jest.mock('../api');
+
+const userToken = 'test-token';
+const mockAmendmentsCheckersApproval = [{ dealId: 'deal1' }, { dealId: 'deal2' }, { dealId: 'deal3' }];
+console.error = jest.fn();
+
+describe('getCheckersApprovalAmendmentDealIds', () => {
+  afterEach(() => {
+    jest.resetAllMocks();
+  });
+
+  it('should return deal IDs when amendments are provided', async () => {
+    api.getAllAmendments.mockResolvedValue(mockAmendmentsCheckersApproval);
+
+    const result = await getCheckersApprovalAmendmentDealIds(userToken);
+
+    expect(result).toEqual(['deal1', 'deal2', 'deal3']);
+  });
+
+  it('should return an empty array when an undefined response is received from the API call', async () => {
+    api.getAllAmendments.mockResolvedValue(undefined);
+
+    const result = await getCheckersApprovalAmendmentDealIds(userToken);
+
+    expect(result).toEqual([]);
+  });
+
+  it('should return an empty array when no amendments are provided', async () => {
+    api.getAllAmendments.mockResolvedValue([]);
+
+    const result = await getCheckersApprovalAmendmentDealIds(userToken);
+
+    expect(result).toEqual([]);
+  });
+
+  it('should throw an error if api.getAllAmendments fails', async () => {
+    const mockError = new Error('API error');
+    api.getAllAmendments.mockRejectedValue(mockError);
+
+    await expect(getCheckersApprovalAmendmentDealIds(userToken)).rejects.toThrow('API error');
+  });
+});
diff --git a/portal/server/helpers/index.js b/portal/server/helpers/index.js
index 07de46c8db0..7c44ed1c5ab 100644
--- a/portal/server/helpers/index.js
+++ b/portal/server/helpers/index.js
@@ -2,6 +2,7 @@ const { isEveryDealFormComplete, isEveryFacilityInDealComplete } = require('./de
 const errorHref = require('./errorHref');
 const formatCountriesForGDSComponent = require('./formatCountriesForGDSComponent');
 const getApiData = require('./getApiData');
+const getCheckersApprovalAmendmentDealIds = require('./getCheckersApprovalAmendmentDealIds');
 const getFlashSuccessMessage = require('./getFlashSuccessMessage');
 const generateErrorSummary = require('./generateErrorSummary');
 const getUserRoles = require('./getUserRoles');
@@ -28,6 +29,7 @@ module.exports = {
   errorHref,
   formatCountriesForGDSComponent,
   getApiData,
+  getCheckersApprovalAmendmentDealIds,
   getFlashSuccessMessage,
   generateErrorSummary,
   getUserRoles,
diff --git a/trade-finance-manager-api/src/v1/controllers/acbs.controller.js b/trade-finance-manager-api/src/v1/controllers/acbs.controller.js
index 7f7e79c4209..8fd3bedca21 100644
--- a/trade-finance-manager-api/src/v1/controllers/acbs.controller.js
+++ b/trade-finance-manager-api/src/v1/controllers/acbs.controller.js
@@ -1,6 +1,6 @@
 const { ObjectId } = require('mongodb');
 const $ = require('mongo-dot-notation');
-const { DURABLE_FUNCTIONS_LOG } = require('@ukef/dtfs2-common');
+const { MONGO_DB_COLLECTIONS, DURABLE_FUNCTIONS_LOG } = require('@ukef/dtfs2-common');
 const { generateSystemAuditDetails, generateAuditDatabaseRecordFromAuditDetails } = require('@ukef/dtfs2-common/change-stream');
 const { isVerifiedPayload } = require('@ukef/dtfs2-common/payload-verification');
 const {
@@ -48,7 +48,7 @@ const addToACBSLog = async (payload) => {
       auditRecord: generateAuditDatabaseRecordFromAuditDetails(auditDetails),
     };
 
-    const collection = await db.getCollection('durable-functions-log');
+    const collection = await db.getCollection(MONGO_DB_COLLECTIONS.DURABLE_FUNCTIONS_LOG);
     return collection.insertOne(logEntry);
   }
 
@@ -197,7 +197,7 @@ const updateAmendedFacilityAcbs = async (taskResult) => {
 const checkAzureAcbsFunction = async () => {
   try {
     // Fetch outstanding functions
-    const collection = await db.getCollection('durable-functions-log');
+    const collection = await db.getCollection(MONGO_DB_COLLECTIONS.DURABLE_FUNCTIONS_LOG);
     const runningTasks = await collection
       .find({
         type: { $eq: DURABLE_FUNCTIONS_LOG.TYPE.ACBS },
@@ -212,7 +212,7 @@ const checkAzureAcbsFunction = async () => {
     taskList.forEach(async (task) => {
       if (task.runtimeStatus) {
         // Update
-        if (task.runtimeStatus !== 'Running') {
+        if (task.runtimeStatus !== DURABLE_FUNCTIONS_LOG.STATUS.RUNNING) {
           await collection.findOneAndUpdate(
             { instanceId: { $eq: task.instanceId } },
             $.flatten({
@@ -223,7 +223,7 @@ const checkAzureAcbsFunction = async () => {
           );
         }
         // ADD `acbs` object to tfm-deals and tfm-facilities
-        if (task.runtimeStatus === 'Completed') {
+        if (task.runtimeStatus === DURABLE_FUNCTIONS_LOG.STATUS.COMPLETED) {
           switch (task.name) {
             case 'acbs-issue-facility':
               await updateIssuedFacilityAcbs(task.output);


Reviews:
user: login: zainUKEF
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T09:28:10Z
user: login: zainUKEF
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T09:28:44Z
user: login: zainUKEF
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T09:28:54Z
user: login: zainUKEF
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T09:29:58Z
user: login: zainUKEF
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T09:31:34Z
user: login: zainUKEF
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T09:31:49Z
user: login: zainUKEF
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T09:40:48Z
user: login: zainUKEF
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T09:40:58Z
user: login: rkontogianni
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T10:55:09Z
user: login: rkontogianni
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T11:12:27Z
user: login: abhi-markan
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T15:04:06Z
user: login: rkontogianni
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T15:29:50Z
user: login: rkontogianni
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T15:40:24Z
user: login: rkontogianni
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T16:20:45Z
user: login: rkontogianni
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-26T12:21:16Z
user: login: zainUKEF
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-26T12:28:27Z
user: login: abhi-markan
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-27T11:41:56Z
user: login: rkontogianni
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-27T13:40:09Z
user: login: rkontogianni
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-27T14:37:57Z
user: login: abhi-markan
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-28T17:03:27Z
user: login: abhi-markan
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-29T08:53:51Z

Review comments:
diff_hunk: @@ -60,13 +61,19 @@ const recursivelyReplaceEscapeOperators = (filters, result = {}) => {
     // This handles when there is an array -- ie in the case of AND and OR
     if (Array.isArray(filters[key])) {
       const newKeyName = getArrayKeyOperatorName(key);
-      if (!result[newKeyName]) {
-        result[newKeyName] = [];
+
+      if (newKeyName === 'dealIdsWithAmendmentsInProgress') {
path: portal-api/src/v1/helpers/escapeOperators.js
user: login: zainUKEF
body: is there a const for `'dealIdsWithAmendmentsInProgress'`?
created_at: 2025-03-25T09:28:10Z
author_association: CONTRIBUTOR
diff_hunk: @@ -60,13 +61,19 @@ const recursivelyReplaceEscapeOperators = (filters, result = {}) => {
     // This handles when there is an array -- ie in the case of AND and OR
     if (Array.isArray(filters[key])) {
       const newKeyName = getArrayKeyOperatorName(key);
-      if (!result[newKeyName]) {
-        result[newKeyName] = [];
+
+      if (newKeyName === 'dealIdsWithAmendmentsInProgress') {
path: portal-api/src/v1/helpers/escapeOperators.js
user: login: zainUKEF
body: documentation too please just so easy to understand 
created_at: 2025-03-25T09:28:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -60,13 +61,19 @@ const recursivelyReplaceEscapeOperators = (filters, result = {}) => {
     // This handles when there is an array -- ie in the case of AND and OR
     if (Array.isArray(filters[key])) {
       const newKeyName = getArrayKeyOperatorName(key);
-      if (!result[newKeyName]) {
-        result[newKeyName] = [];
+
+      if (newKeyName === 'dealIdsWithAmendmentsInProgress') {
+        result._id = { $in: filters[newKeyName].map((dealId) => new ObjectId(dealId)) };
+      } else {
+        if (!result[newKeyName]) {
+          result[newKeyName] = [];
+        }
+        filters[key].forEach((condition, i) => {
path: portal-api/src/v1/helpers/escapeOperators.js
user: login: zainUKEF
body: new line please
created_at: 2025-03-25T09:28:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -90,3 +90,5 @@ describe('api.loginWithSignInLink', () => {
     await expect(loginPromise).rejects.toEqual(error);
   });
 });
+
+describe('api.getAllAmendments', () => {});
path: portal/server/api.test.js
user: login: zainUKEF
body: tests are missing!
created_at: 2025-03-25T09:29:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -12,7 +12,7 @@ const keywordQuery = require('./deals-filters-keyword-query');
  * @example ( 'true', [ dealType: ['BSS/EWCS'] ], { _id: '123', firstName: 'Mock' } )
  * @returns { AND: [ { 'bank.id': '9'} ], OR: [{ dealType: 'BSS/EWCS' }] }
  */
-const dashboardDealsFiltersQuery = (filters, user) => {
+const dashboardDealsFiltersQuery = async (filters, user, userToken) => {
path: portal/server/controllers/dashboard/deals/deals-filters-query.js
user: login: zainUKEF
body: can the params documentation be updated
created_at: 2025-03-25T09:31:34Z
author_association: CONTRIBUTOR
diff_hunk: @@ -23,9 +23,12 @@ const dashboardDealsFiltersQuery = (filters, user) => {
   }
 
   if (isChecker && !isMaker) {
-    query.AND.push({
-      [CONSTANTS.FIELD_NAMES.DEAL.STATUS]: CONSTANTS.STATUS.DEAL.READY_FOR_APPROVAL,
-    });
+    const dealIdsWithAmendmentsInProgress = await getDealIdsWithAmendmentInprogress(userToken);
+    const dealIdsExist = dealIdsWithAmendmentsInProgress && dealIdsWithAmendmentsInProgress.length > 0;
+    const orQuery = {
+      OR: [{ [CONSTANTS.FIELD_NAMES.DEAL.STATUS]: CONSTANTS.STATUS.DEAL.READY_FOR_APPROVAL }, ...(dealIdsExist ? [{ dealIdsWithAmendmentsInProgress }] : [])],
+    };
+    query.AND.push(orQuery);
path: portal/server/controllers/dashboard/deals/deals-filters-query.js
user: login: zainUKEF
body: new lines please
created_at: 2025-03-25T09:31:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,19 @@
+const { PORTAL_AMENDMENT_INPROGRESS_STATUSES } = require('@ukef/dtfs2-common');
+const api = require('../api');
+
+/**
+ * Retrieves deal IDs that have amendments in progress.
+ * @returns {Promise<Array<string>>} A promise that resolves to an array of deal IDs with amendments in progress.
+ */
+const getDealIdsWithAmendmentInprogress = async (userToken) => {
+  try {
+    const amendments = await api.getAllAmendments({ statuses: PORTAL_AMENDMENT_INPROGRESS_STATUSES, userToken });
+    const dealIds = amendments.map((amendment) => amendment.dealId);
+    return dealIds;
+  } catch (error) {
+    console.error('Failed to get all amendments in progress:', error);
path: portal/server/helpers/getDealIdsWithAmendmentInProgress.js
user: login: zainUKEF
body: ```suggestion
    console.error('Failed to get all amendments in progress: %o', error);
```
created_at: 2025-03-25T09:40:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,19 @@
+const { PORTAL_AMENDMENT_INPROGRESS_STATUSES } = require('@ukef/dtfs2-common');
+const api = require('../api');
+
+/**
+ * Retrieves deal IDs that have amendments in progress.
+ * @returns {Promise<Array<string>>} A promise that resolves to an array of deal IDs with amendments in progress.
path: portal/server/helpers/getDealIdsWithAmendmentInProgress.js
user: login: zainUKEF
body: missing param
created_at: 2025-03-25T09:40:58Z
author_association: CONTRIBUTOR
diff_hunk: @@ -90,3 +90,5 @@ describe('api.loginWithSignInLink', () => {
     await expect(loginPromise).rejects.toEqual(error);
   });
 });
+
+describe('api.getAllAmendments', () => {});
path: portal/server/api.test.js
user: login: rkontogianni
body: oops I forgot it. Done
created_at: 2025-03-25T10:55:09Z
author_association: CONTRIBUTOR
diff_hunk: @@ -60,13 +61,19 @@ const recursivelyReplaceEscapeOperators = (filters, result = {}) => {
     // This handles when there is an array -- ie in the case of AND and OR
     if (Array.isArray(filters[key])) {
       const newKeyName = getArrayKeyOperatorName(key);
-      if (!result[newKeyName]) {
-        result[newKeyName] = [];
+
+      if (newKeyName === 'dealIdsWithAmendmentsInProgress') {
path: portal-api/src/v1/helpers/escapeOperators.js
user: login: rkontogianni
body: I added a const in libs common
created_at: 2025-03-25T11:12:26Z
author_association: CONTRIBUTOR
diff_hunk: @@ -23,10 +24,18 @@ const dashboardDealsFiltersQuery = (filters, user) => {
   }
 
   if (isChecker && !isMaker) {
-    query.AND.push({
-      [CONSTANTS.FIELD_NAMES.DEAL.STATUS]: CONSTANTS.STATUS.DEAL.READY_FOR_APPROVAL,
-    });
+    const dealIdsWithAmendmentsInProgress = await getDealIdsWithAmendmentInprogress(userToken);
+    const dealIdsExist = dealIdsWithAmendmentsInProgress && dealIdsWithAmendmentsInProgress.length > 0;
path: portal/server/controllers/dashboard/deals/deals-filters-query.js
user: login: abhi-markan
body: ```suggestion
    const dealIdsExist = dealIdsWithAmendmentsInProgress?.length;
```
created_at: 2025-03-25T14:39:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,20 @@
+const { PORTAL_AMENDMENT_INPROGRESS_STATUSES } = require('@ukef/dtfs2-common');
+const api = require('../api');
+
+/**
+ * Retrieves deal IDs that have amendments in progress.
+ * @param {string} userToken - A valid user token.
+ * @returns {Promise<Array<string>>} A promise that resolves to an array of deal IDs with amendments in progress.
+ */
+const getDealIdsWithAmendmentInprogress = async (userToken) => {
+  try {
+    const amendments = await api.getAllAmendments({ statuses: PORTAL_AMENDMENT_INPROGRESS_STATUSES, userToken });
+    const dealIds = amendments.map((amendment) => amendment.dealId);
path: portal/server/helpers/getDealIdsWithAmendmentInProgress.js
user: login: abhi-markan
body: ```suggestion
    const dealId = amendments.map((amendment) => amendment.dealId);

```
created_at: 2025-03-25T14:41:15Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,20 @@
+const { PORTAL_AMENDMENT_INPROGRESS_STATUSES } = require('@ukef/dtfs2-common');
+const api = require('../api');
+
+/**
+ * Retrieves deal IDs that have amendments in progress.
+ * @param {string} userToken - A valid user token.
+ * @returns {Promise<Array<string>>} A promise that resolves to an array of deal IDs with amendments in progress.
+ */
+const getDealIdsWithAmendmentInprogress = async (userToken) => {
+  try {
+    const amendments = await api.getAllAmendments({ statuses: PORTAL_AMENDMENT_INPROGRESS_STATUSES, userToken });
+    const dealIds = amendments.map((amendment) => amendment.dealId);
+    return dealIds;
+  } catch (error) {
+    console.error('Failed to get all amendments in progress: %o', error);
path: portal/server/helpers/getDealIdsWithAmendmentInProgress.js
user: login: abhi-markan
body: ```suggestion
    console.error('Failed to get all amendments in progress %o', error);
```
created_at: 2025-03-25T14:41:37Z
author_association: CONTRIBUTOR
diff_hunk: @@ -23,10 +24,18 @@ const dashboardDealsFiltersQuery = (filters, user) => {
   }
 
   if (isChecker && !isMaker) {
-    query.AND.push({
-      [CONSTANTS.FIELD_NAMES.DEAL.STATUS]: CONSTANTS.STATUS.DEAL.READY_FOR_APPROVAL,
-    });
+    const dealIdsWithAmendmentsInProgress = await getDealIdsWithAmendmentInprogress(userToken);
+    const dealIdsExist = dealIdsWithAmendmentsInProgress && dealIdsWithAmendmentsInProgress.length > 0;
+    const orQuery = {
+      OR: [
+        { [CONSTANTS.FIELD_NAMES.DEAL.STATUS]: CONSTANTS.STATUS.DEAL.READY_FOR_APPROVAL },
+        ...(dealIdsExist ? [{ [DEALIDS_AMENDMENTS_INPROGRESS]: dealIdsWithAmendmentsInProgress }] : []),
path: portal/server/controllers/dashboard/deals/deals-filters-query.js
user: login: abhi-markan
body: * Can this be a variable please.
* For my understanding is this stipulating `dealIdsWithAmendmentsInProgress: ObjectId(123)` as a secondary OR condition?
created_at: 2025-03-25T15:03:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -50,6 +50,8 @@ export const AMENDMENT_QUERIES = {
   LATEST: 'latest',
 } as const;
 
+export const DEALIDS_AMENDMENTS_INPROGRESS = 'dealIdsWithAmendmentsInProgress';
path: libs/common/src/constants/amendments.ts
user: login: abhi-markan
body: Is this the MongoDB document field?
created_at: 2025-03-25T15:04:04Z
author_association: CONTRIBUTOR
diff_hunk: @@ -50,6 +50,8 @@ export const AMENDMENT_QUERIES = {
   LATEST: 'latest',
 } as const;
 
+export const DEALIDS_AMENDMENTS_INPROGRESS = 'dealIdsWithAmendmentsInProgress';
path: libs/common/src/constants/amendments.ts
user: login: rkontogianni
body: @abhi-markan this is the key I use in escapeOperators file to tranform it if exists to _id: {$in: dealIdsWithAmendmentsInProgress }
created_at: 2025-03-25T15:29:49Z
author_association: CONTRIBUTOR
diff_hunk: @@ -23,10 +24,18 @@ const dashboardDealsFiltersQuery = (filters, user) => {
   }
 
   if (isChecker && !isMaker) {
-    query.AND.push({
-      [CONSTANTS.FIELD_NAMES.DEAL.STATUS]: CONSTANTS.STATUS.DEAL.READY_FOR_APPROVAL,
-    });
+    const dealIdsWithAmendmentsInProgress = await getDealIdsWithAmendmentInprogress(userToken);
+    const dealIdsExist = dealIdsWithAmendmentsInProgress && dealIdsWithAmendmentsInProgress.length > 0;
+    const orQuery = {
+      OR: [
+        { [CONSTANTS.FIELD_NAMES.DEAL.STATUS]: CONSTANTS.STATUS.DEAL.READY_FOR_APPROVAL },
+        ...(dealIdsExist ? [{ [DEALIDS_AMENDMENTS_INPROGRESS]: dealIdsWithAmendmentsInProgress }] : []),
path: portal/server/controllers/dashboard/deals/deals-filters-query.js
user: login: rkontogianni
body: @abhi-markan this is dealIdsWithAmendmentsInProgress: ['123', '456'] as a secondary OR condition and in the backend I transform this to _id: { $in:  [ObjectId('123'), ObjectId('456')]. The reason I am doing this is because I can't use ObjectId or $in in portal and pass them with axios to portal-api.
created_at: 2025-03-25T15:40:24Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,20 @@
+const { PORTAL_AMENDMENT_INPROGRESS_STATUSES } = require('@ukef/dtfs2-common');
+const api = require('../api');
+
+/**
+ * Retrieves deal IDs that have amendments in progress.
+ * @param {string} userToken - A valid user token.
+ * @returns {Promise<Array<string>>} A promise that resolves to an array of deal IDs with amendments in progress.
+ */
+const getDealIdsWithAmendmentInprogress = async (userToken) => {
+  try {
+    const amendments = await api.getAllAmendments({ statuses: PORTAL_AMENDMENT_INPROGRESS_STATUSES, userToken });
+    const dealIds = amendments.map((amendment) => amendment.dealId);
path: portal/server/helpers/getDealIdsWithAmendmentInProgress.js
user: login: rkontogianni
body: @abhi-markan is there any difference in your suggestion ? 
created_at: 2025-03-25T16:20:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -50,6 +50,8 @@ export const AMENDMENT_QUERIES = {
   LATEST: 'latest',
 } as const;
 
+export const DEALIDS_AMENDMENTS_INPROGRESS = 'dealIdsWithAmendmentsInProgress';
path: libs/common/src/constants/amendments.ts
user: login: rkontogianni
body: @abhi-markan @zainUKEF According with the ticket https://ukef-dtfs.atlassian.net/browse/DTFS2-7884 checker cannot view Further Maker's Input Required, I updated the name of this field to DEALIDS_CHECKERS_APPROVAL_AMENDMENTS in order to be clearer that these dealIds are only for deals that checker user can visit.
created_at: 2025-03-26T12:21:15Z
author_association: CONTRIBUTOR
diff_hunk: @@ -60,13 +61,20 @@ const recursivelyReplaceEscapeOperators = (filters, result = {}) => {
     // This handles when there is an array -- ie in the case of AND and OR
     if (Array.isArray(filters[key])) {
       const newKeyName = getArrayKeyOperatorName(key);
-      if (!result[newKeyName]) {
-        result[newKeyName] = [];
+      // This handles when there is a key DEALIDS_CHECKERS_APPROVAL_AMENDMENTS to transform filter _id within the array of DEALIDS_CHECKERS_APPROVAL_AMENDMENTS
path: portal-api/src/v1/helpers/escapeOperators.js
user: login: zainUKEF
body: ```suggestion
       /**
       * This handles DEALIDS_CHECKERS_APPROVAL_AMENDMENTS  key
       * When  key is present, transforms filter _id within the DEALIDS_CHECKERS_APPROVAL_AMENDMENTS array 
       */
```
created_at: 2025-03-26T12:28:27Z
author_association: CONTRIBUTOR
diff_hunk: @@ -23,10 +24,15 @@ const dashboardDealsFiltersQuery = (filters, user) => {
   }
 
   if (isChecker && !isMaker) {
-    query.AND.push({
-      [CONSTANTS.FIELD_NAMES.DEAL.STATUS]: CONSTANTS.STATUS.DEAL.READY_FOR_APPROVAL,
-    });
+    const dealIdsCheckersApprovalAmendments = await getDealIdsCheckersApprovalAmendments(userToken);
+    const dealIdsQuery = dealIdsCheckersApprovalAmendments?.length ? [{ [DEALIDS_CHECKERS_APPROVAL_AMENDMENTS]: dealIdsCheckersApprovalAmendments }] : [];
+    const orQuery = {
path: portal/server/controllers/dashboard/deals/deals-filters-query.js
user: login: abhi-markan
body: ```suggestion

    const orQuery = {
```
created_at: 2025-03-27T07:47:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,20 @@
+const { PORTAL_AMENDMENT_STATUS } = require('@ukef/dtfs2-common');
+const api = require('../api');
+
+/**
+ * Retrieves deal IDs that have amendments status ready for checker's approval.
+ * @param {string} userToken - A valid user token.
+ * @returns {Promise<Array<string>>} A promise that resolves to an array of deal IDs with amendments in progress.
+ */
+const getDealIdsCheckersApprovalAmendments = async (userToken) => {
path: portal/server/helpers/getDealIdsCheckersApprovalAmendments.js
user: login: abhi-markan
body: ```suggestion
const getCheckersApprovalAmendmentDealId = async (userToken) => {
```

Just thinking might be a better name, though not a blocker.
created_at: 2025-03-27T11:16:56Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,20 @@
+const { PORTAL_AMENDMENT_STATUS } = require('@ukef/dtfs2-common');
+const api = require('../api');
+
+/**
+ * Retrieves deal IDs that have amendments status ready for checker's approval.
+ * @param {string} userToken - A valid user token.
+ * @returns {Promise<Array<string>>} A promise that resolves to an array of deal IDs with amendments in progress.
+ */
+const getDealIdsCheckersApprovalAmendments = async (userToken) => {
+  try {
+    const amendments = await api.getAllAmendments({ statuses: [PORTAL_AMENDMENT_STATUS.READY_FOR_CHECKERS_APPROVAL], userToken });
path: portal/server/helpers/getDealIdsCheckersApprovalAmendments.js
user: login: abhi-markan
body: ```suggestion
    const statuses = [PORTAL_AMENDMENT_STATUS.READY_FOR_CHECKERS_APPROVAL];

    const amendments = await api.getAllAmendments({ statuses, userToken });
```
created_at: 2025-03-27T11:18:00Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,20 @@
+const { PORTAL_AMENDMENT_STATUS } = require('@ukef/dtfs2-common');
+const api = require('../api');
+
+/**
+ * Retrieves deal IDs that have amendments status ready for checker's approval.
+ * @param {string} userToken - A valid user token.
+ * @returns {Promise<Array<string>>} A promise that resolves to an array of deal IDs with amendments in progress.
+ */
+const getDealIdsCheckersApprovalAmendments = async (userToken) => {
+  try {
+    const amendments = await api.getAllAmendments({ statuses: [PORTAL_AMENDMENT_STATUS.READY_FOR_CHECKERS_APPROVAL], userToken });
+    const dealIds = amendments.map((amendment) => amendment.dealId);
+    return dealIds;
path: portal/server/helpers/getDealIdsCheckersApprovalAmendments.js
user: login: abhi-markan
body: ```suggestion

    return dealIds;
```
created_at: 2025-03-27T11:18:09Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,37 @@
+const getDealIdsCheckersApprovalAmendments = require('./getDealIdsCheckersApprovalAmendments');
+const api = require('../api');
+
+jest.mock('../api');
+
+const userToken = 'test-token';
+const mockAmendmentsCheckersApproval = [{ dealId: 'deal1' }, { dealId: 'deal2' }, { dealId: 'deal3' }];
+console.error = jest.fn();
+
+describe('getDealIdsCheckersApprovalAmendments', () => {
+  afterEach(() => {
+    jest.resetAllMocks();
+  });
+
+  it('should return deal IDs when amendments are provided', async () => {
path: portal/server/helpers/getDealIdsCheckersApprovalAmendments.test.js
user: login: abhi-markan
body: Can we please add an assertion for an edge case.

```
it('should return an empty array when an undefined response is received from the API call', async () => {
    api.getAllAmendments.mockResolvedValue(undefined);

    const result = await getDealIdsCheckersApprovalAmendments(userToken);

    expect(result).toEqual([]);
  });
```
created_at: 2025-03-27T11:21:41Z
author_association: CONTRIBUTOR
diff_hunk: @@ -50,6 +50,8 @@ export const AMENDMENT_QUERIES = {
   LATEST: 'latest',
 } as const;
 
+export const DEALIDS_CHECKERS_APPROVAL_AMENDMENTS = 'dealIdsCheckersApprovalAmendments';
path: libs/common/src/constants/amendments.ts
user: login: abhi-markan
body: ```suggestion
export const CHECKERS_AMENDMENTS_DEAL_ID = 'checkersAmendmentDealId';
```

what are yout thoughts on above please?
created_at: 2025-03-27T11:30:24Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,20 @@
+const { PORTAL_AMENDMENT_INPROGRESS_STATUSES } = require('@ukef/dtfs2-common');
+const api = require('../api');
+
+/**
+ * Retrieves deal IDs that have amendments in progress.
+ * @param {string} userToken - A valid user token.
+ * @returns {Promise<Array<string>>} A promise that resolves to an array of deal IDs with amendments in progress.
+ */
+const getDealIdsWithAmendmentInprogress = async (userToken) => {
+  try {
+    const amendments = await api.getAllAmendments({ statuses: PORTAL_AMENDMENT_INPROGRESS_STATUSES, userToken });
+    const dealIds = amendments.map((amendment) => amendment.dealId);
path: portal/server/helpers/getDealIdsWithAmendmentInProgress.js
user: login: abhi-markan
body: Apologies Rena I missed it can it be `dealId` as we can also one single dealId.
created_at: 2025-03-27T11:31:32Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,20 @@
+const { PORTAL_AMENDMENT_INPROGRESS_STATUSES } = require('@ukef/dtfs2-common');
+const api = require('../api');
+
+/**
+ * Retrieves deal IDs that have amendments in progress.
+ * @param {string} userToken - A valid user token.
+ * @returns {Promise<Array<string>>} A promise that resolves to an array of deal IDs with amendments in progress.
+ */
+const getDealIdsWithAmendmentInprogress = async (userToken) => {
+  try {
+    const amendments = await api.getAllAmendments({ statuses: PORTAL_AMENDMENT_INPROGRESS_STATUSES, userToken });
+    const dealIds = amendments.map((amendment) => amendment.dealId);
path: portal/server/helpers/getDealIdsWithAmendmentInProgress.js
user: login: rkontogianni
body: @abhi-markan this is an array of dealIds why to make it single?
created_at: 2025-03-27T13:40:09Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,20 @@
+const { PORTAL_AMENDMENT_STATUS } = require('@ukef/dtfs2-common');
+const api = require('../api');
+
+/**
+ * Retrieves deal IDs that have amendments status ready for checker's approval.
+ * @param {string} userToken - A valid user token.
+ * @returns {Promise<Array<string>>} A promise that resolves to an array of deal IDs with amendments in progress.
+ */
+const getDealIdsCheckersApprovalAmendments = async (userToken) => {
path: portal/server/helpers/getDealIdsCheckersApprovalAmendments.js
user: login: rkontogianni
body: I changed it to  getCheckersApprovalAmendmentDealIds because is an array of dealIds
created_at: 2025-03-27T14:37:57Z
author_association: CONTRIBUTOR

PR comments:
user: login: sonarqubecloud[bot]
created_at: 2025-03-28T16:47:52Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=UK-Export-Finance_dtfs2&pullRequest=4270) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=UK-Export-Finance_dtfs2&pullRequest=4270&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=UK-Export-Finance_dtfs2&pullRequest=4270&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=UK-Export-Finance_dtfs2&pullRequest=4270&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=UK-Export-Finance_dtfs2&pullRequest=4270&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=UK-Export-Finance_dtfs2&pullRequest=4270&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=UK-Export-Finance_dtfs2&pullRequest=4270)


author_association: NONE