forked from Yara724/api
296 lines
8.4 KiB
TypeScript
296 lines
8.4 KiB
TypeScript
import { Prop, Schema, SchemaFactory } from "@nestjs/mongoose";
|
|
import { Schema as MongooseSchema, Types } from "mongoose";
|
|
import {
|
|
ExpertProfileSnapshot,
|
|
ExpertProfileSnapshotSchema,
|
|
} from "src/request-management/entities/schema/expert-profile-snapshot.schema";
|
|
import { FactorStatus } from "src/Types&Enums/claim-request-management/factor-status.enum";
|
|
import { UserReplyEnum } from "src/Types&Enums/claim-request-management/userReply.enum";
|
|
|
|
@Schema({ _id: false })
|
|
export class ClaimPartPricing {
|
|
@Prop({ type: String })
|
|
partId: string;
|
|
|
|
/**
|
|
* Legacy string or structured `{ part, side }` from expert reply DTOs (V1/V2).
|
|
* Must be Mixed — objects cannot cast to String.
|
|
*/
|
|
@Prop({ type: MongooseSchema.Types.Mixed })
|
|
carPartDamage?: string | { part?: string; side?: string };
|
|
|
|
@Prop({ type: String })
|
|
typeOfDamage?: string;
|
|
|
|
@Prop({ type: MongooseSchema.Types.Mixed })
|
|
price?: string | number;
|
|
|
|
@Prop({ type: MongooseSchema.Types.Mixed })
|
|
salary?: string | number;
|
|
|
|
@Prop({ type: MongooseSchema.Types.Mixed })
|
|
totalPayment?: string | number;
|
|
|
|
/** V1/V2: string/number legacy, or `{ option, price?, branchId? }` after expert normalization. */
|
|
@Prop({ type: MongooseSchema.Types.Mixed })
|
|
daghi?: string | number | Record<string, unknown>;
|
|
|
|
@Prop({ type: Boolean, default: false })
|
|
factorNeeded?: boolean;
|
|
|
|
@Prop({ type: Types.ObjectId })
|
|
factorLink?: Types.ObjectId;
|
|
|
|
@Prop({ type: String, enum: FactorStatus, default: null })
|
|
factorStatus?: FactorStatus | null;
|
|
|
|
@Prop({ type: String, default: null })
|
|
rejectionReason?: string | null;
|
|
}
|
|
export const ClaimPartPricingSchema =
|
|
SchemaFactory.createForClass(ClaimPartPricing);
|
|
|
|
@Schema({ _id: false })
|
|
export class ClaimExpertActor {
|
|
@Prop({ type: String })
|
|
actorName?: string;
|
|
|
|
/**
|
|
* Kept as string to support existing queries like:
|
|
* `"damageExpertReply.actorDetail.actorId": actor.sub`
|
|
*/
|
|
@Prop({ type: String })
|
|
actorId?: string;
|
|
}
|
|
export const ClaimExpertActorSchema =
|
|
SchemaFactory.createForClass(ClaimExpertActor);
|
|
|
|
@Schema({ _id: false })
|
|
export class ClaimUserComment {
|
|
@Prop({ type: Boolean, default: null })
|
|
isAccept?: boolean | null;
|
|
|
|
@Prop({ type: Types.ObjectId })
|
|
signDetailId?: Types.ObjectId;
|
|
}
|
|
export const ClaimUserCommentSchema =
|
|
SchemaFactory.createForClass(ClaimUserComment);
|
|
|
|
/** Owner acceptance + signature after expert pricing (WAITING_FOR_INSURER_APPROVAL @ INSURER_REVIEW). */
|
|
@Schema({ _id: false })
|
|
export class ClaimOwnerInsurerApproval {
|
|
@Prop({ type: Boolean, required: true })
|
|
agree: boolean;
|
|
|
|
/** Branch the owner is signing for (must belong to their insurer; aligned with expert daghi options when present). */
|
|
@Prop({ type: Types.ObjectId })
|
|
branchId?: Types.ObjectId;
|
|
|
|
@Prop({ type: Types.ObjectId })
|
|
signDetailId?: Types.ObjectId;
|
|
|
|
@Prop({ type: Date, default: () => new Date() })
|
|
signedAt?: Date;
|
|
}
|
|
export const ClaimOwnerInsurerApprovalSchema =
|
|
SchemaFactory.createForClass(ClaimOwnerInsurerApproval);
|
|
|
|
@Schema({ _id: false })
|
|
export class ClaimExpertReply {
|
|
@Prop({ type: String })
|
|
description?: string;
|
|
|
|
@Prop({ type: ClaimExpertActorSchema })
|
|
actorDetail?: ClaimExpertActor;
|
|
|
|
@Prop({ type: [ClaimPartPricingSchema], default: [] })
|
|
parts?: ClaimPartPricing[];
|
|
|
|
@Prop({ type: Date, default: () => new Date() })
|
|
submittedAt?: Date;
|
|
|
|
@Prop({ type: ClaimUserCommentSchema })
|
|
userComment?: ClaimUserComment;
|
|
|
|
/** Damage expert profile at reply time (from `damage-expert` collection). */
|
|
@Prop({ type: ExpertProfileSnapshotSchema })
|
|
expertProfileSnapshot?: ExpertProfileSnapshot;
|
|
}
|
|
export const ClaimExpertReplySchema =
|
|
SchemaFactory.createForClass(ClaimExpertReply);
|
|
|
|
/** One line item the user disputes on an expert-priced part */
|
|
@Schema({ _id: false })
|
|
export class ClaimUserObjectionPart {
|
|
@Prop({ type: String, required: true })
|
|
partId: string;
|
|
|
|
@Prop({ type: String })
|
|
reason?: string;
|
|
|
|
@Prop({ type: String })
|
|
partPrice?: string;
|
|
|
|
@Prop({ type: String })
|
|
partSalary?: string;
|
|
|
|
@Prop({ type: String })
|
|
typeOfDamage?: string;
|
|
|
|
@Prop({ type: String })
|
|
carPartDamage?: string;
|
|
|
|
@Prop({ type: String })
|
|
side?: string;
|
|
}
|
|
export const ClaimUserObjectionPartSchema =
|
|
SchemaFactory.createForClass(ClaimUserObjectionPart);
|
|
|
|
@Schema({ _id: false })
|
|
export class ClaimUserObjectionNewPart {
|
|
@Prop({ type: String })
|
|
partId?: string;
|
|
|
|
@Prop({ type: String, required: true })
|
|
partName: string;
|
|
|
|
@Prop({ type: String })
|
|
side?: string;
|
|
}
|
|
export const ClaimUserObjectionNewPartSchema =
|
|
SchemaFactory.createForClass(ClaimUserObjectionNewPart);
|
|
|
|
/**
|
|
* Full user objection payload (matches v1 DTO: objectionParts + newParts).
|
|
* Stored on {@link ClaimEvaluation.objection}.
|
|
*/
|
|
@Schema({ _id: false })
|
|
export class ClaimUserObjectionPayload {
|
|
@Prop({ type: [ClaimUserObjectionPartSchema], default: [] })
|
|
objectionParts?: ClaimUserObjectionPart[];
|
|
|
|
@Prop({ type: [ClaimUserObjectionNewPartSchema], default: [] })
|
|
newParts?: ClaimUserObjectionNewPart[];
|
|
|
|
@Prop({ type: Date, default: () => new Date() })
|
|
submittedAt?: Date;
|
|
}
|
|
export const ClaimUserObjectionPayloadSchema =
|
|
SchemaFactory.createForClass(ClaimUserObjectionPayload);
|
|
|
|
@Schema({ _id: false })
|
|
export class ClaimResendRequest {
|
|
@Prop({ type: String })
|
|
resendDescription?: string;
|
|
|
|
@Prop({ type: [MongooseSchema.Types.Mixed], default: [] })
|
|
resendDocuments?: any[];
|
|
|
|
@Prop({ type: [MongooseSchema.Types.Mixed], default: [] })
|
|
resendCarParts?: any[];
|
|
|
|
/** Set when the owner has satisfied every requested document/part (or acknowledged description-only resend). */
|
|
@Prop({ type: Date })
|
|
fulfilledAt?: Date;
|
|
|
|
/** Damage expert profile when resend was requested (`damage-expert` collection). */
|
|
@Prop({ type: ExpertProfileSnapshotSchema })
|
|
expertProfileSnapshot?: ExpertProfileSnapshot;
|
|
}
|
|
export const ClaimResendRequestSchema =
|
|
SchemaFactory.createForClass(ClaimResendRequest);
|
|
|
|
@Schema({ _id: false })
|
|
export class ClaimUserResendPayload {
|
|
@Prop({ type: [MongooseSchema.Types.Mixed], default: [] })
|
|
documents?: any[];
|
|
|
|
@Prop({ type: [MongooseSchema.Types.Mixed], default: [] })
|
|
carParts?: any[];
|
|
}
|
|
export const ClaimUserResendPayloadSchema =
|
|
SchemaFactory.createForClass(ClaimUserResendPayload);
|
|
|
|
@Schema({ _id: false })
|
|
export class ClaimFileRating {
|
|
@Prop({ type: Number, min: 0, max: 5 })
|
|
collisionMethodAccuracy?: number;
|
|
|
|
@Prop({ type: Number, min: 0, max: 5 })
|
|
evaluationTimeliness?: number;
|
|
|
|
@Prop({ type: Number, min: 0, max: 5 })
|
|
accidentCauseAccuracy?: number;
|
|
|
|
@Prop({ type: Number, min: 0, max: 5 })
|
|
guiltyVehicleIdentification?: number;
|
|
|
|
@Prop({ type: Number, min: 0, max: 5 })
|
|
botRating?: number;
|
|
}
|
|
export const ClaimFileRatingSchema =
|
|
SchemaFactory.createForClass(ClaimFileRating);
|
|
|
|
@Schema({ _id: false })
|
|
export class ClaimPriceDrop {
|
|
@Prop({ type: Number })
|
|
total?: number;
|
|
|
|
@Prop({ type: Number })
|
|
carPrice?: number;
|
|
|
|
@Prop({ type: Number })
|
|
carModel?: number;
|
|
|
|
@Prop({ type: [Number], default: [] })
|
|
carValue?: number[];
|
|
|
|
@Prop({ type: Number })
|
|
sumOfSeverity?: number;
|
|
}
|
|
export const ClaimPriceDropSchema = SchemaFactory.createForClass(ClaimPriceDrop);
|
|
|
|
@Schema({ _id: false })
|
|
export class ClaimEvaluation {
|
|
@Prop({ type: String, enum: UserReplyEnum, default: null })
|
|
effectedUserReply?: UserReplyEnum | null;
|
|
|
|
@Prop({ type: ClaimExpertReplySchema })
|
|
damageExpertReply?: ClaimExpertReply | null;
|
|
|
|
@Prop({ type: ClaimExpertReplySchema })
|
|
damageExpertReplyFinal?: ClaimExpertReply | null;
|
|
|
|
@Prop({ type: ClaimResendRequestSchema })
|
|
damageExpertResend?: ClaimResendRequest | null;
|
|
|
|
@Prop({ type: ClaimUserObjectionPayloadSchema })
|
|
objection?: ClaimUserObjectionPayload;
|
|
|
|
@Prop({ type: ClaimUserResendPayloadSchema })
|
|
userResendDocuments?: ClaimUserResendPayload;
|
|
|
|
@Prop({ type: ClaimFileRatingSchema })
|
|
rating?: ClaimFileRating;
|
|
|
|
@Prop({ type: ClaimOwnerInsurerApprovalSchema })
|
|
ownerInsurerApproval?: ClaimOwnerInsurerApproval;
|
|
|
|
@Prop({ type: String })
|
|
visitLocation?: string;
|
|
|
|
@Prop({ type: ClaimPriceDropSchema })
|
|
priceDrop?: ClaimPriceDrop;
|
|
|
|
/** Damage expert profile at last factor validation (`damage-expert` collection). */
|
|
@Prop({ type: ExpertProfileSnapshotSchema })
|
|
factorValidationExpertProfileSnapshot?: ExpertProfileSnapshot;
|
|
|
|
/** Damage expert profile when in-person visit was requested (`damage-expert` collection). */
|
|
@Prop({ type: ExpertProfileSnapshotSchema })
|
|
inPersonVisitExpertProfileSnapshot?: ExpertProfileSnapshot;
|
|
}
|
|
export const ClaimEvaluationSchema =
|
|
SchemaFactory.createForClass(ClaimEvaluation);
|
|
|