1
0
forked from Yara724/api

blame and claim refactored

This commit is contained in:
2026-02-24 12:19:25 +03:30
parent 0d8858f458
commit 35732dd70a
81 changed files with 11603 additions and 77 deletions

View File

@@ -0,0 +1,510 @@
/**
* Swagger example bodies for CLAIM workflow step management
*/
export const createClaimWorkflowStepExamples = {
claimCreated: {
summary: 'Claim Created Step',
value: {
stepKey: 'CLAIM_CREATED',
type: 'CLAIM',
stepNumber: 1,
isActive: true,
stepName_fa: 'ایجاد درخواست خسارت',
stepName_en: 'Create Claim Request',
description_fa: 'ایجاد درخواست خسارت از پرونده تعیین تقصیر تکمیل شده - فقط طرف آسیب‌دیده می‌تواند درخواست دهد',
description_en: 'Create claim request from completed blame case - only damaged party can proceed',
category: 'CLAIM',
requiredPreviousSteps: [],
nextPossibleSteps: ['SELECT_OUTER_PARTS'],
allowedRoles: ['user'],
estimatedDuration: 1,
fields: [],
metadata: {
icon: 'file-plus',
color: '#8B5CF6',
requiresBlameCase: true,
blameStatusRequired: 'COMPLETED',
bothPartiesMustAccept: true,
userMustBeDamagedParty: true
}
}
},
selectOuterParts: {
summary: 'Select Outer Parts Step',
value: {
stepKey: 'SELECT_OUTER_PARTS',
type: 'CLAIM',
stepNumber: 2,
isActive: true,
stepName_fa: 'انتخاب قطعات خارجی آسیب‌دیده',
stepName_en: 'Select Damaged Outer Parts',
description_fa: 'انتخاب قطعات خارجی خودرو که در حادثه آسیب دیده‌اند (کاپوت، درب‌ها، سپر و...)',
description_en: 'Select vehicle outer parts damaged in the accident (hood, doors, bumpers, etc.)',
category: 'CLAIM',
requiredPreviousSteps: ['CLAIM_CREATED'],
nextPossibleSteps: ['SELECT_OTHER_PARTS'],
allowedRoles: ['user'],
estimatedDuration: 3,
fields: [
{
id: '67fa10c259e15f231a2d1001',
name_fa: 'قطعات خارجی',
name_en: 'outerParts',
label_fa: 'قطعات خارجی آسیب‌دیده',
label_en: 'Damaged Outer Parts',
placeholder_fa: 'قطعات خارجی آسیب‌دیده را انتخاب کنید',
placeholder_en: 'Select damaged outer parts',
value: [
{ label_fa: 'کاپوت', label_en: 'Hood', value: 'hood' },
{ label_fa: 'درب جلو راست', label_en: 'Front Right Door', value: 'front_right_door' },
{ label_fa: 'درب جلو چپ', label_en: 'Front Left Door', value: 'front_left_door' },
{ label_fa: 'درب عقب راست', label_en: 'Rear Right Door', value: 'rear_right_door' },
{ label_fa: 'درب عقب چپ', label_en: 'Rear Left Door', value: 'rear_left_door' },
{ label_fa: 'سپر جلو', label_en: 'Front Bumper', value: 'front_bumper' },
{ label_fa: 'سپر عقب', label_en: 'Rear Bumper', value: 'rear_bumper' },
{ label_fa: 'گلگیر جلو راست', label_en: 'Front Right Fender', value: 'front_right_fender' },
{ label_fa: 'گلگیر جلو چپ', label_en: 'Front Left Fender', value: 'front_left_fender' },
{ label_fa: 'گلگیر عقب راست', label_en: 'Rear Right Fender', value: 'rear_right_fender' },
{ label_fa: 'گلگیر عقب چپ', label_en: 'Rear Left Fender', value: 'rear_left_fender' },
{ label_fa: 'صندوق عقب', label_en: 'Trunk', value: 'trunk' },
{ label_fa: 'سقف', label_en: 'Roof', value: 'roof' }
],
dataType: 'multiselect',
required: true,
order: 1,
isActive: true,
validation: {
minItems: 1,
maxItems: 13
}
}
],
metadata: {
icon: 'car',
color: '#3B82F6',
requiresMultipleSelection: true
}
}
},
selectOtherParts: {
summary: 'Select Other Parts & Bank Info Step',
value: {
stepKey: 'SELECT_OTHER_PARTS',
type: 'CLAIM',
stepNumber: 3,
isActive: true,
stepName_fa: 'انتخاب سایر قطعات و اطلاعات بانکی',
stepName_en: 'Select Other Parts & Bank Information',
description_fa: 'انتخاب سایر قطعات آسیب‌دیده (غیر از بدنه)، شماره شبا و کد ملی بیمه‌گذار',
description_en: 'Select other damaged parts (non-body), Sheba number and insurer national code',
category: 'CLAIM',
requiredPreviousSteps: ['SELECT_OUTER_PARTS'],
nextPossibleSteps: ['UPLOAD_REQUIRED_DOCUMENTS'],
allowedRoles: ['user'],
estimatedDuration: 4,
fields: [
{
id: '67fa10c259e15f231a2d1002',
name_fa: 'سایر قطعات',
name_en: 'otherParts',
label_fa: 'سایر قطعات آسیب‌دیده',
label_en: 'Other Damaged Parts',
placeholder_fa: 'سایر قطعات آسیب‌دیده را انتخاب کنید',
placeholder_en: 'Select other damaged parts',
value: [
{ label_fa: 'موتور', label_en: 'Engine', value: 'engine' },
{ label_fa: 'سیستم تعلیق', label_en: 'Suspension', value: 'suspension' },
{ label_fa: 'سیستم ترمز', label_en: 'Brake System', value: 'brake_system' },
{ label_fa: 'سیستم برق', label_en: 'Electrical System', value: 'electrical' },
{ label_fa: 'رادیاتور', label_en: 'Radiator', value: 'radiator' },
{ label_fa: 'گیربکس', label_en: 'Transmission', value: 'transmission' },
{ label_fa: 'اگزوز', label_en: 'Exhaust', value: 'exhaust' },
{ label_fa: 'چراغ جلو', label_en: 'Headlight', value: 'headlight' },
{ label_fa: 'چراغ عقب', label_en: 'Taillight', value: 'taillight' },
{ label_fa: 'آینه', label_en: 'Mirror', value: 'mirror' },
{ label_fa: 'شیشه', label_en: 'Glass', value: 'glass' }
],
dataType: 'multiselect',
required: false,
order: 1,
isActive: true,
validation: {
minItems: 0,
maxItems: 11
}
},
{
id: '67fa10c259e15f231a2d1003',
name_fa: 'شماره شبا',
name_en: 'shebaNumber',
label_fa: 'شماره شبا',
label_en: 'Sheba Number',
placeholder_fa: 'شماره شبا (24 رقم بدون IR)',
placeholder_en: 'Sheba number (24 digits without IR)',
value: null,
dataType: 'string',
required: true,
order: 2,
isActive: true,
validation: {
pattern: '^[0-9]{24}$',
minLength: 24,
maxLength: 24
}
},
{
id: '67fa10c259e15f231a2d1004',
name_fa: 'کد ملی مالک',
name_en: 'nationalCodeOfOwner',
label_fa: 'کد ملی مالک',
label_en: 'National Code of Owner',
placeholder_fa: 'کد ملی 10 رقمی مالک',
placeholder_en: '10-digit national code of owner',
value: null,
dataType: 'string',
required: true,
order: 3,
isActive: true,
validation: {
pattern: '^[0-9]{10}$',
minLength: 10,
maxLength: 10
}
}
],
metadata: {
icon: 'list',
color: '#10B981',
requiresBankInfo: true
}
}
},
uploadRequiredDocuments: {
summary: 'Upload Required Documents Step',
value: {
stepKey: 'UPLOAD_REQUIRED_DOCUMENTS',
type: 'CLAIM',
stepNumber: 4,
isActive: true,
stepName_fa: 'آپلود مدارک مورد نیاز',
stepName_en: 'Upload Required Documents',
description_fa: 'آپلود مدارک مورد نیاز برای بررسی خسارت (لیست داینامیک بر اساس قطعات انتخاب شده)',
description_en: 'Upload required documents for claim review (dynamic list based on selected parts)',
category: 'CLAIM',
requiredPreviousSteps: ['SELECT_OTHER_PARTS'],
nextPossibleSteps: ['CAPTURE_PART_DAMAGES'],
allowedRoles: ['user'],
estimatedDuration: 5,
fields: [],
metadata: {
icon: 'upload',
color: '#F59E0B',
dynamicFields: true,
requiresAPI: '/claim-request-management/car-part-image-required/:claimRequestID',
note: 'لیست مدارک به صورت داینامیک از API دریافت می‌شود'
}
}
},
capturePartDamages: {
summary: 'Capture Part Damages Step',
value: {
stepKey: 'CAPTURE_PART_DAMAGES',
type: 'CLAIM',
stepNumber: 5,
isActive: true,
stepName_fa: 'ثبت تصاویر آسیب‌های قطعات',
stepName_en: 'Capture Part Damages',
description_fa: 'ثبت تصاویر آسیب برای هر قطعه (یک درخواست به ازای هر قطعه)',
description_en: 'Capture damage images for each part (one request per part)',
category: 'CLAIM',
requiredPreviousSteps: ['UPLOAD_REQUIRED_DOCUMENTS'],
nextPossibleSteps: ['USER_SUBMISSION_COMPLETE'],
allowedRoles: ['user'],
estimatedDuration: 10,
fields: [],
metadata: {
icon: 'camera',
color: '#EF4444',
dynamicFields: true,
requiresAPI: '/claim-request-management/capture-car-part-damage/:claimRequestID/:partId',
requiresCamera: true,
multipleRequests: true,
note: 'برای هر قطعه یک درخواست جداگانه ارسال می‌شود'
}
}
},
userSubmissionComplete: {
summary: 'User Submission Complete',
value: {
stepKey: 'USER_SUBMISSION_COMPLETE',
type: 'CLAIM',
stepNumber: 6,
isActive: true,
stepName_fa: 'تکمیل ثبت اطلاعات کاربر',
stepName_en: 'User Submission Complete',
description_fa: 'اطلاعات کاربر به طور کامل ثبت شد و در انتظار بررسی کارشناس خسارت',
description_en: 'User information completed, waiting for damage expert review',
category: 'CLAIM',
requiredPreviousSteps: ['CAPTURE_PART_DAMAGES'],
nextPossibleSteps: ['EXPERT_DAMAGE_ASSESSMENT'],
allowedRoles: ['user', 'damage_expert', 'admin'],
estimatedDuration: 0,
fields: [],
metadata: {
icon: 'check-circle',
color: '#10B981',
readOnly: true,
isSystemStep: true
}
}
},
expertDamageAssessment: {
summary: 'Expert Damage Assessment',
value: {
stepKey: 'EXPERT_DAMAGE_ASSESSMENT',
type: 'CLAIM',
stepNumber: 7,
isActive: true,
stepName_fa: 'ارزیابی خسارت توسط کارشناس',
stepName_en: 'Expert Damage Assessment',
description_fa: 'بررسی و ارزیابی خسارت توسط کارشناس خسارت',
description_en: 'Damage review and assessment by damage expert',
category: 'EXPERT',
requiredPreviousSteps: ['USER_SUBMISSION_COMPLETE'],
nextPossibleSteps: ['EXPERT_COST_EVALUATION'],
allowedRoles: ['damage_expert', 'admin'],
estimatedDuration: 30,
fields: [
{
id: '67fa10c259e15f231a2d1005',
name_fa: 'وضعیت ارزیابی',
name_en: 'assessmentStatus',
label_fa: 'وضعیت ارزیابی',
label_en: 'Assessment Status',
placeholder_fa: 'وضعیت ارزیابی را انتخاب کنید',
placeholder_en: 'Select assessment status',
value: [
{ label_fa: 'تایید شده', label_en: 'Approved', value: 'approved' },
{ label_fa: 'نیاز به بازنگری', label_en: 'Needs Revision', value: 'needs_revision' },
{ label_fa: 'رد شده', label_en: 'Rejected', value: 'rejected' }
],
dataType: 'select',
required: true,
order: 1,
isActive: true,
validation: {
enum: ['approved', 'needs_revision', 'rejected']
}
},
{
id: '67fa10c259e15f231a2d1006',
name_fa: 'توضیحات کارشناس',
name_en: 'expertComments',
label_fa: 'توضیحات کارشناس',
label_en: 'Expert Comments',
placeholder_fa: 'توضیحات خود را وارد کنید',
placeholder_en: 'Enter your comments',
value: null,
dataType: 'textarea',
required: true,
order: 2,
isActive: true,
validation: {
minLength: 10,
maxLength: 2000
}
}
],
metadata: {
icon: 'clipboard-check',
color: '#8B5CF6',
requiresExpertRole: true
}
}
},
expertCostEvaluation: {
summary: 'Expert Cost Evaluation',
value: {
stepKey: 'EXPERT_COST_EVALUATION',
type: 'CLAIM',
stepNumber: 8,
isActive: true,
stepName_fa: 'برآورد هزینه توسط کارشناس',
stepName_en: 'Expert Cost Evaluation',
description_fa: 'محاسبه و برآورد هزینه تعمیرات توسط کارشناس',
description_en: 'Repair cost calculation and estimation by expert',
category: 'EXPERT',
requiredPreviousSteps: ['EXPERT_DAMAGE_ASSESSMENT'],
nextPossibleSteps: ['INSURER_REVIEW'],
allowedRoles: ['damage_expert', 'admin'],
estimatedDuration: 20,
fields: [
{
id: '67fa10c259e15f231a2d1007',
name_fa: 'هزینه کل برآورد شده',
name_en: 'estimatedTotalCost',
label_fa: 'هزینه کل برآورد شده (ریال)',
label_en: 'Estimated Total Cost (Rials)',
placeholder_fa: 'مبلغ را وارد کنید',
placeholder_en: 'Enter amount',
value: null,
dataType: 'number',
required: true,
order: 1,
isActive: true,
validation: {
min: 0,
max: 999999999999
}
},
{
id: '67fa10c259e15f231a2d1008',
name_fa: 'جزئیات هزینه',
name_en: 'costBreakdown',
label_fa: 'جزئیات هزینه',
label_en: 'Cost Breakdown',
placeholder_fa: 'جزئیات هزینه را وارد کنید',
placeholder_en: 'Enter cost breakdown',
value: null,
dataType: 'textarea',
required: true,
order: 2,
isActive: true,
validation: {
minLength: 20,
maxLength: 5000
}
}
],
metadata: {
icon: 'dollar-sign',
color: '#F59E0B',
requiresExpertRole: true,
requiresCostCalculation: true
}
}
},
insurerReview: {
summary: 'Insurer Review',
value: {
stepKey: 'INSURER_REVIEW',
type: 'CLAIM',
stepNumber: 9,
isActive: true,
stepName_fa: 'بررسی بیمه‌گر',
stepName_en: 'Insurer Review',
description_fa: 'بررسی نهایی و تایید یا رد خسارت توسط بیمه‌گر',
description_en: 'Final review and approval/rejection by insurer',
category: 'INSURER',
requiredPreviousSteps: ['EXPERT_COST_EVALUATION'],
nextPossibleSteps: ['CLAIM_COMPLETED'],
allowedRoles: ['insurer', 'admin'],
estimatedDuration: 60,
fields: [
{
id: '67fa10c259e15f231a2d1009',
name_fa: 'تصمیم بیمه‌گر',
name_en: 'insurerDecision',
label_fa: 'تصمیم بیمه‌گر',
label_en: 'Insurer Decision',
placeholder_fa: 'تصمیم خود را انتخاب کنید',
placeholder_en: 'Select your decision',
value: [
{ label_fa: 'تایید', label_en: 'Approved', value: 'approved' },
{ label_fa: 'رد', label_en: 'Rejected', value: 'rejected' }
],
dataType: 'select',
required: true,
order: 1,
isActive: true,
validation: {
enum: ['approved', 'rejected']
}
},
{
id: '67fa10c259e15f231a2d100a',
name_fa: 'توضیحات بیمه‌گر',
name_en: 'insurerNotes',
label_fa: 'توضیحات بیمه‌گر',
label_en: 'Insurer Notes',
placeholder_fa: 'توضیحات خود را وارد کنید',
placeholder_en: 'Enter your notes',
value: null,
dataType: 'textarea',
required: true,
order: 2,
isActive: true,
validation: {
minLength: 10,
maxLength: 2000
}
}
],
metadata: {
icon: 'shield-check',
color: '#6366F1',
requiresInsurerRole: true,
isFinalStep: false
}
}
},
claimCompleted: {
summary: 'Claim Completed',
value: {
stepKey: 'CLAIM_COMPLETED',
type: 'CLAIM',
stepNumber: 10,
isActive: true,
stepName_fa: 'تکمیل خسارت',
stepName_en: 'Claim Completed',
description_fa: 'خسارت به طور کامل بررسی و نتیجه‌گیری شده است',
description_en: 'Claim has been fully reviewed and concluded',
category: 'FINAL',
requiredPreviousSteps: ['INSURER_REVIEW'],
nextPossibleSteps: [],
allowedRoles: ['user', 'damage_expert', 'insurer', 'admin'],
estimatedDuration: 0,
fields: [],
metadata: {
icon: 'check-circle',
color: '#10B981',
readOnly: true,
isSystemStep: true,
isFinalStep: true
}
}
}
};
export const updateClaimWorkflowStepExamples = {
example1: {
summary: 'Update claim step name',
value: {
stepName_fa: 'انتخاب قطعات خارجی - بروزرسانی شده',
stepName_en: 'Select Outer Parts - Updated',
category: 'CLAIM',
isActive: true
}
},
example2: {
summary: 'Update claim step metadata',
value: {
metadata: {
icon: 'car',
color: '#10B981',
requiresMultipleSelection: true,
priority: 'high'
}
}
}
};

