mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 08:48:11 +00:00
implement rule engine module with dynamic booking evaluation, 7 entities, and Postman endpoints
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||
import { IsBoolean, IsInt, IsOptional, IsString, IsUUID, MaxLength, Min } from 'class-validator';
|
||||
|
||||
export class CreateCargoTypeDto {
|
||||
@ApiProperty({ description: 'Machine-readable code, e.g. BULK, BREAK_BULK', maxLength: 50 })
|
||||
@IsString()
|
||||
@MaxLength(50)
|
||||
code!: string;
|
||||
|
||||
@ApiProperty({ description: 'Cargo type display name', maxLength: 255 })
|
||||
@IsString()
|
||||
@MaxLength(255)
|
||||
cargoTypeName!: string;
|
||||
|
||||
@ApiPropertyOptional({ description: 'Parent group ID for hierarchical cargo types' })
|
||||
@IsOptional()
|
||||
@IsUUID()
|
||||
parentGroupId?: string;
|
||||
|
||||
@ApiPropertyOptional({ default: false })
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
showFreeTextBox?: boolean;
|
||||
|
||||
@ApiPropertyOptional({ default: false })
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
requiresDirectorApproval?: boolean;
|
||||
|
||||
@ApiPropertyOptional({ default: true })
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
isActive?: boolean;
|
||||
|
||||
@ApiPropertyOptional({ default: 1 })
|
||||
@IsOptional()
|
||||
@IsInt()
|
||||
@Min(1)
|
||||
displayOrder?: number;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||
import { IsBoolean, IsInt, IsOptional, IsString, MaxLength, Min } from 'class-validator';
|
||||
|
||||
export class CreateContainerTypeDto {
|
||||
@ApiProperty({ description: 'Size code, e.g. 20FT or 40FT', maxLength: 20 })
|
||||
@IsString()
|
||||
@MaxLength(20)
|
||||
sizeCode!: string;
|
||||
|
||||
@ApiPropertyOptional({ description: 'Human-readable description', maxLength: 100 })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(100)
|
||||
description?: string;
|
||||
|
||||
@ApiProperty({ description: 'Number of containers that fit per rail wagon (2 for 20FT, 1 for 40FT)' })
|
||||
@IsInt()
|
||||
@Min(1)
|
||||
containersPerWagon!: number;
|
||||
|
||||
@ApiPropertyOptional({ default: true })
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
isActive?: boolean;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||
import { IsBoolean, IsEnum, IsInt, IsOptional, IsString, MaxLength, Min } from 'class-validator';
|
||||
import { Freight } from '@edr/types';
|
||||
|
||||
export class CreatePriorityRuleDto {
|
||||
@ApiProperty({ enum: Freight.PriorityType, description: 'Priority type (unique per rule)' })
|
||||
@IsEnum(Freight.PriorityType)
|
||||
priorityType!: Freight.PriorityType;
|
||||
|
||||
@ApiProperty({ description: 'Human-readable rule name', maxLength: 255 })
|
||||
@IsString()
|
||||
@MaxLength(255)
|
||||
ruleName!: string;
|
||||
|
||||
@ApiPropertyOptional({ description: 'Explanation of when this rule is triggered' })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
description?: string;
|
||||
|
||||
@ApiPropertyOptional({ description: 'Technical expression describing the activation condition' })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
activationCondition?: string;
|
||||
|
||||
@ApiProperty({ description: 'Points added to booking.priorityScore when this rule matches', default: 0 })
|
||||
@IsInt()
|
||||
@Min(0)
|
||||
bonusPoints!: number;
|
||||
|
||||
@ApiPropertyOptional({ default: false })
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
isActive?: boolean;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||
import { IsBoolean, IsInt, IsOptional, IsString, MaxLength, Min } from 'class-validator';
|
||||
|
||||
export class CreateServiceTypeDto {
|
||||
@ApiProperty({ description: 'Machine-readable code, e.g. RAIL_ONLY', maxLength: 50 })
|
||||
@IsString()
|
||||
@MaxLength(50)
|
||||
code!: string;
|
||||
|
||||
@ApiProperty({ description: 'Service type display name', maxLength: 255 })
|
||||
@IsString()
|
||||
@MaxLength(255)
|
||||
serviceName!: string;
|
||||
|
||||
@ApiPropertyOptional({ description: 'Detailed description' })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
description?: string;
|
||||
|
||||
@ApiPropertyOptional({ default: true })
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
canBeBookedAlone?: boolean;
|
||||
|
||||
@ApiPropertyOptional({ default: false })
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
includesFirstMile?: boolean;
|
||||
|
||||
@ApiPropertyOptional({ default: false })
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
includesLastMile?: boolean;
|
||||
|
||||
@ApiPropertyOptional({ default: false })
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
includesCustoms?: boolean;
|
||||
|
||||
@ApiPropertyOptional({ description: 'Priority bonus points awarded when this service is used', default: 0 })
|
||||
@IsOptional()
|
||||
@IsInt()
|
||||
@Min(0)
|
||||
priorityBonusPoints?: number;
|
||||
|
||||
@ApiPropertyOptional({ default: true })
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
isActive?: boolean;
|
||||
|
||||
@ApiPropertyOptional({ default: 1 })
|
||||
@IsOptional()
|
||||
@IsInt()
|
||||
@Min(1)
|
||||
displayOrder?: number;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||
import { IsBoolean, IsOptional, IsString, MaxLength } from 'class-validator';
|
||||
|
||||
export class CreateSurchargeTypeDto {
|
||||
@ApiProperty({ description: 'Unique code, e.g. HAZARDOUS, REFRIGERATED', maxLength: 50 })
|
||||
@IsString()
|
||||
@MaxLength(50)
|
||||
code!: string;
|
||||
|
||||
@ApiProperty({ description: 'Display name', maxLength: 100 })
|
||||
@IsString()
|
||||
@MaxLength(100)
|
||||
name!: string;
|
||||
|
||||
@ApiPropertyOptional({ description: 'Description of when this surcharge type is triggered' })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
description?: string;
|
||||
|
||||
@ApiPropertyOptional({ default: true })
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
isActive?: boolean;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||
import {
|
||||
IsBoolean,
|
||||
IsEnum,
|
||||
IsNumber,
|
||||
IsOptional,
|
||||
IsString,
|
||||
IsUUID,
|
||||
Length,
|
||||
MaxLength,
|
||||
Min,
|
||||
} from 'class-validator';
|
||||
import { Freight } from '@edr/types';
|
||||
|
||||
export class CreateSurchargeDto {
|
||||
@ApiProperty({ description: 'FK to surcharge_types.id' })
|
||||
@IsUUID()
|
||||
surchargeTypeId!: string;
|
||||
|
||||
@ApiProperty({ description: 'Display name for this surcharge line item', maxLength: 255 })
|
||||
@IsString()
|
||||
@MaxLength(255)
|
||||
feeName!: string;
|
||||
|
||||
@ApiPropertyOptional({ description: 'Human-readable description of when this surcharge is triggered' })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
triggerDescription?: string;
|
||||
|
||||
@ApiProperty({ enum: Freight.CalculationMethod, default: Freight.CalculationMethod.PER_TON })
|
||||
@IsEnum(Freight.CalculationMethod)
|
||||
calculationMethod!: Freight.CalculationMethod;
|
||||
|
||||
@ApiProperty({ description: 'Rate amount (per ton, flat, or percentage)' })
|
||||
@IsNumber()
|
||||
@Min(0)
|
||||
rate!: number;
|
||||
|
||||
@ApiProperty({ description: 'ISO 4217 currency code', default: 'USD' })
|
||||
@IsString()
|
||||
@Length(3, 3)
|
||||
currency!: string;
|
||||
|
||||
@ApiPropertyOptional({ default: false })
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
applyToRail?: boolean;
|
||||
|
||||
@ApiPropertyOptional({ default: false })
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
applyToFirstMile?: boolean;
|
||||
|
||||
@ApiPropertyOptional({ default: false })
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
applyToLastMile?: boolean;
|
||||
|
||||
@ApiPropertyOptional({ default: true })
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
isActive?: boolean;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||
import { IsBoolean, IsEnum, IsNumber, IsOptional, IsUUID, Min } from 'class-validator';
|
||||
import { Freight } from '@edr/types';
|
||||
|
||||
export class CreateWeightLimitRuleDto {
|
||||
@ApiProperty({ description: 'FK to container_types.id' })
|
||||
@IsUUID()
|
||||
containerTypeId!: string;
|
||||
|
||||
@ApiProperty({ enum: Freight.TradeDirection, description: 'Trade direction this rule applies to' })
|
||||
@IsEnum(Freight.TradeDirection)
|
||||
tradeDirection!: Freight.TradeDirection;
|
||||
|
||||
@ApiProperty({ description: 'Maximum allowed weight in tons before surcharge is applied' })
|
||||
@IsNumber()
|
||||
@Min(0)
|
||||
maxWeightTons!: number;
|
||||
|
||||
@ApiProperty({ description: 'Weight at which a warning is issued (must be ≤ maxWeightTons)' })
|
||||
@IsNumber()
|
||||
@Min(0)
|
||||
warningThresholdTons!: number;
|
||||
|
||||
@ApiPropertyOptional({ enum: Freight.ExceededAction, default: Freight.ExceededAction.WARNING_ONLY })
|
||||
@IsOptional()
|
||||
@IsEnum(Freight.ExceededAction)
|
||||
exceededAction?: Freight.ExceededAction;
|
||||
|
||||
@ApiPropertyOptional({ description: 'FK to surcharges.id — surcharge billed when max is exceeded' })
|
||||
@IsOptional()
|
||||
@IsUUID()
|
||||
surchargeId?: string;
|
||||
|
||||
@ApiPropertyOptional({ default: true })
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
isActive?: boolean;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import { PartialType } from '@nestjs/mapped-types';
|
||||
import { CreateCargoTypeDto } from './create-cargo-type.dto';
|
||||
|
||||
export class UpdateCargoTypeDto extends PartialType(CreateCargoTypeDto) {}
|
||||
@@ -0,0 +1,4 @@
|
||||
import { PartialType } from '@nestjs/mapped-types';
|
||||
import { CreateContainerTypeDto } from './create-container-type.dto';
|
||||
|
||||
export class UpdateContainerTypeDto extends PartialType(CreateContainerTypeDto) {}
|
||||
@@ -0,0 +1,4 @@
|
||||
import { PartialType } from '@nestjs/mapped-types';
|
||||
import { CreatePriorityRuleDto } from './create-priority-rule.dto';
|
||||
|
||||
export class UpdatePriorityRuleDto extends PartialType(CreatePriorityRuleDto) {}
|
||||
@@ -0,0 +1,4 @@
|
||||
import { PartialType } from '@nestjs/mapped-types';
|
||||
import { CreateServiceTypeDto } from './create-service-type.dto';
|
||||
|
||||
export class UpdateServiceTypeDto extends PartialType(CreateServiceTypeDto) {}
|
||||
@@ -0,0 +1,4 @@
|
||||
import { PartialType } from '@nestjs/mapped-types';
|
||||
import { CreateSurchargeTypeDto } from './create-surcharge-type.dto';
|
||||
|
||||
export class UpdateSurchargeTypeDto extends PartialType(CreateSurchargeTypeDto) {}
|
||||
@@ -0,0 +1,4 @@
|
||||
import { PartialType } from '@nestjs/mapped-types';
|
||||
import { CreateSurchargeDto } from './create-surcharge.dto';
|
||||
|
||||
export class UpdateSurchargeDto extends PartialType(CreateSurchargeDto) {}
|
||||
@@ -0,0 +1,4 @@
|
||||
import { PartialType } from '@nestjs/mapped-types';
|
||||
import { CreateWeightLimitRuleDto } from './create-weight-limit-rule.dto';
|
||||
|
||||
export class UpdateWeightLimitRuleDto extends PartialType(CreateWeightLimitRuleDto) {}
|
||||
Reference in New Issue
Block a user