Skip to content

Commit

Permalink
feat: Add full validation rules and vehicle types for TROS/TROW (#1449)
Browse files Browse the repository at this point in the history
  • Loading branch information
john-fletcher-aot authored Jun 27, 2024
1 parent 40bf970 commit 61b0559
Show file tree
Hide file tree
Showing 15 changed files with 867 additions and 50 deletions.
23 changes: 16 additions & 7 deletions policy/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions policy/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
},
"dependencies": {
"dayjs": "^1.11.10",
"flattie": "^1.1.1",
"json-rules-engine": "^6.5.0"
},
"jest": {
Expand Down
9 changes: 9 additions & 0 deletions policy/src/enum/permit-app-info.enum.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* This enum represents a subset of commonly-used paths and
* other information in permit applications which may be
* referenced from within source code.
*/
export enum PermitAppInfo {
PermitStartDate = 'permitData.startDate',
PermitDateFormat = 'YYYY-MM-DD',
}
25 changes: 11 additions & 14 deletions policy/src/helper/facts.helper.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import dayjs from 'dayjs';
import { Engine } from 'json-rules-engine';
import { flattie } from 'flattie';
import PermitApplication from '../type/permit-application.type';
import { PermitFacts } from '../interface/facts.interface';
import { PermitAppInfo } from '../enum/permit-app-info.enum';
import { PolicyFacts } from '../enum/facts.enum';

/**
Expand All @@ -10,16 +12,16 @@ import { PolicyFacts } from '../enum/facts.enum';
* @param engine json-rules-engine Engine instance to add facts to.
*/
export function addRuntimeFacts(engine: Engine): void {
const today: string = dayjs().format('YYYY-MM-DD');
const today: string = dayjs().format(PermitAppInfo.PermitDateFormat.toString());
engine.addFact(PolicyFacts.ValidationDate.toString(), today);

// Will be either 365 or 366, for use when comparing against
// duration for 1 year permits.
engine.addFact(
PolicyFacts.DaysInPermitYear.toString(),
async function (params, almanac) {
const startDate: string = await almanac.factValue('startDate');
const dateFrom = dayjs(startDate, 'YYYY-MM-DD');
const startDate: string = await almanac.factValue(PermitAppInfo.PermitStartDate.toString());
const dateFrom = dayjs(startDate, PermitAppInfo.PermitDateFormat.toString());
return dateFrom.diff(dateFrom.add(1, 'year'), 'day');
},
);
Expand All @@ -34,17 +36,12 @@ export function addRuntimeFacts(engine: Engine): void {
export function transformPermitFacts(
permitApplication: PermitApplication,
): PermitFacts {
const permitFacts: PermitFacts = {};
permitFacts.companyName = permitApplication?.permitData?.companyName;
permitFacts.duration = permitApplication?.permitData?.permitDuration;
permitFacts.permitType = permitApplication?.permitType;
permitFacts.startDate = permitApplication?.permitData?.startDate;
permitFacts.vehicleIdentificationNumber =
permitApplication?.permitData?.vehicleDetails?.vin;
permitFacts.vehiclePlate =
permitApplication?.permitData?.vehicleDetails?.plate;
permitFacts.vehicleType =
permitApplication?.permitData?.vehicleDetails?.vehicleSubType;
// Flatten the permit application so all properties can be accessed
// by key
const permitFacts: PermitFacts = flattie(permitApplication);

// Add the app itself as a fact to be used by more complex rules
permitFacts.app = permitApplication;

return permitFacts;
}
1 change: 1 addition & 0 deletions policy/src/interface/facts.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ export interface PermitFacts {
vehicleIdentificationNumber?: string;
vehiclePlate?: string;
vehicleType?: string;
app?: object;
}
7 changes: 4 additions & 3 deletions policy/src/rule-operator/custom-operators.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { Operator } from 'json-rules-engine';
import { PermitAppInfo } from '../enum/permit-app-info.enum';
import dayjs from 'dayjs';

function stringValidator(a: any): boolean {
return typeof a === 'string';
}

function dateStringValidator(a: any): boolean {
const d = dayjs(a, 'YYYY-MM-DD');
const d = dayjs(a, PermitAppInfo.PermitDateFormat.toString());
return d.isValid();
}

Expand All @@ -24,8 +25,8 @@ CustomOperators.push(
new Operator(
'dateLessThan',
(a: string, b: string) => {
const firstDate = dayjs(a, 'YYYY-MM-DD');
const secondDate = dayjs(b, 'YYYY-MM-DD');
const firstDate = dayjs(a, PermitAppInfo.PermitDateFormat.toString());
const secondDate = dayjs(b, PermitAppInfo.PermitDateFormat.toString());
return firstDate.diff(secondDate) < 0;
},
dateStringValidator,
Expand Down
1 change: 1 addition & 0 deletions policy/src/type/permit-application.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type PermitCommodity = {

type PermitData = {
companyName: string;
doingBusinessAs?: string;
clientNumber: string;
permitDuration: number;
commodities: Array<PermitCommodity>;
Expand Down
4 changes: 2 additions & 2 deletions policy/test/permit-app/valid-tros-30day.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ export const validTros30Day: PermitApplication = {
phone1Extension: null,
phone2: '(250) 555-4321',
phone2Extension: null,
email: 'bryan.lane@gov.bc.ca',
additionalEmail: 'michael.melo@gov.bc.ca',
email: 'chief.baker@gov.bc.ca',
additionalEmail: 'baker.chief@gov.bc.ca',
fax: null,
},
mailingAddress: {
Expand Down
69 changes: 69 additions & 0 deletions policy/test/permit-app/valid-trow-120day.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import PermitApplication from '../../src/type/permit-application.type';

export const validTrow120Day: PermitApplication = {
permitType: 'TROW',
permitData: {
"companyName": "Chief, Master",
"doingBusinessAs": "DBA test 1233",
"clientNumber": "B3-000102-187",
"permitDuration": 120,
"commodities": [
{
"description": "General Permit Conditions",
"condition": "CVSE-1000",
"conditionLink": "https://www.th.gov.bc.ca/forms/getForm.aspx?formId=1251",
"checked": true,
"disabled": true
},
{
"description": "Permit Scope and Limitation",
"condition": "CVSE-1070",
"conditionLink": "https://www.th.gov.bc.ca/forms/getForm.aspx?formId=1261",
"checked": true,
"disabled": true
},
{
"description": "Highways and Restrictive Load Limits",
"condition": "CVSE-1011",
"conditionLink": "https://www.th.gov.bc.ca/forms/getForm.aspx?formId=1258",
"checked": true,
"disabled": true
}
],
"contactDetails": {
"firstName": "Arbiter",
"lastName": "Flood",
"phone1": "(250) 555-1234",
"phone1Extension": null,
"phone2": null,
"phone2Extension": null,
"email": "[email protected]",
"additionalEmail": "[email protected]",
"fax": null
},
"mailingAddress": {
"addressLine1": "1000 Main Street",
"addressLine2": null,
"city": "Victoria",
"provinceCode": "BC",
"countryCode": "CA",
"postalCode": "V8V 8V8"
},
"vehicleDetails": {
"vehicleId": "108",
"unitNumber": "-",
"vin": "898989",
"plate": "V6R4E3",
"make": "FORD",
"year": 2007,
"countryCode": "US",
"provinceCode": "ME",
"vehicleType": "powerUnit",
"vehicleSubType": "GRADERS",
"saveVehicle": false
},
"feeSummary": "120",
"startDate": "2024-05-15",
"expiryDate": "2024-09-11"
}
};
14 changes: 7 additions & 7 deletions policy/test/policy-config/all-event-types.sample.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const allEventTypes: PolicyDefinition = {
{
conditions: {
not: {
fact: 'duration',
fact: 'permitData.permitDuration',
operator: 'equal',
value: 31,
},
Expand All @@ -38,7 +38,7 @@ export const allEventTypes: PolicyDefinition = {
{
conditions: {
not: {
fact: 'duration',
fact: 'permitData.permitDuration',
operator: 'equal',
value: 32,
},
Expand All @@ -53,7 +53,7 @@ export const allEventTypes: PolicyDefinition = {
{
conditions: {
not: {
fact: 'duration',
fact: 'permitData.permitDuration',
operator: 'equal',
value: 33,
},
Expand All @@ -68,7 +68,7 @@ export const allEventTypes: PolicyDefinition = {
{
conditions: {
not: {
fact: 'duration',
fact: 'permitData.permitDuration',
operator: 'equal',
value: 34,
},
Expand All @@ -83,7 +83,7 @@ export const allEventTypes: PolicyDefinition = {
{
conditions: {
not: {
fact: 'duration',
fact: 'permitData.permitDuration',
operator: 'equal',
value: 35,
},
Expand All @@ -98,7 +98,7 @@ export const allEventTypes: PolicyDefinition = {
{
conditions: {
not: {
fact: 'duration',
fact: 'permitData.permitDuration',
operator: 'equal',
value: 35,
},
Expand All @@ -110,7 +110,7 @@ export const allEventTypes: PolicyDefinition = {
{
conditions: {
not: {
fact: 'duration',
fact: 'permitData.permitDuration',
operator: 'equal',
value: 36,
},
Expand Down
10 changes: 5 additions & 5 deletions policy/test/policy-config/five-types.sample.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const fiveTypes: PolicyDefinition = {
{
conditions: {
not: {
fact: 'companyName',
fact: 'permitData.companyName',
operator: 'stringMinimumLength',
value: 1,
},
Expand All @@ -36,7 +36,7 @@ export const fiveTypes: PolicyDefinition = {
conditions: {
any: [
{
fact: 'startDate',
fact: 'permitData.startDate',
operator: 'dateLessThan',
value: {
fact: 'validationDate',
Expand All @@ -54,7 +54,7 @@ export const fiveTypes: PolicyDefinition = {
{
conditions: {
not: {
fact: 'vehicleIdentificationNumber',
fact: 'permitData.vehicleDetails.vin',
operator: 'regex',
value: '^[a-zA-Z0-9]{6}$',
},
Expand Down Expand Up @@ -89,14 +89,14 @@ export const fiveTypes: PolicyDefinition = {
all: [
{
not: {
fact: 'duration',
fact: 'permitData.permitDuration',
operator: 'in',
value: [30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330],
},
},
{
not: {
fact: 'duration',
fact: 'permitData.permitDuration',
operator: 'equal',
value: {
fact: 'daysInPermitYear',
Expand Down
Loading

0 comments on commit 61b0559

Please sign in to comment.