From 4ad04f32534e4a314f9d176dc3b8631015d11d25 Mon Sep 17 00:00:00 2001 From: Krishnan Subramanian Date: Wed, 23 Oct 2024 18:33:39 +0530 Subject: [PATCH 1/5] Adding to cache --- vehicles/src/app.service.ts | 9 ++++ vehicles/src/common/enum/cache-key.enum.ts | 1 + .../response/read-policy-configuration.dto.ts | 33 +++++++++++++++ .../entities/policy-configuration.entity.ts | 42 +++++++++++++++++++ vehicles/src/modules/policy/policy.module.ts | 11 +++++ vehicles/src/modules/policy/policy.service.ts | 29 +++++++++++++ 6 files changed, 125 insertions(+) create mode 100644 vehicles/src/modules/policy/dto/response/read-policy-configuration.dto.ts create mode 100644 vehicles/src/modules/policy/entities/policy-configuration.entity.ts create mode 100644 vehicles/src/modules/policy/policy.module.ts create mode 100644 vehicles/src/modules/policy/policy.service.ts diff --git a/vehicles/src/app.service.ts b/vehicles/src/app.service.ts index bcee88529..ba08c8c6d 100644 --- a/vehicles/src/app.service.ts +++ b/vehicles/src/app.service.ts @@ -12,6 +12,7 @@ import { PaymentService } from './modules/permit-application-payment/payment/pay import { LogAsyncMethodExecution } from './common/decorator/log-async-method-execution.decorator'; import { FeatureFlagsService } from './modules/feature-flags/feature-flags.service'; import { ApplicationService } from './modules/permit-application-payment/application/application.service'; +import { PolicyService } from './modules/policy/policy.service'; @Injectable() export class AppService { @@ -27,6 +28,7 @@ export class AppService { private paymentService: PaymentService, private featureFlagsService: FeatureFlagsService, private applicationService: ApplicationService, + private policyService: PolicyService ) {} getHello(): string { @@ -128,6 +130,13 @@ export class AppService { createCacheMap(permitApprovalSource, 'id', 'code'), ); + const policyConfigs = await this.policyService.findAllActive(); + await addToCache( + this.cacheManager, + CacheKey.POLICY_CONFIGURATIONS, + createCacheMap(policyConfigs, '??', 'policyJson'), + ); + const endDateTime = new Date(); const processingTime = endDateTime.getTime() - startDateTime.getTime(); this.logger.log( diff --git a/vehicles/src/common/enum/cache-key.enum.ts b/vehicles/src/common/enum/cache-key.enum.ts index 82100c8cc..e114b56b7 100644 --- a/vehicles/src/common/enum/cache-key.enum.ts +++ b/vehicles/src/common/enum/cache-key.enum.ts @@ -20,4 +20,5 @@ export enum CacheKey { FEATURE_FLAG_TYPE = 'FEATURE_FLAG_TYPE', PERMIT_APPLICATION_ORIGIN = 'PERMIT_APPLICATION_ORIGIN', PERMIT_APPROVAL_SOURCE = 'PERMIT_APPROVAL_SOURCE', + POLICY_CONFIGURATIONS = 'POLICY_CONFIGURATIONS', } diff --git a/vehicles/src/modules/policy/dto/response/read-policy-configuration.dto.ts b/vehicles/src/modules/policy/dto/response/read-policy-configuration.dto.ts new file mode 100644 index 000000000..076e99328 --- /dev/null +++ b/vehicles/src/modules/policy/dto/response/read-policy-configuration.dto.ts @@ -0,0 +1,33 @@ +import { AutoMap } from '@automapper/classes'; +import { ApiProperty } from '@nestjs/swagger'; + +export class ReadPolicyConfigurationDto { + @AutoMap() + @ApiProperty({ + description: 'Id of the policy configuration.', + example: 74, + }) + policyConfigurationId: number; + + @AutoMap() + @ApiProperty({ + description: 'The policy config json.', + required: false, + }) + policyJson: JSON; + + @AutoMap() + @ApiProperty({ + description: 'The effective date of the policy config.', + required: false, + }) + effectiveDate: string; + + @AutoMap() + @ApiProperty({ + description: 'Boolean indicator on whether the policy config is a draft.', + example: false, + required: false, + }) + isDraft: boolean; +} diff --git a/vehicles/src/modules/policy/entities/policy-configuration.entity.ts b/vehicles/src/modules/policy/entities/policy-configuration.entity.ts new file mode 100644 index 000000000..be1696b1e --- /dev/null +++ b/vehicles/src/modules/policy/entities/policy-configuration.entity.ts @@ -0,0 +1,42 @@ +import { AutoMap } from '@automapper/classes'; +import { ApiProperty } from '@nestjs/swagger'; +import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'; +import { Base } from '../../common/entities/base.entity'; + +@Entity({ name: 'ORBC_POLICY_CONFIGURATION' }) +export class PolicyConfiguration extends Base { + @AutoMap() + @ApiProperty({ + example: '1', + description: 'Unique identifier for the policy configuration.', + }) + @PrimaryGeneratedColumn({ type: 'int', name: 'POLICY_CONFIGURATION_ID' }) + policyConfigurationId: string; + + @AutoMap() + @Column({ length: 8000, name: 'POLICY_JSON', nullable: true }) + policyJson: string; + + @AutoMap() + @Column({ + insert: false, + update: false, + name: 'EFFECTIVE_DATE', + nullable: true, + type: 'date', + }) + effectiveDate: string; + + @AutoMap() + @Column({ + type: 'char', + name: 'IS_DRAFT', + nullable: false, + default: true, + transformer: { + to: (value: boolean): string => (value ? 'Y' : 'N'), // Converts the boolean value to 'Y' or 'N' for storage. + from: (value: string): boolean => value === 'Y', // Converts the stored string back to a boolean. + }, + }) + isDraft: boolean; +} diff --git a/vehicles/src/modules/policy/policy.module.ts b/vehicles/src/modules/policy/policy.module.ts new file mode 100644 index 000000000..db6787114 --- /dev/null +++ b/vehicles/src/modules/policy/policy.module.ts @@ -0,0 +1,11 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { PolicyConfiguration } from './entities/policy-configuration.entity'; +import { PolicyService } from './policy.service'; + +@Module({ + imports: [TypeOrmModule.forFeature([PolicyConfiguration])], + providers: [PolicyService], + exports: [PolicyService], +}) +export class PolicyConfigurationModule {} diff --git a/vehicles/src/modules/policy/policy.service.ts b/vehicles/src/modules/policy/policy.service.ts new file mode 100644 index 000000000..e95ce4ca1 --- /dev/null +++ b/vehicles/src/modules/policy/policy.service.ts @@ -0,0 +1,29 @@ +import { Mapper } from '@automapper/core'; +import { InjectMapper } from '@automapper/nestjs'; +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Repository } from 'typeorm'; +import { LogAsyncMethodExecution } from '../../common/decorator/log-async-method-execution.decorator'; +import { ReadPolicyConfigurationDto } from './dto/response/read-policy-configuration.dto'; +import { PolicyConfiguration } from './entities/policy-configuration.entity'; + +@Injectable() +export class PolicyService { + constructor( + @InjectRepository(PolicyConfiguration) + private policyConfigurationRepository: Repository, + @InjectMapper() private readonly classMapper: Mapper, + ) {} + + @LogAsyncMethodExecution() + async findAllActive(): Promise { + return this.classMapper.mapArrayAsync( + await this.policyConfigurationRepository.find({ + select: { policyJson: true }, + where: { isDraft: false }, + }), + PolicyConfiguration, + ReadPolicyConfigurationDto, + ); + } +} From dc3610dddd4ba1ced1b41d1f4cf18f407305e4b8 Mon Sep 17 00:00:00 2001 From: Krishnan Subramanian Date: Tue, 29 Oct 2024 18:05:52 +0530 Subject: [PATCH 2/5] Replace policy service with http call to policy --- vehicles/src/app.service.ts | 10 ++-- vehicles/src/common/constants/api.constant.ts | 3 +- vehicles/src/common/enum/cache-key.enum.ts | 1 + .../common/enum/gov-common-services.enum.ts | 1 + .../helper/gov-common-services.helper.ts | 7 ++- .../helper/permit-application.helper.ts | 9 ++-- .../src/common/helper/permit-fee.helper.ts | 4 +- .../src/common/helper/policy-engine.helper.ts | 30 +++++++++++ .../application/application.service.ts | 4 +- .../payment/payment.service.ts | 11 ++-- .../dto/response/read-policy-config.dto.ts | 53 +++++++++++++++++++ .../response/read-policy-configuration.dto.ts | 33 ------------ .../entities/policy-configuration.entity.ts | 42 --------------- vehicles/src/modules/policy/policy.module.ts | 11 ---- vehicles/src/modules/policy/policy.service.ts | 29 ---------- 15 files changed, 117 insertions(+), 131 deletions(-) create mode 100644 vehicles/src/modules/policy/dto/response/read-policy-config.dto.ts delete mode 100644 vehicles/src/modules/policy/dto/response/read-policy-configuration.dto.ts delete mode 100644 vehicles/src/modules/policy/entities/policy-configuration.entity.ts delete mode 100644 vehicles/src/modules/policy/policy.module.ts delete mode 100644 vehicles/src/modules/policy/policy.service.ts diff --git a/vehicles/src/app.service.ts b/vehicles/src/app.service.ts index ba08c8c6d..d2c29221c 100644 --- a/vehicles/src/app.service.ts +++ b/vehicles/src/app.service.ts @@ -12,7 +12,8 @@ import { PaymentService } from './modules/permit-application-payment/payment/pay import { LogAsyncMethodExecution } from './common/decorator/log-async-method-execution.decorator'; import { FeatureFlagsService } from './modules/feature-flags/feature-flags.service'; import { ApplicationService } from './modules/permit-application-payment/application/application.service'; -import { PolicyService } from './modules/policy/policy.service'; +import { HttpService } from '@nestjs/axios'; +import { getActivePolicyDefinitions } from './common/helper/policy-engine.helper'; @Injectable() export class AppService { @@ -28,7 +29,7 @@ export class AppService { private paymentService: PaymentService, private featureFlagsService: FeatureFlagsService, private applicationService: ApplicationService, - private policyService: PolicyService + private readonly httpService: HttpService, ) {} getHello(): string { @@ -130,7 +131,10 @@ export class AppService { createCacheMap(permitApprovalSource, 'id', 'code'), ); - const policyConfigs = await this.policyService.findAllActive(); + const policyConfigs = await getActivePolicyDefinitions( + this.httpService, + this.cacheManager, + ); await addToCache( this.cacheManager, CacheKey.POLICY_CONFIGURATIONS, diff --git a/vehicles/src/common/constants/api.constant.ts b/vehicles/src/common/constants/api.constant.ts index b15b80cbe..ffcbeb052 100644 --- a/vehicles/src/common/constants/api.constant.ts +++ b/vehicles/src/common/constants/api.constant.ts @@ -8,6 +8,5 @@ export const CRYPTO_ALGORITHM_MD5 = 'md5'; export const CRYPTO_ALGORITHM_SHA256 = 'sha256'; export const TOKEN_EXPIRY_BUFFER = 15; export const PERMISSIONS_KEY = 'permissions'; -export const TIMEZONE_PACIFIC = "America/Vancouver"; +export const TIMEZONE_PACIFIC = 'America/Vancouver'; export const GL_PROJ_CODE_PLACEHOLDER = 'PROJECT'; - diff --git a/vehicles/src/common/enum/cache-key.enum.ts b/vehicles/src/common/enum/cache-key.enum.ts index e114b56b7..fd58b6416 100644 --- a/vehicles/src/common/enum/cache-key.enum.ts +++ b/vehicles/src/common/enum/cache-key.enum.ts @@ -21,4 +21,5 @@ export enum CacheKey { PERMIT_APPLICATION_ORIGIN = 'PERMIT_APPLICATION_ORIGIN', PERMIT_APPROVAL_SOURCE = 'PERMIT_APPROVAL_SOURCE', POLICY_CONFIGURATIONS = 'POLICY_CONFIGURATIONS', + ORBC_SERVICE_ACCOUNT_ACCESS_TOKEN = 'ORBC_SERVICE_ACCOUNT_ACCESS_TOKEN', } diff --git a/vehicles/src/common/enum/gov-common-services.enum.ts b/vehicles/src/common/enum/gov-common-services.enum.ts index 6a44a473f..acc92f93d 100644 --- a/vehicles/src/common/enum/gov-common-services.enum.ts +++ b/vehicles/src/common/enum/gov-common-services.enum.ts @@ -2,4 +2,5 @@ export enum GovCommonServices { COMMON_HOSTED_EMAIL_SERVICE = 'CHES', COMMON_DOCUMENT_GENERATION_SERVICE = 'CDOGS', CREDIT_ACCOUNT_SERVICE = 'CREDIT_ACCOUNT', + ORBC_SERVICE_ACCOUNT = 'SA', } diff --git a/vehicles/src/common/helper/gov-common-services.helper.ts b/vehicles/src/common/helper/gov-common-services.helper.ts index be81e942b..d453be518 100644 --- a/vehicles/src/common/helper/gov-common-services.helper.ts +++ b/vehicles/src/common/helper/gov-common-services.helper.ts @@ -124,7 +124,12 @@ function getTokenCredentials(govCommonServices: GovCommonServices): { username = process.env.CFS_CREDIT_ACCOUNT_CLIENT_ID; password = process.env.CFS_CREDIT_ACCOUNT_CLIENT_SECRET; break; - + case GovCommonServices.ORBC_SERVICE_ACCOUNT: + tokenCacheKey = CacheKey.ORBC_SERVICE_ACCOUNT_ACCESS_TOKEN; + tokenUrl = process.env.ORBC_SERVICE_ACCOUNT_TOKEN_URL; + username = process.env.ORBC_SERVICE_ACCOUNT_CLIENT_ID; + password = process.env.ORBC_SERVICE_ACCOUNT_CLIENT_SECRET; + break; default: break; } diff --git a/vehicles/src/common/helper/permit-application.helper.ts b/vehicles/src/common/helper/permit-application.helper.ts index b572f57e9..96d3b53e4 100644 --- a/vehicles/src/common/helper/permit-application.helper.ts +++ b/vehicles/src/common/helper/permit-application.helper.ts @@ -268,9 +268,12 @@ export const isPermitTypeEligibleForQueue = ( return PERMIT_TYPES_FOR_QUEUE.includes(permitType); }; -export const validApplicationDates = (application: Permit, timezone: string): boolean => { +export const validApplicationDates = ( + application: Permit, + timezone: string, +): boolean => { const todayUTC = dayjs(new Date()); - const todayPacific = todayUTC.tz(timezone).format("YYYY-MM-DD"); + const todayPacific = todayUTC.tz(timezone).format('YYYY-MM-DD'); const { startDate, expiryDate } = application.permitData; return startDate >= todayPacific && startDate <= expiryDate; -} +}; diff --git a/vehicles/src/common/helper/permit-fee.helper.ts b/vehicles/src/common/helper/permit-fee.helper.ts index 8e2314c02..dc14bf979 100644 --- a/vehicles/src/common/helper/permit-fee.helper.ts +++ b/vehicles/src/common/helper/permit-fee.helper.ts @@ -205,7 +205,7 @@ export const validAmount = ( calculatedAmount: number, receivedAmount: number, transactionType: TransactionType, -): boolean =>{ +): boolean => { const isAmountValid = receivedAmount.toFixed(2) === Math.abs(calculatedAmount).toFixed(2); @@ -218,4 +218,4 @@ export const validAmount = ( isAmountValid && (isRefundValid || transactionType !== TransactionType.REFUND) ); -} +}; diff --git a/vehicles/src/common/helper/policy-engine.helper.ts b/vehicles/src/common/helper/policy-engine.helper.ts index fcf3fd3ba..88ec6459a 100644 --- a/vehicles/src/common/helper/policy-engine.helper.ts +++ b/vehicles/src/common/helper/policy-engine.helper.ts @@ -1,6 +1,12 @@ import { Permit } from 'src/modules/permit-application-payment/permit/entities/permit.entity'; import { PolicyApplication } from '../interface/policy-application.interface'; import { PermitData } from '../interface/permit.template.interface'; +import { getAccessToken } from './gov-common-services.helper'; +import { GovCommonServices } from '../enum/gov-common-services.enum'; +import { HttpService } from '@nestjs/axios'; +import { Cache } from 'cache-manager'; +import { AxiosResponse } from 'axios'; +import { ReadPolicyConfigDto } from '../../modules/policy/dto/response/read-policy-config.dto'; export const convertToPolicyApplication = ( application: Permit, @@ -10,3 +16,27 @@ export const convertToPolicyApplication = ( permitData: JSON.parse(application.permitData.permitData) as PermitData, }; }; + +export const getActivePolicyDefinitions = async ( + httpService: HttpService, + cacheManager: Cache, +) => { + const token = await getAccessToken( + GovCommonServices.ORBC_SERVICE_ACCOUNT, + httpService, + cacheManager, + ); + const response = await httpService.axiosRef.get< + // eslint-disable-next-line @typescript-eslint/no-explicit-any + any, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + AxiosResponse, + Request + >(process.env.ORBC_POLICY_URL + '/policy-configurations', { + headers: { + Authorization: `Bearer ${token}`, + 'Content-Type': 'application/json', + }, + }); + return (await response.data.json()) as ReadPolicyConfigDto[]; +}; diff --git a/vehicles/src/modules/permit-application-payment/application/application.service.ts b/vehicles/src/modules/permit-application-payment/application/application.service.ts index 81f29aef6..5cde7daa3 100644 --- a/vehicles/src/modules/permit-application-payment/application/application.service.ts +++ b/vehicles/src/modules/permit-application-payment/application/application.service.ts @@ -1236,8 +1236,8 @@ export class ApplicationService { company: { companyId: permit.company.companyId }, }, }); - if(loaDetails.length != loaIdsToInsert.length) - throw new BadRequestException('One or more loa(s) does not exist') + if (loaDetails.length != loaIdsToInsert.length) + throw new BadRequestException('One or more loa(s) does not exist'); // Transform the permit LOA IDs from an array of numbers into individual records. const singlePermitLoa = loaIdsToInsert.map((loaId) => ({ permitId, diff --git a/vehicles/src/modules/permit-application-payment/payment/payment.service.ts b/vehicles/src/modules/permit-application-payment/payment/payment.service.ts index e4a061f1a..e511f1ced 100644 --- a/vehicles/src/modules/permit-application-payment/payment/payment.service.ts +++ b/vehicles/src/modules/permit-application-payment/payment/payment.service.ts @@ -51,7 +51,10 @@ import { } from 'src/common/helper/permit-fee.helper'; import { CfsTransactionDetail } from './entities/cfs-transaction.entity'; import { CfsFileStatus } from 'src/common/enum/cfs-file-status.enum'; -import { isAmendmentApplication, validApplicationDates } from '../../../common/helper/permit-application.helper'; +import { + isAmendmentApplication, + validApplicationDates, +} from '../../../common/helper/permit-application.helper'; import { isCfsPaymentMethodType } from 'src/common/helper/payment.helper'; import { PgApprovesStatus } from 'src/common/enum/pg-approved-status-type.enum'; import { CACHE_MANAGER } from '@nestjs/cache-manager'; @@ -513,8 +516,10 @@ export class PaymentService { // Calculate and add amount for each requested application, as per the available backend data. for (const application of applications) { //Check if each application has a valid start date and valid expiry date. - if (isCVClientUser && !validApplicationDates(application, TIMEZONE_PACIFIC)) - { + if ( + isCVClientUser && + !validApplicationDates(application, TIMEZONE_PACIFIC) + ) { throw new UnprocessableEntityException( `Atleast one of the application has invalid startDate or expiryDate.`, ); diff --git a/vehicles/src/modules/policy/dto/response/read-policy-config.dto.ts b/vehicles/src/modules/policy/dto/response/read-policy-config.dto.ts new file mode 100644 index 000000000..2f43db29c --- /dev/null +++ b/vehicles/src/modules/policy/dto/response/read-policy-config.dto.ts @@ -0,0 +1,53 @@ +import { AutoMap } from '@automapper/classes'; +import { ApiProperty } from '@nestjs/swagger'; + +export class ReadPolicyConfigDto { + /** + * Unique identifier for the policy configuration. + */ + @AutoMap() + @ApiProperty({ + example: '1', + description: 'Unique identifier for the policy configuration.', + }) + policyConfigId: number; + + /** + * JSON data representing the policy configuration. + */ + @AutoMap() + @ApiProperty({ + description: 'Policy configuration in JSON format.', + }) + policy: JSON; + + /** + * Configuration effective date. + */ + @AutoMap() + @ApiProperty({ + example: '2023-07-13T17:31:17.470Z', + description: 'Policy Configuration effective date.', + }) + effectiveDate: string; + + /** + * Indicates if the configuration is currently a draft version. + */ + @AutoMap() + @ApiProperty({ + example: true, + description: 'Indicates if the configuration is currently a draft.', + }) + isDraft: boolean; + + /** + * Description of changes made in the configuration. + */ + @AutoMap() + @ApiProperty({ + example: 'Initial release of policy configuration with updated rules', + description: 'Description of changes made in the configuration.', + }) + changeDescription: string; +} diff --git a/vehicles/src/modules/policy/dto/response/read-policy-configuration.dto.ts b/vehicles/src/modules/policy/dto/response/read-policy-configuration.dto.ts deleted file mode 100644 index 076e99328..000000000 --- a/vehicles/src/modules/policy/dto/response/read-policy-configuration.dto.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { AutoMap } from '@automapper/classes'; -import { ApiProperty } from '@nestjs/swagger'; - -export class ReadPolicyConfigurationDto { - @AutoMap() - @ApiProperty({ - description: 'Id of the policy configuration.', - example: 74, - }) - policyConfigurationId: number; - - @AutoMap() - @ApiProperty({ - description: 'The policy config json.', - required: false, - }) - policyJson: JSON; - - @AutoMap() - @ApiProperty({ - description: 'The effective date of the policy config.', - required: false, - }) - effectiveDate: string; - - @AutoMap() - @ApiProperty({ - description: 'Boolean indicator on whether the policy config is a draft.', - example: false, - required: false, - }) - isDraft: boolean; -} diff --git a/vehicles/src/modules/policy/entities/policy-configuration.entity.ts b/vehicles/src/modules/policy/entities/policy-configuration.entity.ts deleted file mode 100644 index be1696b1e..000000000 --- a/vehicles/src/modules/policy/entities/policy-configuration.entity.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { AutoMap } from '@automapper/classes'; -import { ApiProperty } from '@nestjs/swagger'; -import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'; -import { Base } from '../../common/entities/base.entity'; - -@Entity({ name: 'ORBC_POLICY_CONFIGURATION' }) -export class PolicyConfiguration extends Base { - @AutoMap() - @ApiProperty({ - example: '1', - description: 'Unique identifier for the policy configuration.', - }) - @PrimaryGeneratedColumn({ type: 'int', name: 'POLICY_CONFIGURATION_ID' }) - policyConfigurationId: string; - - @AutoMap() - @Column({ length: 8000, name: 'POLICY_JSON', nullable: true }) - policyJson: string; - - @AutoMap() - @Column({ - insert: false, - update: false, - name: 'EFFECTIVE_DATE', - nullable: true, - type: 'date', - }) - effectiveDate: string; - - @AutoMap() - @Column({ - type: 'char', - name: 'IS_DRAFT', - nullable: false, - default: true, - transformer: { - to: (value: boolean): string => (value ? 'Y' : 'N'), // Converts the boolean value to 'Y' or 'N' for storage. - from: (value: string): boolean => value === 'Y', // Converts the stored string back to a boolean. - }, - }) - isDraft: boolean; -} diff --git a/vehicles/src/modules/policy/policy.module.ts b/vehicles/src/modules/policy/policy.module.ts deleted file mode 100644 index db6787114..000000000 --- a/vehicles/src/modules/policy/policy.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Module } from '@nestjs/common'; -import { TypeOrmModule } from '@nestjs/typeorm'; -import { PolicyConfiguration } from './entities/policy-configuration.entity'; -import { PolicyService } from './policy.service'; - -@Module({ - imports: [TypeOrmModule.forFeature([PolicyConfiguration])], - providers: [PolicyService], - exports: [PolicyService], -}) -export class PolicyConfigurationModule {} diff --git a/vehicles/src/modules/policy/policy.service.ts b/vehicles/src/modules/policy/policy.service.ts deleted file mode 100644 index e95ce4ca1..000000000 --- a/vehicles/src/modules/policy/policy.service.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Mapper } from '@automapper/core'; -import { InjectMapper } from '@automapper/nestjs'; -import { Injectable } from '@nestjs/common'; -import { InjectRepository } from '@nestjs/typeorm'; -import { Repository } from 'typeorm'; -import { LogAsyncMethodExecution } from '../../common/decorator/log-async-method-execution.decorator'; -import { ReadPolicyConfigurationDto } from './dto/response/read-policy-configuration.dto'; -import { PolicyConfiguration } from './entities/policy-configuration.entity'; - -@Injectable() -export class PolicyService { - constructor( - @InjectRepository(PolicyConfiguration) - private policyConfigurationRepository: Repository, - @InjectMapper() private readonly classMapper: Mapper, - ) {} - - @LogAsyncMethodExecution() - async findAllActive(): Promise { - return this.classMapper.mapArrayAsync( - await this.policyConfigurationRepository.find({ - select: { policyJson: true }, - where: { isDraft: false }, - }), - PolicyConfiguration, - ReadPolicyConfigurationDto, - ); - } -} From 6d98b4126b6a63974ae02670713d8e937a58d607 Mon Sep 17 00:00:00 2001 From: Krishnan Subramanian Date: Tue, 29 Oct 2024 21:11:27 +0530 Subject: [PATCH 3/5] Rough structure for validation --- vehicles/package-lock.json | 47 +++++++++++++++++++ vehicles/package.json | 3 +- .../src/common/helper/policy-engine.helper.ts | 15 ++++++ .../dto/response/read-policy-config.dto.ts | 15 +++++- vehicles/tsconfig.json | 2 +- 5 files changed, 79 insertions(+), 3 deletions(-) diff --git a/vehicles/package-lock.json b/vehicles/package-lock.json index 7e112c88a..6a33b528d 100644 --- a/vehicles/package-lock.json +++ b/vehicles/package-lock.json @@ -39,6 +39,7 @@ "nest-winston": "^1.10.0", "nestjs-cls": "^4.4.1", "nestjs-typeorm-paginate": "^4.0.4", + "onroute-policy-engine": "0.2.1", "passport": "^0.7.0", "passport-jwt": "^4.0.1", "response-time": "^2.3.2", @@ -5540,6 +5541,11 @@ "node": ">=6" } }, + "node_modules/eventemitter2": { + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", + "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==" + }, "node_modules/eventemitter3": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", @@ -6436,6 +6442,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hash-it": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/hash-it/-/hash-it-6.0.0.tgz", + "integrity": "sha512-KHzmSFx1KwyMPw0kXeeUD752q/Kfbzhy6dAZrjXV9kAIXGqzGvv8vhkUqj+2MGZldTo0IBpw6v7iWE7uxsvH0w==" + }, "node_modules/hasown": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", @@ -7822,6 +7833,25 @@ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, + "node_modules/json-rules-engine": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/json-rules-engine/-/json-rules-engine-6.6.0.tgz", + "integrity": "sha512-jJ4eVCPnItetPiU3fTIzrrl3d2zeIXCcCy11dwWhN72YXBR2mByV1Vfbrvt6y2n+VFmxc6rtL/XhDqLKIwBx6g==", + "dependencies": { + "clone": "^2.1.2", + "eventemitter2": "^6.4.4", + "hash-it": "^6.0.0", + "jsonpath-plus": "^7.2.0" + } + }, + "node_modules/json-rules-engine/node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "engines": { + "node": ">=0.8" + } + }, "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -7860,6 +7890,14 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsonpath-plus": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-7.2.0.tgz", + "integrity": "sha512-zBfiUPM5nD0YZSBT/o/fbCUlCcepMIdP0CJZxM1+KgA4f2T206f6VAg9e7mX35+KlMaIc5qXW34f3BnwJ3w+RA==", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/jsonwebtoken": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", @@ -9118,6 +9156,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/onroute-policy-engine": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/onroute-policy-engine/-/onroute-policy-engine-0.2.1.tgz", + "integrity": "sha512-AGsIrq7uggF2+TsieXZ1i0vCz1mybiECVTTCfTz3WR+o9gll3rQ2ZjcDdEeoPvTYgLa0MTW0xbRs1AInBePOLg==", + "dependencies": { + "dayjs": "^1.11.10", + "json-rules-engine": "^6.5.0" + } + }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", diff --git a/vehicles/package.json b/vehicles/package.json index 2e9e7fa73..2132a635e 100644 --- a/vehicles/package.json +++ b/vehicles/package.json @@ -78,7 +78,8 @@ "swagger-ui-express": "^5.0.1", "typeorm": "^0.3.20", "uuid": "^9.0.1", - "winston": "^3.14.2" + "winston": "^3.14.2", + "onroute-policy-engine": "0.2.1" }, "devDependencies": { "@golevelup/ts-jest": "^0.5.4", diff --git a/vehicles/src/common/helper/policy-engine.helper.ts b/vehicles/src/common/helper/policy-engine.helper.ts index 88ec6459a..3716baece 100644 --- a/vehicles/src/common/helper/policy-engine.helper.ts +++ b/vehicles/src/common/helper/policy-engine.helper.ts @@ -7,6 +7,7 @@ import { HttpService } from '@nestjs/axios'; import { Cache } from 'cache-manager'; import { AxiosResponse } from 'axios'; import { ReadPolicyConfigDto } from '../../modules/policy/dto/response/read-policy-config.dto'; +import { Policy, ValidationResults } from 'onroute-policy-engine'; export const convertToPolicyApplication = ( application: Permit, @@ -40,3 +41,17 @@ export const getActivePolicyDefinitions = async ( }); return (await response.data.json()) as ReadPolicyConfigDto[]; }; + +export const validateWithPolicyEngine = async ( + permitApplication: unknown, + cacheManager: Cache, +): Promise => { + const policyDefinitions: ReadPolicyConfigDto[] = await cacheManager.get( + 'active-policy-definitions', + ); + const policy = new Policy(policyDefinitions); + const validationResults: ValidationResults = + await policy.validate(permitApplication); + + return validationResults.violations.length > 0; +}; diff --git a/vehicles/src/modules/policy/dto/response/read-policy-config.dto.ts b/vehicles/src/modules/policy/dto/response/read-policy-config.dto.ts index 2f43db29c..246117a02 100644 --- a/vehicles/src/modules/policy/dto/response/read-policy-config.dto.ts +++ b/vehicles/src/modules/policy/dto/response/read-policy-config.dto.ts @@ -1,5 +1,7 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { AutoMap } from '@automapper/classes'; import { ApiProperty } from '@nestjs/swagger'; +// import { PolicyDefinition } from 'onroute-policy-engine/types'; export class ReadPolicyConfigDto { /** @@ -19,7 +21,18 @@ export class ReadPolicyConfigDto { @ApiProperty({ description: 'Policy configuration in JSON format.', }) - policy: JSON; + policy: { + version: string; + geographicRegions: any; + permitTypes: any[]; + commonRules: any[]; + globalWeightDefaults: any; + globalSizeDefaults: any; + vehicleCategories: any; + vehicleTypes: any; + commodities: any[]; + rangeMatrices?: any[]; + }; /** * Configuration effective date. diff --git a/vehicles/tsconfig.json b/vehicles/tsconfig.json index fd39c3271..c153b4495 100644 --- a/vehicles/tsconfig.json +++ b/vehicles/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "module": "commonjs", + "module": "CommonJS", "declaration": true, "removeComments": true, "emitDecoratorMetadata": true, From e30d6fd254ddad07c602707441d3766a55e4b857 Mon Sep 17 00:00:00 2001 From: Krishnan Subramanian Date: Tue, 5 Nov 2024 14:55:39 -0800 Subject: [PATCH 4/5] With correct import --- .../dto/response/read-policy-config.dto.ts | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/vehicles/src/modules/policy/dto/response/read-policy-config.dto.ts b/vehicles/src/modules/policy/dto/response/read-policy-config.dto.ts index 246117a02..21a3bf049 100644 --- a/vehicles/src/modules/policy/dto/response/read-policy-config.dto.ts +++ b/vehicles/src/modules/policy/dto/response/read-policy-config.dto.ts @@ -1,7 +1,6 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ import { AutoMap } from '@automapper/classes'; import { ApiProperty } from '@nestjs/swagger'; -// import { PolicyDefinition } from 'onroute-policy-engine/types'; +import { PolicyDefinition } from 'onroute-policy-engine/dist/types'; export class ReadPolicyConfigDto { /** @@ -21,18 +20,7 @@ export class ReadPolicyConfigDto { @ApiProperty({ description: 'Policy configuration in JSON format.', }) - policy: { - version: string; - geographicRegions: any; - permitTypes: any[]; - commonRules: any[]; - globalWeightDefaults: any; - globalSizeDefaults: any; - vehicleCategories: any; - vehicleTypes: any; - commodities: any[]; - rangeMatrices?: any[]; - }; + policy: PolicyDefinition; /** * Configuration effective date. From 0130db672b91284e296b611ef261c77a7333c839 Mon Sep 17 00:00:00 2001 From: Krishnan Subramanian Date: Wed, 6 Nov 2024 20:20:05 -0800 Subject: [PATCH 5/5] Upgraded version of policy --- vehicles/package-lock.json | 8 ++++---- vehicles/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/vehicles/package-lock.json b/vehicles/package-lock.json index 6a33b528d..9e090b108 100644 --- a/vehicles/package-lock.json +++ b/vehicles/package-lock.json @@ -39,7 +39,7 @@ "nest-winston": "^1.10.0", "nestjs-cls": "^4.4.1", "nestjs-typeorm-paginate": "^4.0.4", - "onroute-policy-engine": "0.2.1", + "onroute-policy-engine": "0.4.2", "passport": "^0.7.0", "passport-jwt": "^4.0.1", "response-time": "^2.3.2", @@ -9157,9 +9157,9 @@ } }, "node_modules/onroute-policy-engine": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/onroute-policy-engine/-/onroute-policy-engine-0.2.1.tgz", - "integrity": "sha512-AGsIrq7uggF2+TsieXZ1i0vCz1mybiECVTTCfTz3WR+o9gll3rQ2ZjcDdEeoPvTYgLa0MTW0xbRs1AInBePOLg==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/onroute-policy-engine/-/onroute-policy-engine-0.4.2.tgz", + "integrity": "sha512-LTkCy8omP/UHO+Qw0UowiDGDBfqCPTXNmrXeYftkCQ9QBDulBQiHDLFP+W569mFsFqz4I/Cy0I40NdoiP5IUqA==", "dependencies": { "dayjs": "^1.11.10", "json-rules-engine": "^6.5.0" diff --git a/vehicles/package.json b/vehicles/package.json index 2132a635e..3505bb3f3 100644 --- a/vehicles/package.json +++ b/vehicles/package.json @@ -79,7 +79,7 @@ "typeorm": "^0.3.20", "uuid": "^9.0.1", "winston": "^3.14.2", - "onroute-policy-engine": "0.2.1" + "onroute-policy-engine": "0.4.2" }, "devDependencies": { "@golevelup/ts-jest": "^0.5.4",