View File

@@ -0,0 +1,254 @@
import { IsNotEmpty, IsString, IsNumber, IsBoolean, IsOptional, IsArray, IsEnum, ValidateNested, IsObject } from 'class-validator';
import { Type } from 'class-transformer';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { ClaimWorkflowStep } from 'src/Types&Enums/claim-request-management/claim-workflow-steps.enum';
import { WorkflowStep } from 'src/Types&Enums/blame-request-management/blameWorkflow-steps.enum';
import { Types } from 'mongoose';
// Combined enum for validation
const AllWorkflowSteps = { ...WorkflowStep, ...ClaimWorkflowStep };
export class ClaimStepFieldDto {
@ApiProperty({
description: 'Unique identifier for the field',
example: '67fa10c259e15f231a2d1001'
})
@IsNotEmpty()
id: Types.ObjectId;
@ApiProperty({
description: 'Field name in Farsi',
example: 'قطعات خارجی'
})
@IsNotEmpty()
@IsString()
name_fa: string;
@ApiProperty({
description: 'Field name in English',
example: 'outerParts'
})
@IsNotEmpty()
@IsString()
name_en: string;
@ApiPropertyOptional({
description: 'Field label in Farsi',
example: 'قطعات خارجی آسیب‌دیده'
})
@IsOptional()
@IsString()
label_fa?: string;
@ApiPropertyOptional({
description: 'Field label in English',
example: 'Damaged Outer Parts'
})
@IsOptional()
@IsString()
label_en?: string;
@ApiPropertyOptional({
description: 'Placeholder text in Farsi',
example: 'قطعات خارجی آسیب‌دیده را انتخاب کنید'
})
@IsOptional()
@IsString()
placeholder_fa?: string;
@ApiPropertyOptional({
description: 'Placeholder text in English',
example: 'Select damaged outer parts'
})
@IsOptional()
@IsString()
placeholder_en?: string;
@ApiPropertyOptional({
description: 'Possible values for select/multiselect fields (null for non-select fields)',
example: null,
nullable: true,
default: null
})
@IsOptional()
value?: Object[] | null;
@ApiProperty({
description: 'Data type of the field',
example: 'multiselect',
enum: ['string', 'number', 'boolean', 'date', 'select', 'multiselect', 'file', 'textarea', 'email', 'phone', 'object']
})
@IsNotEmpty()
@IsString()
dataType: string;
@ApiPropertyOptional({
description: 'Whether the field is required',
example: true,
default: false
})
@IsOptional()
@IsBoolean()
required?: boolean;
@ApiPropertyOptional({
description: 'Validation rules for the field',
example: { minItems: 1, maxItems: 13 }
})
@IsOptional()
@IsObject()
validation?: Object;
@ApiPropertyOptional({
description: 'Display order of the field in the form',
example: 1
})
@IsOptional()
@IsNumber()
order?: number;
@ApiPropertyOptional({
description: 'Whether the field is active',
example: true,
default: true
})
@IsOptional()
@IsBoolean()
isActive?: boolean;
}
export class CreateClaimWorkflowStepDto {
@ApiProperty({
description: 'Unique key identifying the claim workflow step',
example: 'CLAIM_CREATED',
enum: AllWorkflowSteps
})
@IsNotEmpty()
@IsEnum(AllWorkflowSteps)
stepKey: ClaimWorkflowStep | WorkflowStep;
@ApiProperty({
description: 'Workflow type: CLAIM for claim workflow',
example: 'CLAIM',
default: 'CLAIM'
})
@IsNotEmpty()
@IsString()
type: string;
@ApiProperty({
description: 'Order number of the step in the claim workflow',
example: 1
})
@IsNotEmpty()
@IsNumber()
stepNumber: number;
@ApiPropertyOptional({
description: 'Whether the step is active',
example: true,
default: true
})
@IsOptional()
@IsBoolean()
isActive?: boolean;
@ApiProperty({
description: 'Step name in Farsi',
example: 'ایجاد درخواست خسارت'
})
@IsNotEmpty()
@IsString()
stepName_fa: string;
@ApiProperty({
description: 'Step name in English',
example: 'Create Claim Request'
})
@IsNotEmpty()
@IsString()
stepName_en: string;
@ApiPropertyOptional({
description: 'Step description in Farsi',
example: 'ایجاد درخواست خسارت از پرونده تعیین تقصیر تکمیل شده'
})
@IsOptional()
@IsString()
description_fa?: string;
@ApiPropertyOptional({
description: 'Step description in English',
example: 'Create claim request from completed blame case'
})
@IsOptional()
@IsString()
description_en?: string;
@ApiPropertyOptional({
description: 'Category of the step',
example: 'CLAIM',
enum: ['CLAIM', 'EXPERT', 'INSURER', 'FINAL']
})
@IsOptional()
@IsString()
category?: string;
@ApiPropertyOptional({
description: 'Dynamic fields for this step',
type: [ClaimStepFieldDto],
example: []
})
@IsOptional()
@IsArray()
@ValidateNested({ each: true })
@Type(() => ClaimStepFieldDto)
fields?: ClaimStepFieldDto[];
@ApiPropertyOptional({
description: 'Steps that must be completed before this step',
example: [],
enum: AllWorkflowSteps,
isArray: true
})
@IsOptional()
@IsArray()
@IsEnum(AllWorkflowSteps, { each: true })
requiredPreviousSteps?: (ClaimWorkflowStep | WorkflowStep)[];
@ApiPropertyOptional({
description: 'Possible next steps after completing this step',
example: ['SELECT_OUTER_PARTS'],
enum: AllWorkflowSteps,
isArray: true
})
@IsOptional()
@IsArray()
@IsEnum(AllWorkflowSteps, { each: true })
nextPossibleSteps?: (ClaimWorkflowStep | WorkflowStep)[];
@ApiPropertyOptional({
description: 'Additional metadata for the step',
example: { icon: 'file-plus', color: '#8B5CF6' }
})
@IsOptional()
@IsObject()
metadata?: Record<string, any>;
@ApiPropertyOptional({
description: 'Estimated duration in minutes',
example: 1
})
@IsOptional()
@IsNumber()
estimatedDuration?: number;
@ApiPropertyOptional({
description: 'Roles allowed to access this step',
example: ['user', 'damage_expert', 'admin']
})
@IsOptional()
@IsArray()
@IsString({ each: true })
allowedRoles?: string[];
}

