Repository: UK-Export-Finance/tfs-api
Pull request #1016: feat(GIFT-11376): maximum amount validations
Author: login: tony-barnes-ukef
Labels: name: Type: chore
name: Type: Feature
Created: 2025-05-15T13:34:10Z | Merged: 2025-05-21T08:39:30Z

## Introduction :pencil2:

This PR updates all "amount" related GIFT fields to have a maximum validation rule.

## Resolution :heavy_check_mark:

- Update validation constants.
- Update DTOs.
- Update tests.

## Miscellaneous :heavy_plus_sign:

- Minor documentation improvements.
- Add some missing `required: true` properties.


Diff:
diff --git a/src/constants/gift/validation.constant.ts b/src/constants/gift/validation.constant.ts
index 10ee2f6b..570be9ec 100644
--- a/src/constants/gift/validation.constant.ts
+++ b/src/constants/gift/validation.constant.ts
@@ -14,6 +14,12 @@ const DATE_STRING_VALIDATION = {
   MAX_LENGTH: 10,
 };
 
+/**
+ * Maximum monetary amount.
+ * This is used for any monetary "amount" field.
+ */
+const MAX_MONETARY_AMOUNT = Number.MAX_SAFE_INTEGER;
+
 export const VALIDATION = {
   CURRENCY: CURRENCY_VALIDATION,
   FACILITY: {
@@ -23,7 +29,7 @@ export const VALIDATION = {
       EFFECTIVE_DATE: DATE_STRING_VALIDATION,
       END_OF_COVER_DATE: DATE_STRING_VALIDATION,
       EXPIRY_DATE: DATE_STRING_VALIDATION,
-      FACILITY_AMOUNT: { MIN: 1 },
+      FACILITY_AMOUNT: { MIN: 1, MAX: MAX_MONETARY_AMOUNT },
       FACILITY_ID: UKEFID.VALIDATION,
       FACILITY_NAME: { MIN_LENGTH: 1, MAX_LENGTH: 35 },
       OBLIGOR_URN: { MIN_LENGTH: 8, MAX_LENGTH: 8 },
@@ -38,24 +44,25 @@ export const VALIDATION = {
     START_DATE: DATE_STRING_VALIDATION,
   },
   FIXED_FEE: {
-    AMOUNT_DUE: { MIN: 1, MAX: 999999999999 },
+    AMOUNT_DUE: { MIN: 1, MAX: MAX_MONETARY_AMOUNT },
     CURRENCY: CURRENCY_VALIDATION,
     DESCRIPTION: { MIN_LENGTH: 1, MAX_LENGTH: 128 },
     EFFECTIVE_DATE: DATE_STRING_VALIDATION,
     FEE_TYPE_CODE: { MIN_LENGTH: 3, MAX_LENGTH: 3 },
   },
+  MAX_MONETARY_AMOUNT,
   OBLIGATION: {
     CURRENCY: CURRENCY_VALIDATION,
     EFFECTIVE_DATE: DATE_STRING_VALIDATION,
     MATURITY_DATE: DATE_STRING_VALIDATION,
-    OBLIGATION_AMOUNT: { MIN: 1, MAX: 999999999999 },
+    OBLIGATION_AMOUNT: { MIN: 1, MAX: MAX_MONETARY_AMOUNT },
     OBLIGATION_SUB_TYPE: { MIN_LENGTH: 1, MAX_LENGTH: 30 },
   },
   REPAYMENT_PROFILE: {
     NAME: { MIN_LENGTH: 1, MAX_LENGTH: 120 },
     ALLOCATION: {
       DUE_DATE: DATE_STRING_VALIDATION,
-      AMOUNT: { MIN: 0 },
+      AMOUNT: { MIN: 0, MAX: MAX_MONETARY_AMOUNT },
     },
   },
 };
diff --git a/src/modules/gift/dto/facility-overview.ts b/src/modules/gift/dto/facility-overview.ts
index 0405585a..a13d2d78 100644
--- a/src/modules/gift/dto/facility-overview.ts
+++ b/src/modules/gift/dto/facility-overview.ts
@@ -2,7 +2,7 @@ import { ApiProperty } from '@nestjs/swagger';
 import { EXAMPLES, GIFT } from '@ukef/constants';
 import { ValidatedFacilityIdentifierApiProperty } from '@ukef/decorators/validated-facility-identifier-api-property';
 import { UkefId } from '@ukef/helpers';
-import { IsBoolean, IsDefined, IsNumber, IsNumberString, IsString, Length, Min } from 'class-validator';
+import { IsBoolean, IsDefined, IsNumber, IsNumberString, IsString, Length, Max, Min } from 'class-validator';
 
 import { IsSupportedCurrency } from '../custom-decorators';
 
@@ -72,6 +72,7 @@ export class GiftFacilityOverviewDto {
   @IsDefined()
   @IsNumber()
   @Min(VALIDATION.FACILITY_AMOUNT.MIN)
+  @Max(VALIDATION.FACILITY_AMOUNT.MAX)
   @ApiProperty({
     example: EXAMPLE.facilityAmount,
     required: true,
diff --git a/src/modules/gift/dto/fixed-fee.ts b/src/modules/gift/dto/fixed-fee.ts
index e45ba55e..5d747dc0 100644
--- a/src/modules/gift/dto/fixed-fee.ts
+++ b/src/modules/gift/dto/fixed-fee.ts
@@ -22,6 +22,7 @@ export class GiftFixedFeeDto {
   @Min(VALIDATION.AMOUNT_DUE.MIN)
   @Max(VALIDATION.AMOUNT_DUE.MAX)
   @ApiProperty({
+    required: true,
     example: FIXED_FEE().amountDue,
   })
   amountDue: number;
@@ -49,6 +50,7 @@ export class GiftFixedFeeDto {
   @IsString()
   @Length(VALIDATION.EFFECTIVE_DATE.MIN_LENGTH, VALIDATION.EFFECTIVE_DATE.MAX_LENGTH)
   @ApiProperty({
+    required: true,
     example: FIXED_FEE().effectiveDate,
   })
   effectiveDate: string;
diff --git a/src/modules/gift/dto/repayment-profile-allocation.ts b/src/modules/gift/dto/repayment-profile-allocation.ts
index 842d186a..23e7b645 100644
--- a/src/modules/gift/dto/repayment-profile-allocation.ts
+++ b/src/modules/gift/dto/repayment-profile-allocation.ts
@@ -1,6 +1,6 @@
 import { ApiProperty } from '@nestjs/swagger';
 import { EXAMPLES, GIFT } from '@ukef/constants';
-import { IsDefined, IsNumber, IsString, Length, Min } from 'class-validator';
+import { IsDefined, IsNumber, IsString, Length, Max, Min } from 'class-validator';
 
 const {
   GIFT: { REPAYMENT_PROFILE_ALLOCATION },
@@ -20,6 +20,7 @@ export class GiftRepaymentProfileAllocationDto {
   @IsDefined()
   @IsNumber()
   @Min(VALIDATION.AMOUNT.MIN)
+  @Max(VALIDATION.AMOUNT.MAX)
   @ApiProperty({
     example: REPAYMENT_PROFILE_ALLOCATION().amount,
     required: true,
diff --git a/test/gift/assertions/array-of-nested-objects-number-validation.ts b/test/gift/assertions/array-of-nested-objects-number-validation.ts
index b23b45f8..f85cdda0 100644
--- a/test/gift/assertions/array-of-nested-objects-number-validation.ts
+++ b/test/gift/assertions/array-of-nested-objects-number-validation.ts
@@ -10,8 +10,8 @@ import { assert400Response } from './response-assertion';
  * @param {String} parentFieldName: The name of a parent field. E.g parentObject
  * @param {String} grandParentFieldName: The name of a parent field. E.g grandParentObject
  * @param {Object} initialPayload: The payload to use before adding a field value
- * @param {Number} min: The minimum length
- * @param {Number} max: The maximum length
+ * @param {Number} min: The minimum
+ * @param {Number} max: The maximum
  * @param {String} url: The URL the tests will call.
  */
 export const arrayOfNestedObjectsNumberValidation = ({ fieldName, grandParentFieldName, parentFieldName, initialPayload, min, max, url }) => {
@@ -50,15 +50,19 @@ export const arrayOfNestedObjectsNumberValidation = ({ fieldName, grandParentFie
       // Assert
       const expected = [
         `${grandParentFieldName}.0.${parentFieldName}.0.${fieldName} should not be null or undefined`,
+        `${grandParentFieldName}.0.${parentFieldName}.0.${fieldName} must not be greater than ${max}`,
         `${grandParentFieldName}.0.${parentFieldName}.0.${fieldName} must not be less than ${min}`,
         `${grandParentFieldName}.0.${parentFieldName}.0.${fieldName} must be a number conforming to the specified constraints`,
         `${grandParentFieldName}.0.${parentFieldName}.1.${fieldName} should not be null or undefined`,
+        `${grandParentFieldName}.0.${parentFieldName}.1.${fieldName} must not be greater than ${max}`,
         `${grandParentFieldName}.0.${parentFieldName}.1.${fieldName} must not be less than ${min}`,
         `${grandParentFieldName}.0.${parentFieldName}.1.${fieldName} must be a number conforming to the specified constraints`,
         `${grandParentFieldName}.1.${parentFieldName}.0.${fieldName} should not be null or undefined`,
+        `${grandParentFieldName}.1.${parentFieldName}.0.${fieldName} must not be greater than ${max}`,
         `${grandParentFieldName}.1.${parentFieldName}.0.${fieldName} must not be less than ${min}`,
         `${grandParentFieldName}.1.${parentFieldName}.0.${fieldName} must be a number conforming to the specified constraints`,
         `${grandParentFieldName}.1.${parentFieldName}.1.${fieldName} should not be null or undefined`,
+        `${grandParentFieldName}.1.${parentFieldName}.1.${fieldName} must not be greater than ${max}`,
         `${grandParentFieldName}.1.${parentFieldName}.1.${fieldName} must not be less than ${min}`,
         `${grandParentFieldName}.1.${parentFieldName}.1.${fieldName} must be a number conforming to the specified constraints`,
       ];
@@ -90,15 +94,19 @@ export const arrayOfNestedObjectsNumberValidation = ({ fieldName, grandParentFie
       // Assert
       const expected = [
         `${grandParentFieldName}.0.${parentFieldName}.0.${fieldName} should not be null or undefined`,
+        `${grandParentFieldName}.0.${parentFieldName}.0.${fieldName} must not be greater than ${max}`,
         `${grandParentFieldName}.0.${parentFieldName}.0.${fieldName} must not be less than ${min}`,
         `${grandParentFieldName}.0.${parentFieldName}.0.${fieldName} must be a number conforming to the specified constraints`,
         `${grandParentFieldName}.0.${parentFieldName}.1.${fieldName} should not be null or undefined`,
+        `${grandParentFieldName}.0.${parentFieldName}.1.${fieldName} must not be greater than ${max}`,
         `${grandParentFieldName}.0.${parentFieldName}.1.${fieldName} must not be less than ${min}`,
         `${grandParentFieldName}.0.${parentFieldName}.1.${fieldName} must be a number conforming to the specified constraints`,
         `${grandParentFieldName}.1.${parentFieldName}.0.${fieldName} should not be null or undefined`,
+        `${grandParentFieldName}.1.${parentFieldName}.0.${fieldName} must not be greater than ${max}`,
         `${grandParentFieldName}.1.${parentFieldName}.0.${fieldName} must not be less than ${min}`,
         `${grandParentFieldName}.1.${parentFieldName}.0.${fieldName} must be a number conforming to the specified constraints`,
         `${grandParentFieldName}.1.${parentFieldName}.1.${fieldName} should not be null or undefined`,
+        `${grandParentFieldName}.1.${parentFieldName}.1.${fieldName} must not be greater than ${max}`,
         `${grandParentFieldName}.1.${parentFieldName}.1.${fieldName} must not be less than ${min}`,
         `${grandParentFieldName}.1.${parentFieldName}.1.${fieldName} must be a number conforming to the specified constraints`,
       ];
@@ -129,12 +137,16 @@ export const arrayOfNestedObjectsNumberValidation = ({ fieldName, grandParentFie
 
       // Assert
       const expected = [
+        `${grandParentFieldName}.0.${parentFieldName}.0.${fieldName} must not be greater than ${max}`,
         `${grandParentFieldName}.0.${parentFieldName}.0.${fieldName} must not be less than ${min}`,
         `${grandParentFieldName}.0.${parentFieldName}.0.${fieldName} must be a number conforming to the specified constraints`,
+        `${grandParentFieldName}.0.${parentFieldName}.1.${fieldName} must not be greater than ${max}`,
         `${grandParentFieldName}.0.${parentFieldName}.1.${fieldName} must not be less than ${min}`,
         `${grandParentFieldName}.0.${parentFieldName}.1.${fieldName} must be a number conforming to the specified constraints`,
+        `${grandParentFieldName}.1.${parentFieldName}.0.${fieldName} must not be greater than ${max}`,
         `${grandParentFieldName}.1.${parentFieldName}.0.${fieldName} must not be less than ${min}`,
         `${grandParentFieldName}.1.${parentFieldName}.0.${fieldName} must be a number conforming to the specified constraints`,
+        `${grandParentFieldName}.1.${parentFieldName}.1.${fieldName} must not be greater than ${max}`,
         `${grandParentFieldName}.1.${parentFieldName}.1.${fieldName} must not be less than ${min}`,
         `${grandParentFieldName}.1.${parentFieldName}.1.${fieldName} must be a number conforming to the specified constraints`,
       ];
@@ -177,37 +189,37 @@ export const arrayOfNestedObjectsNumberValidation = ({ fieldName, grandParentFie
     });
   });
 
-  if (max) {
-    describe(`when ${fieldName} is above the maximum`, () => {
-      let mockPayload;
+  describe(`when ${fieldName} is above the maximum`, () => {
+    let mockPayload;
 
+    beforeAll(() => {
+      // Arrange
       const value = max + 1;
 
-      beforeAll(() => {
-        // Arrange
-        mockPayload = generatePayloadArrayOfObjects({ ...payloadParams, value });
-      });
+      mockPayload = generatePayloadArrayOfObjects({ ...payloadParams, value });
+    });
 
-      it(`should return a ${HttpStatus.BAD_REQUEST} response`, async () => {
-        // Act
-        const response = await api.post(url, mockPayload);
+    it(`should return a ${HttpStatus.BAD_REQUEST} response`, async () => {
+      // Act
+      const response = await api.post(url, mockPayload);
 
-        // Assert
-        assert400Response(response);
-      });
+      // Assert
+      assert400Response(response);
+    });
 
-      it('should return the correct error messages', async () => {
-        // Act
-        const { body } = await api.post(url, mockPayload);
+    it('should return the correct error messages', async () => {
+      // Act
+      const { body } = await api.post(url, mockPayload);
 
-        // Assert
-        const expected = [
-          `${parentFieldName}.0.${fieldName} must not be greater than ${max}`,
-          `${parentFieldName}.1.${fieldName} must not be greater than ${max}`,
-        ];
+      // Assert
+      const expected = [
+        `${grandParentFieldName}.0.${parentFieldName}.0.${fieldName} must not be greater than ${max}`,
+        `${grandParentFieldName}.0.${parentFieldName}.1.${fieldName} must not be greater than ${max}`,
+        `${grandParentFieldName}.1.${parentFieldName}.0.${fieldName} must not be greater than ${max}`,
+        `${grandParentFieldName}.1.${parentFieldName}.1.${fieldName} must not be greater than ${max}`,
+      ];
 
-        expect(body.message).toStrictEqual(expected);
-      });
+      expect(body.message).toStrictEqual(expected);
     });
-  }
+  });
 };
diff --git a/test/gift/assertions/array-of-objects-number-validation.ts b/test/gift/assertions/array-of-objects-number-validation.ts
index 419b046f..10e1ef7a 100644
--- a/test/gift/assertions/array-of-objects-number-validation.ts
+++ b/test/gift/assertions/array-of-objects-number-validation.ts
@@ -8,8 +8,8 @@ import { assert400Response } from './response-assertion';
  * @param {String} fieldName: The name of a field. E.g, amount
  * @param {String} parentFieldName: The name of a parent field. E.g parentObject
  * @param {Object} initialPayload: The payload to use before adding a field value
- * @param {Number} min: The minimum length
- * @param {Number} max: The maximum length
+ * @param {Number} min: The minimum
+ * @param {Number} max: The maximum
  * @param {String} url: The URL the tests will call.
  */
 export const arrayOfObjectsNumberValidation = ({ fieldName, parentFieldName, initialPayload, min, max, url }) => {
diff --git a/test/gift/assertions/number-validation.ts b/test/gift/assertions/number-validation.ts
index 8bc9f54e..264d7887 100644
--- a/test/gift/assertions/number-validation.ts
+++ b/test/gift/assertions/number-validation.ts
@@ -7,11 +7,12 @@ import { assert400Response } from './response-assertion';
  * Validation tests for a number field with invalid values
  * @param {String} fieldName: The name of a field. E.g, amount
  * @param {Object} initialPayload: The payload to use before adding a field value
- * @param {Number} min: The minimum length
+ * @param {Number} min: The minimum
+ * @param {Number} max: The maximum
  * @param {String} parentFieldName: The name of a parent field. E.g parentObject
  * @param {String} url: The URL the tests will call.
  */
-export const numberValidation = ({ fieldName, initialPayload, min, parentFieldName, url }) => {
+export const numberValidation = ({ fieldName, initialPayload, min, max, parentFieldName, url }) => {
   let api: Api;
 
   beforeAll(async () => {
@@ -47,6 +48,7 @@ export const numberValidation = ({ fieldName, initialPayload, min, parentFieldNa
       // Assert
       const expected = [
         `${fieldPath} should not be null or undefined`,
+        `${fieldPath} must not be greater than ${max}`,
         `${fieldPath} must not be less than ${min}`,
         `${fieldPath} must be a number conforming to the specified constraints`,
       ];
@@ -76,6 +78,7 @@ export const numberValidation = ({ fieldName, initialPayload, min, parentFieldNa
       // Assert
       const expected = [
         `${fieldPath} should not be null or undefined`,
+        `${fieldPath} must not be greater than ${max}`,
         `${fieldPath} must not be less than ${min}`,
         `${fieldPath} must be a number conforming to the specified constraints`,
       ];
@@ -103,7 +106,11 @@ export const numberValidation = ({ fieldName, initialPayload, min, parentFieldNa
       const { body } = await api.post(url, mockPayload);
 
       // Assert
-      const expected = [`${fieldPath} must not be less than ${min}`, `${fieldPath} must be a number conforming to the specified constraints`];
+      const expected = [
+        `${fieldPath} must not be greater than ${max}`,
+        `${fieldPath} must not be less than ${min}`,
+        `${fieldPath} must be a number conforming to the specified constraints`,
+      ];
 
       expect(body.message).toStrictEqual(expected);
     });
@@ -128,7 +135,11 @@ export const numberValidation = ({ fieldName, initialPayload, min, parentFieldNa
       const { body } = await api.post(url, mockPayload);
 
       // Assert
-      const expected = [`${fieldPath} must not be less than ${min}`, `${fieldPath} must be a number conforming to the specified constraints`];
+      const expected = [
+        `${fieldPath} must not be greater than ${max}`,
+        `${fieldPath} must not be less than ${min}`,
+        `${fieldPath} must be a number conforming to the specified constraints`,
+      ];
 
       expect(body.message).toStrictEqual(expected);
     });
@@ -153,7 +164,11 @@ export const numberValidation = ({ fieldName, initialPayload, min, parentFieldNa
       const { body } = await api.post(url, mockPayload);
 
       // Assert
-      const expected = [`${fieldPath} must not be less than ${min}`, `${fieldPath} must be a number conforming to the specified constraints`];
+      const expected = [
+        `${fieldPath} must not be greater than ${max}`,
+        `${fieldPath} must not be less than ${min}`,
+        `${fieldPath} must be a number conforming to the specified constraints`,
+      ];
 
       expect(body.message).toStrictEqual(expected);
     });
@@ -178,7 +193,11 @@ export const numberValidation = ({ fieldName, initialPayload, min, parentFieldNa
       const { body } = await api.post(url, mockPayload);
 
       // Assert
-      const expected = [`${fieldPath} must not be less than ${min}`, `${fieldPath} must be a number conforming to the specified constraints`];
+      const expected = [
+        `${fieldPath} must not be greater than ${max}`,
+        `${fieldPath} must not be less than ${min}`,
+        `${fieldPath} must be a number conforming to the specified constraints`,
+      ];
 
       expect(body.message).toStrictEqual(expected);
     });
@@ -187,7 +206,35 @@ export const numberValidation = ({ fieldName, initialPayload, min, parentFieldNa
   describe(`when ${fieldName} is below the minimum`, () => {
     beforeAll(() => {
       // Arrange
-      mockPayload[`${parentFieldName}`][`${fieldName}`] = 'a'.repeat(min - 1);
+      mockPayload[`${parentFieldName}`][`${fieldName}`] = min - 1;
+    });
+
+    it('should return a 400 response', async () => {
+      // Act
+      const response = await api.post(url, mockPayload);
+
+      // Assert
+      assert400Response(response);
+    });
+
+    it('should return the correct error messages', async () => {
+      // Act
+      const { body } = await api.post(url, mockPayload);
+
+      // Assert
+      const expected = [`${fieldPath} must not be less than ${min}`];
+
+      expect(body.message).toStrictEqual(expected);
+    });
+  });
+
+  describe(`when ${fieldName} is above the maximum`, () => {
+    beforeAll(() => {
+      // Arrange
+
+      const value = max + 1;
+
+      mockPayload[`${parentFieldName}`][`${fieldName}`] = value;
     });
 
     it('should return a 400 response', async () => {
@@ -203,7 +250,7 @@ export const numberValidation = ({ fieldName, initialPayload, min, parentFieldNa
       const { body } = await api.post(url, mockPayload);
 
       // Assert
-      const expected = [`${fieldPath} must not be less than ${min}`, `${fieldPath} must be a number conforming to the specified constraints`];
+      const expected = [`${fieldPath} must not be greater than ${max}`];
 
       expect(body.message).toStrictEqual(expected);
     });
diff --git a/test/gift/create-facility-validation-repayment-profiles.api-test.ts b/test/gift/create-facility-validation-repayment-profiles.api-test.ts
index 38a4ee3e..cf4ec17f 100644
--- a/test/gift/create-facility-validation-repayment-profiles.api-test.ts
+++ b/test/gift/create-facility-validation-repayment-profiles.api-test.ts
@@ -200,6 +200,7 @@ describe('POST /gift/facility - validation - repayment profiles', () => {
         error: 'Bad Request',
         message: [
           'repaymentProfiles.0.allocations.0.amount should not be null or undefined',
+          `repaymentProfiles.0.allocations.0.amount must not be greater than ${REPAYMENT_PROFILE_VALIDATION.ALLOCATION.AMOUNT.MAX}`,
           `repaymentProfiles.0.allocations.0.amount must not be less than ${REPAYMENT_PROFILE_VALIDATION.ALLOCATION.AMOUNT.MIN}`,
           'repaymentProfiles.0.allocations.0.amount must be a number conforming to the specified constraints',
           'repaymentProfiles.0.allocations.0.dueDate should not be null or undefined',
@@ -220,7 +221,7 @@ describe('POST /gift/facility - validation - repayment profiles', () => {
       parentFieldName: 'allocations',
       fieldName: 'amount',
       min: REPAYMENT_PROFILE_VALIDATION.ALLOCATION.AMOUNT.MIN,
-      max: null,
+      max: REPAYMENT_PROFILE_VALIDATION.ALLOCATION.AMOUNT.MAX,
     });
   });
 
diff --git a/test/gift/create-facility-validation.api-test.ts b/test/gift/create-facility-validation.api-test.ts
index 25ba22a5..d4861ab5 100644
--- a/test/gift/create-facility-validation.api-test.ts
+++ b/test/gift/create-facility-validation.api-test.ts
@@ -255,6 +255,7 @@ describe('POST /gift/facility - validation', () => {
           `overview.expiryDate must be longer than or equal to ${VALIDATION.FACILITY.OVERVIEW.EXPIRY_DATE.MIN_LENGTH} characters`,
           'overview.expiryDate must be a string',
           'overview.facilityAmount should not be null or undefined',
+          `overview.facilityAmount must not be greater than ${VALIDATION.FACILITY.OVERVIEW.FACILITY_AMOUNT.MAX}`,
           `overview.facilityAmount must not be less than ${VALIDATION.FACILITY.OVERVIEW.FACILITY_AMOUNT.MIN}`,
           'overview.facilityAmount must be a number conforming to the specified constraints',
           'overview.facilityId must be a string',
@@ -313,7 +314,7 @@ describe('POST /gift/facility - validation', () => {
           `obligations.maturityDate must be longer than or equal to ${VALIDATION.OBLIGATION.MATURITY_DATE.MIN_LENGTH} characters`,
           'obligations.maturityDate must be a string',
           'obligations.obligationAmount should not be null or undefined',
-          'obligations.obligationAmount must not be greater than 999999999999',
+          `obligations.obligationAmount must not be greater than ${VALIDATION.OBLIGATION.OBLIGATION_AMOUNT.MAX}`,
           `obligations.obligationAmount must not be less than ${VALIDATION.OBLIGATION.OBLIGATION_AMOUNT.MIN}`,
           'obligations.obligationAmount must be a number conforming to the specified constraints',
           'obligations.obligationSubtype should not be null or undefined',
@@ -384,6 +385,7 @@ describe('POST /gift/facility - validation', () => {
       ...baseParams,
       fieldName: 'facilityAmount',
       min: VALIDATION.FACILITY.OVERVIEW.FACILITY_AMOUNT.MIN,
+      max: VALIDATION.FACILITY.OVERVIEW.FACILITY_AMOUNT.MAX,
     });
   });
 


Reviews:
user: login: abhi-markan
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-16T07:25:03Z
user: login: tony-barnes-ukef
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-16T10:30:02Z
user: login: tony-barnes-ukef
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-20T15:10:55Z
user: login: abhi-markan
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-21T08:39:26Z

Review comments:
diff_hunk: @@ -14,6 +14,12 @@ const DATE_STRING_VALIDATION = {
   MAX_LENGTH: 10,
 };
 
+/**
+ * Maximum monetary amount.
+ * This is used for any monetary "amount" field.
+ */
+const MAX_MONETARY_AMOUNT = 10000000000000000;
path: src/constants/gift/validation.constant.ts
user: login: abhi-markan
body: Shouldn't this be `Number.MAX_SAFE_INTEGER` which is equates to 9 quadrillion (aprox).
created_at: 2025-05-16T07:24:21Z
author_association: CONTRIBUTOR
diff_hunk: @@ -14,6 +14,12 @@ const DATE_STRING_VALIDATION = {
   MAX_LENGTH: 10,
 };
 
+/**
+ * Maximum monetary amount.
+ * This is used for any monetary "amount" field.
+ */
+const MAX_MONETARY_AMOUNT = 10000000000000000;
path: src/constants/gift/validation.constant.ts
user: login: tony-barnes-ukef
body: Agree - ongoing discussion, waiting for the OK before updating.
created_at: 2025-05-16T10:30:02Z
author_association: COLLABORATOR
diff_hunk: @@ -14,6 +14,12 @@ const DATE_STRING_VALIDATION = {
   MAX_LENGTH: 10,
 };
 
+/**
+ * Maximum monetary amount.
+ * This is used for any monetary "amount" field.
+ */
+const MAX_MONETARY_AMOUNT = 10000000000000000;
path: src/constants/gift/validation.constant.ts
user: login: tony-barnes-ukef
body: Now agreed and updated.
created_at: 2025-05-20T15:10:55Z
author_association: COLLABORATOR

PR comments:
user: login: sonarqubecloud[bot]
created_at: 2025-05-20T15:11:30Z
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_tfs-api&pullRequest=1016) **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_tfs-api&pullRequest=1016&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_tfs-api&pullRequest=1016&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_tfs-api&pullRequest=1016&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_tfs-api&pullRequest=1016&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [12.1% Duplication on New Code](https://sonarcloud.io/component_measures?id=UK-Export-Finance_tfs-api&pullRequest=1016&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=UK-Export-Finance_tfs-api&pullRequest=1016)


author_association: NONE