onroute-policy-engine
v2.11.1
Published
Policy Engine library for commercial vehicle permitting
Keywords
Readme
onRouteBC Policy Engine
A comprehensive JSON-based rules engine for validating commercial vehicle permit applications against British Columbia's transportation policy regulations.
Overview
The onRouteBC Policy Engine is a sophisticated validation library designed to ensure commercial vehicle permit applications comply with British Columbia's transportation regulations. It provides a flexible, rule-based system that can validate complex vehicle configurations, weight distributions, axle arrangements, and permit requirements.
Key Features
- Comprehensive Vehicle Validation: Validates vehicle configurations, weights, dimensions, and axle arrangements
- Policy-Driven Rules: Uses JSON-based policy definitions for flexible rule configuration
- Bridge Formula Calculations: Implements provincial bridge formula requirements for axle group weight limits
- Tire Load Validation: Ensures tire configurations meet safety and regulatory requirements
- Weight Distribution Checks: Validates proper weight distribution across vehicle axles
- Permit Type Support: Handles multiple permit types including Term Oversize, Single Trip Oversize, and Motive Fuel
- Commodity-Based Validation: Supports commodity-specific permit requirements
- Extensible Architecture: Built on json-rules-engine with custom operators for complex validations
Installation
npm install onroute-policy-engineQuick Start
import Policy from 'onroute-policy-engine';
// Load your policy definition
const policyDefinition = require('./policy-definition.json');
// Create policy instance
const policy = new Policy(policyDefinition);
// Validate a permit application
const permitApplication = {
permitType: 'TROS',
permitData: {
// Your permit data here
}
};
const results = await policy.validate(permitApplication);
console.log(results);Core Concepts
Policy Definition
The policy engine uses a JSON-based policy definition that describes:
- Permit Types: Different types of permits (TROS, STOS, MFP, etc.)
- Vehicle Types: Power units and trailers with their characteristics
- Validation Rules: Complex rules for weight, dimension, and configuration validation
- Commodities: Cargo types that affect permit requirements
Vehicle Configuration
A vehicle configuration consists of:
- Power Units: The primary vehicle (truck, tractor, etc.)
- Trailers: Additional units being towed
- Axle Configurations: Detailed axle arrangements with weights and dimensions
Validation Results
The engine returns comprehensive validation results including:
- Policy Violations: Specific rule violations with detailed messages
- Informational Messages: Guidance and recommendations
- Axle Calculations: Bridge formula and weight distribution results
API Reference
Main Policy Class
class Policy {
constructor(policyDefinition: PolicyDefinition)
// Core validation
validate(permitApplication: PermitApplication): Promise<ValidationResults>
// Vehicle configuration validation
runAxleCalculation(
vehicleConfiguration: string[],
axleConfiguration: AxleConfiguration[],
licensedGVW: number
): AxleCalcResults
// Policy information
getPermitTypes(): Map<string, string>
getCommodities(permitTypeId?: string): Map<string, string>
getPowerUnitTypes(): Map<string, string>
getTrailerTypes(): Map<string, string>
// Vehicle configuration helpers
getNextPermittableVehicles(
permitTypeId: string,
commodityId: string,
currentConfiguration: string[]
): Map<string, string>
// Weight and dimension calculations
getDefaultPowerUnitWeight(vehicleType: string, axleCode: number): WeightDimension[]
getDefaultTrailerWeight(vehicleType: string, axles: number): TrailerWeightDimension[]
calculateBridge(axleConfiguration: AxleConfiguration[]): BridgeCalculationResult[]
}Key Types
interface PermitApplication {
permitType: string;
permitData: any;
}
interface ValidationResults {
results: ValidationResult[];
summary: {
totalViolations: number;
totalWarnings: number;
totalInfo: number;
};
}
interface AxleConfiguration {
numberOfAxles: number;
numberOfTires?: number;
tireSize?: number;
axleUnitWeight: number;
axleSpread?: number;
}Usage Examples
Basic Permit Validation
import Policy from 'onroute-policy-engine';
const policy = new Policy(policyDefinition);
const permitApp = {
permitType: 'TROS',
permitData: {
vehicleConfiguration: ['TRKTRAC', 'SEMITRL'],
axleConfiguration: [
{ numberOfAxles: 2, axleUnitWeight: 12000, numberOfTires: 4, tireSize: 445 },
{ numberOfAxles: 3, axleUnitWeight: 34000, numberOfTires: 12, tireSize: 445 },
{ numberOfAxles: 3, axleUnitWeight: 34000, numberOfTires: 12, tireSize: 445 }
],
licensedGVW: 63500
}
};
const results = await policy.validate(permitApp);
console.log(`Validation completed with ${results.violations.length} violations`);Axle Calculation Validation
// Validate axle configuration against policy rules
const axleResults = policy.runAxleCalculation(
['TRKTRAC', 'SEMITRL'],
[
{ numberOfAxles: 2, axleUnitWeight: 12000, numberOfTires: 4, tireSize: 445 },
{ numberOfAxles: 3, axleUnitWeight: 34000, numberOfTires: 12, tireSize: 445 },
{ numberOfAxles: 3, axleUnitWeight: 34000, numberOfTires: 12, tireSize: 445 }
],
63500
);
console.log('Axle validation results:', axleResults.results);Getting Available Options
// Get all available permit types
const permitTypes = policy.getPermitTypes();
console.log('Available permit types:', Array.from(permitTypes.entries()));
// Get commodities for a specific permit type
const commodities = policy.getCommodities('TROS');
console.log('TROS commodities:', Array.from(commodities.entries()));
// Get valid next vehicles for a configuration
const nextVehicles = policy.getNextPermittableVehicles(
'STOS',
'IMCONTN',
['TRKTRAC']
);
console.log('Valid next vehicles:', Array.from(nextVehicles.entries()));Policy Check Rules
The engine implements several key validation rules:
- Bridge Formula Check: Validates axle group weights based on axle spacing
- Number of Wheels Per Axle: Ensures valid tire counts per axle unit
- Permittable Weight Check: Validates axle unit weights against limits
- Minimum Steer Axle Weight: Ensures proper front axle weight distribution
- Minimum Drive Axle Weight: Validates drive axle weight requirements
- Maximum Tire Load: Checks tire load capacity based on size and quantity
For detailed information about these rules, see Policy Check Rules Documentation.
Development
Prerequisites
- Node.js 18+
- TypeScript 5.7+
- npm or yarn
Setup
# Clone the repository
git clone https://github.com/bcgov/onroutebc-policy-engine.git
cd onroutebc-policy-engine
# Install dependencies
npm install
# Build the project
npm run build
# Run tests
npm test
# Run linting
npm run lintProject Structure
src/
├── enum/ # Enumerations and constants
├── helper/ # Helper functions and utilities
├── types/ # TypeScript type definitions
├── _examples/ # Usage examples and demos
├── _test/ # Test data and configurations
├── policy-engine.ts # Main policy engine implementation
├── validation-result.ts # Validation result types
└── index.ts # Public API exportsBuilding
# Clean build
npm run clean-build
# Development build
npm run buildDocumentation
- Policy Configuration Reference - Detailed policy definition format
- Validation Result Reference - Understanding validation results
- Basic Client-Server Flow - Integration patterns
- Policy Check Rules - Detailed explanation of validation rules
Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/new-feature) - Commit your changes (
git commit -m 'Add new feature') - Push to the branch (
git push origin feature/new-feature) - Open a Pull Request
Code Style
- Follow TypeScript best practices
- Use ESLint and Prettier for code formatting
- Write comprehensive tests for new features
- Update documentation for API changes
Testing
# Run all tests
npm test
# Run tests with coverage
npm test -- --coverage
# Run specific test file
npm test -- validate-tros.spec.tsUsing npm link for local policy engine changes
Use this when you want this frontend example, including the permit form application flow, to pick up local onroute-policy-engine changes without publishing a package.
# policy engine repo route
# note: linking only works the BUILT files! so you must run `npm run build` after pulling down any PR, making any code changes, etc, to the policy engine
npm run build
# npm run build -- --watch # optional for active library development; rebuilds dist on change
npm link
# this example app
cd src/_examples/usage/react-frontend-example
npm link onroute-policy-engine
npm run dev
# OPTIONAL - Now assume you have further changes to make to policy engine, or are switching policy engine branches, etc. To bring those changes in, you would:
# in PE repo, after changes are made
npm run build
# in application repo, after build is done
kill the npm run dev
npm run dev
# now that you've built + restarted the dev server, changes should be represented.If Chrome DevTools shows import/module resolution issues after linking, add this to vite.config.ts:
export default defineConfig({
resolve: {
preserveSymlinks: true,
},
});License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Support
For questions, issues, or contributions:
- Issues: GitHub Issues
- Documentation: Check the docs directory
- Examples: See src/_examples for usage examples
Related Projects
- json-rules-engine - Core rules engine functionality
- onRouteBC - British Columbia's commercial vehicle permitting system
Note: This policy engine is specifically designed for British Columbia's commercial vehicle regulations. Ensure compliance with local regulations when adapting for other jurisdictions.