View File

@@ -0,0 +1,271 @@
import { IsNotEmpty, IsString, IsNumber, IsBoolean, IsOptional, IsArray, IsEnum, ValidateNested, IsObject } from 'class-validator';
import { Type } from 'class-transformer';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { WorkflowStep } from 'src/Types&Enums/blame-request-management/blameWorkflow-steps.enum';
import { ClaimWorkflowStep } from 'src/Types&Enums/claim-request-management/claim-workflow-steps.enum';
import { Types } from 'mongoose';
// Combined enum for validation
const AllWorkflowSteps = { ...WorkflowStep, ...ClaimWorkflowStep };
export class StepFieldDto {
@ApiProperty({
description: 'Unique identifier for the field',
example: '507f1f77bcf86cd799439011'
})
@IsNotEmpty()
id: Types.ObjectId;
@ApiProperty({
description: 'Field name in Farsi',
example: 'فایل ویدیو'
})
@IsNotEmpty()
@IsString()
name_fa: string;
@ApiProperty({
description: 'Field name in English',
example: 'videoFile'
})
@IsNotEmpty()
@IsString()
name_en: string;
@ApiPropertyOptional({
description: 'Field label in Farsi',
example: 'فایل ویدیو'
})
@IsOptional()
@IsString()
label_fa?: string;
@ApiPropertyOptional({
description: 'Field label in English',
example: 'Video File'
})
@IsOptional()
@IsString()
label_en?: string;
@ApiPropertyOptional({
description: 'Placeholder text in Farsi',
example: 'فایل ویدیو خود را آپلود کنید'
})
@IsOptional()
@IsString()
placeholder_fa?: string;
@ApiPropertyOptional({
description: 'Placeholder text in English',
example: 'Upload your video file'
})
@IsOptional()
@IsString()
placeholder_en?: string;
@ApiPropertyOptional({
description: 'Possible values for select/multiselect fields (null for non-select fields)',
example: null,
nullable: true,
default: null
})
@IsOptional()
value?: Object[] | null;
@ApiProperty({
description: 'Data type of the field',
example: 'file',
enum: ['string', 'number', 'boolean', 'date', 'select', 'multiselect', 'file', 'textarea', 'email', 'phone']
})
@IsNotEmpty()
@IsString()
dataType: string;
@ApiPropertyOptional({
description: 'Whether the field is required',
example: true,
default: false
})
@IsOptional()
@IsBoolean()
required?: boolean;
@ApiPropertyOptional({
description: 'Validation rules for the field',
example: { maxSize: 52428800, allowedTypes: ['video/mp4', 'video/webm'] }
})
@IsOptional()
@IsObject()
validation?: Object;
@ApiPropertyOptional({
description: 'Display order of the field in the form',
example: 1
})
@IsOptional()
@IsNumber()
order?: number;
@ApiPropertyOptional({
description: 'Whether the field is active',
example: true,
default: true
})
@IsOptional()
@IsBoolean()
isActive?: boolean;
}
export class CreateWorkflowStepDto {
@ApiProperty({
description: 'Unique key identifying the workflow step (blame or claim)',
example: 'FIRST_VIDEO',
enum: AllWorkflowSteps
})
@IsNotEmpty()
@IsEnum(AllWorkflowSteps)
stepKey: WorkflowStep | ClaimWorkflowStep;
@ApiProperty({
description: 'Workflow type: THIRD_PARTY (blame) or CLAIM (claim workflow)',
example: 'THIRD_PARTY',
enum: ['THIRD_PARTY', 'CLAIM']
})
@IsNotEmpty()
@IsString()
type: string;
@ApiProperty({
description: 'Order number of the step within this workflow type',
example: 2
})
@IsNotEmpty()
@IsNumber()
stepNumber: number;
@ApiPropertyOptional({
description: 'Whether the step is active',
example: true,
default: true
})
@IsOptional()
@IsBoolean()
isActive?: boolean;
@ApiProperty({
description: 'Step name in Farsi',
example: 'ویدیو طرف اول'
})
@IsNotEmpty()
@IsString()
stepName_fa: string;
@ApiProperty({
description: 'Step name in English',
example: 'First Party Video'
})
@IsNotEmpty()
@IsString()
stepName_en: string;
@ApiPropertyOptional({
description: 'Step description in Farsi',
example: 'ضبط ویدیو توسط طرف اول'
})
@IsOptional()
@IsString()
description_fa?: string;
@ApiPropertyOptional({
description: 'Step description in English',
example: 'Video capture by first party'
})
@IsOptional()
@IsString()
description_en?: string;
@ApiPropertyOptional({
description: 'Category of the step within workflow (e.g., INITIAL, FIRST_PARTY, EXPERT)',
example: 'FIRST_PARTY',
enum: ['INITIAL', 'FIRST_PARTY', 'SECOND_PARTY', 'CLAIM', 'EXPERT', 'INSURER', 'FINAL']
})
@IsOptional()
@IsString()
category?: string;
@ApiPropertyOptional({
description: 'Dynamic fields for this step',
type: [StepFieldDto],
example: [
{
id: '507f1f77bcf86cd799439011',
name_fa: 'فایل ویدیو',
name_en: 'videoFile',
label_fa: 'فایل ویدیو',
label_en: 'Video File',
value: null,
dataType: 'file',
required: true,
order: 1,
isActive: true,
validation: {
maxSize: 52428800,
allowedTypes: ['video/mp4', 'video/webm']
}
}
]
})
@IsOptional()
@IsArray()
@ValidateNested({ each: true })
@Type(() => StepFieldDto)
fields?: StepFieldDto[];
@ApiPropertyOptional({
description: 'Steps that must be completed before this step',
example: ['CREATED'],
enum: AllWorkflowSteps,
isArray: true
})
@IsOptional()
@IsArray()
@IsEnum(AllWorkflowSteps, { each: true })
requiredPreviousSteps?: (WorkflowStep | ClaimWorkflowStep)[];
@ApiPropertyOptional({
description: 'Possible next steps after completing this step',
example: ['FIRST_INITIAL_FORM'],
enum: AllWorkflowSteps,
isArray: true
})
@IsOptional()
@IsArray()
@IsEnum(AllWorkflowSteps, { each: true })
nextPossibleSteps?: (WorkflowStep | ClaimWorkflowStep)[];
@ApiPropertyOptional({
description: 'Additional metadata for the step',
example: { icon: 'video', color: '#3B82F6' }
})
@IsOptional()
@IsObject()
metadata?: Record<string, any>;
@ApiPropertyOptional({
description: 'Estimated duration in minutes',
example: 5
})
@IsOptional()
@IsNumber()
estimatedDuration?: number;
@ApiPropertyOptional({
description: 'Roles allowed to access this step',
example: ['user', 'expert', 'admin']
})
@IsOptional()
@IsArray()
@IsString({ each: true })
allowedRoles?: string[];
}

View File

@@ -0,0 +1,8 @@
import { PartialType } from '@nestjs/swagger';
import { CreateWorkflowStepDto } from './create-workflow-step.dto';
/**
* Update DTO inherits all fields from Create DTO but makes them all optional
* Supports both blame and claim workflow steps
*/
export class UpdateWorkflowStepDto extends PartialType(CreateWorkflowStepDto) {}

File diff suppressed because it is too large Load Diff