forked from Yara724/api
256 lines
7.0 KiB
TypeScript
256 lines
7.0 KiB
TypeScript
import { Prop, Schema, SchemaFactory } from "@nestjs/mongoose";
|
|
import { HydratedDocument, Schema as MongooseSchema, Types } from "mongoose";
|
|
import { ClaimRequiredDocumentType } from "src/Types&Enums/claim-request-management/required-document-type.enum";
|
|
import { ClaimStatus } from "src/Types&Enums/claim-request-management/claimStatus.enum";
|
|
import { ClaimCaseStatus } from "src/Types&Enums/claim-request-management/claim-case-status.enum";
|
|
import {
|
|
HistoryEvent,
|
|
HistoryEventSchema,
|
|
} from "src/request-management/entities/schema/historyEvent.type";
|
|
import {
|
|
ClaimDamageSelection,
|
|
ClaimDamageSelectionSchema,
|
|
} from "./claim-case.damage.schema";
|
|
import {
|
|
ClaimMoney,
|
|
ClaimMoneySchema,
|
|
ClaimOwner,
|
|
ClaimOwnerSchema,
|
|
ClaimVehicleSnapshot,
|
|
ClaimVehicleSnapshotSchema,
|
|
} from "./claim-case.identity.schema";
|
|
import { ClaimMedia, ClaimMediaSchema } from "./claim-case.media.schema";
|
|
import {
|
|
ClaimEvaluation,
|
|
ClaimEvaluationSchema,
|
|
} from "./claim-case.evaluation.schema";
|
|
import {
|
|
ClaimCaseSnapshot,
|
|
ClaimCaseSnapshotSchema,
|
|
} from "./claim-case.snapshot.schema";
|
|
import {
|
|
ClaimWorkflow,
|
|
ClaimWorkflowSchema,
|
|
} from "./claim-case.workflow.schema";
|
|
import { UserClaimRating } from "./claim-request-management.schema";
|
|
import {
|
|
CaseInquiries,
|
|
CaseInquiriesSchema,
|
|
} from "src/common/schema/case-inquiries.schema";
|
|
|
|
@Schema({ _id: false })
|
|
export class RequiredDocumentRef {
|
|
@Prop({ type: Types.ObjectId })
|
|
fileId?: Types.ObjectId;
|
|
|
|
@Prop({ type: String })
|
|
filePath?: string;
|
|
|
|
@Prop({ type: String })
|
|
fileName?: string;
|
|
|
|
@Prop({ type: Boolean, default: true })
|
|
uploaded?: boolean;
|
|
|
|
@Prop({ type: Date })
|
|
uploadedAt?: Date;
|
|
}
|
|
export const RequiredDocumentRefSchema =
|
|
SchemaFactory.createForClass(RequiredDocumentRef);
|
|
|
|
@Schema({ _id: false })
|
|
export class FanavaranSyncStage {
|
|
@Prop({ type: String })
|
|
status?: "pending" | "success" | "failed" | "skipped";
|
|
|
|
@Prop({ type: Date })
|
|
lastTriedAt?: Date;
|
|
|
|
@Prop({ type: String })
|
|
lastError?: string;
|
|
|
|
@Prop({ type: Number })
|
|
claimId?: number;
|
|
|
|
@Prop({ type: Number })
|
|
claimNo?: number;
|
|
|
|
@Prop({ type: Number })
|
|
dmgCaseId?: number;
|
|
|
|
@Prop({ type: Number })
|
|
expertiseId?: number;
|
|
|
|
@Prop({ type: [MongooseSchema.Types.Mixed], default: [] })
|
|
files?: unknown[];
|
|
|
|
@Prop({ type: MongooseSchema.Types.Mixed })
|
|
response?: unknown;
|
|
}
|
|
export const FanavaranSyncStageSchema =
|
|
SchemaFactory.createForClass(FanavaranSyncStage);
|
|
|
|
@Schema({ _id: false })
|
|
export class FanavaranSyncState {
|
|
@Prop({ type: FanavaranSyncStageSchema })
|
|
baseClaim?: FanavaranSyncStage;
|
|
|
|
@Prop({ type: FanavaranSyncStageSchema })
|
|
damageCase?: FanavaranSyncStage;
|
|
|
|
@Prop({ type: FanavaranSyncStageSchema })
|
|
attachments?: FanavaranSyncStage;
|
|
|
|
@Prop({ type: FanavaranSyncStageSchema })
|
|
expertise?: FanavaranSyncStage;
|
|
}
|
|
export const FanavaranSyncStateSchema =
|
|
SchemaFactory.createForClass(FanavaranSyncState);
|
|
|
|
@Schema({
|
|
collection: "claimCases",
|
|
timestamps: true,
|
|
id: true,
|
|
versionKey: false,
|
|
})
|
|
export class ClaimCase {
|
|
@Prop({ required: true, unique: true, index: true, trim: true })
|
|
requestNo: string;
|
|
|
|
/**
|
|
* Human-friendly shared id across blame+claim (e.g. A14235).
|
|
* Generated once on blame creation and copied into claim.
|
|
*/
|
|
@Prop({ required: true, unique: true, index: true, trim: true })
|
|
publicId: string;
|
|
|
|
/**
|
|
* Overall case status (user flow + expert flow progression)
|
|
*/
|
|
@Prop({
|
|
required: true,
|
|
type: String,
|
|
enum: ClaimCaseStatus,
|
|
default: ClaimCaseStatus.CREATED,
|
|
})
|
|
status: ClaimCaseStatus;
|
|
|
|
/**
|
|
* Claim damage determination status (expert assessment)
|
|
*/
|
|
@Prop({ type: String, enum: ClaimStatus, default: ClaimStatus.PENDING })
|
|
claimStatus: ClaimStatus;
|
|
|
|
/**
|
|
* Set while the linked blame file is in WAITING_FOR_DOCUMENT_RESEND so the claim flow can block or message the user.
|
|
*/
|
|
@Prop({ default: false })
|
|
blameDocumentResendPending?: boolean;
|
|
|
|
/**
|
|
* Link to the blame case that originated this claim.
|
|
* IMPORTANT: this is intentionally ONLY an id reference (no embedded blame file).
|
|
*/
|
|
@Prop({ type: Types.ObjectId, index: true })
|
|
blameRequestId?: Types.ObjectId;
|
|
|
|
@Prop({ type: String, index: true })
|
|
blameRequestNo?: string;
|
|
|
|
/**
|
|
* Set when this claim was created by a field expert on behalf of the damaged
|
|
* party (expert-initiated IN_PERSON flow). Used to scope the expert's panel
|
|
* access to only their own initiated files.
|
|
*/
|
|
@Prop({ type: Types.ObjectId, index: true })
|
|
initiatedByFieldExpertId?: Types.ObjectId;
|
|
|
|
/**
|
|
* The damaged party's userId, resolved from the blame at claim-creation time.
|
|
* Stored here so view/list access does not require an extra blame lookup.
|
|
* For CAR_BODY this is the FIRST party; for THIRD_PARTY it is the non-guilty party.
|
|
*/
|
|
@Prop({ type: Types.ObjectId, index: true })
|
|
damagedPartyUserId?: Types.ObjectId;
|
|
|
|
@Prop({ type: ClaimWorkflowSchema, default: () => ({}) })
|
|
workflow?: ClaimWorkflow;
|
|
|
|
@Prop({ type: ClaimOwnerSchema, default: () => ({}) })
|
|
owner?: ClaimOwner;
|
|
|
|
@Prop({ type: ClaimVehicleSnapshotSchema, default: () => ({}) })
|
|
vehicle?: ClaimVehicleSnapshot;
|
|
|
|
@Prop({ type: ClaimMoneySchema })
|
|
money?: ClaimMoney;
|
|
|
|
@Prop({ type: Number })
|
|
claimNo?: number;
|
|
|
|
@Prop({ type: Number })
|
|
claimId?: number;
|
|
|
|
@Prop({ type: Number })
|
|
dmgCaseId?: number;
|
|
|
|
@Prop({ type: Number })
|
|
expertiseId?: number;
|
|
|
|
@Prop({ type: FanavaranSyncStateSchema, default: () => ({}) })
|
|
fanavaranSync?: FanavaranSyncState;
|
|
|
|
@Prop({ type: ClaimDamageSelectionSchema, default: () => ({}) })
|
|
damage?: ClaimDamageSelection;
|
|
|
|
@Prop({ type: ClaimMediaSchema, default: () => ({}) })
|
|
media?: ClaimMedia;
|
|
|
|
@Prop({ type: ClaimEvaluationSchema, default: () => ({}) })
|
|
evaluation?: ClaimEvaluation;
|
|
|
|
@Prop({ type: CaseInquiriesSchema, default: () => ({}) })
|
|
inquiries?: CaseInquiries;
|
|
|
|
/**
|
|
* Optional “read-optimized” copy of fields from blame/request side.
|
|
* Source of truth remains `blameRequestId`.
|
|
*/
|
|
@Prop({ type: ClaimCaseSnapshotSchema })
|
|
snapshot?: ClaimCaseSnapshot;
|
|
|
|
/**
|
|
* For quick “has user uploaded X?” checks. Values point to docs in the
|
|
* `claim-required-documents` collection.
|
|
*/
|
|
@Prop({
|
|
type: Map,
|
|
of: RequiredDocumentRefSchema,
|
|
default: () => ({}),
|
|
})
|
|
requiredDocuments?: Map<string, RequiredDocumentRef>;
|
|
|
|
@Prop({ type: [HistoryEventSchema], default: [] })
|
|
history?: HistoryEvent[];
|
|
|
|
/**
|
|
* User satisfaction rating (damaged party), after the case is completed.
|
|
*/
|
|
@Prop({ type: UserClaimRating, required: false })
|
|
userRating?: UserClaimRating;
|
|
|
|
@Prop({ type: Types.ObjectId, index: true })
|
|
createdByRegistrarId?: Types.ObjectId;
|
|
|
|
/**
|
|
* Legacy fields kept optional to simplify progressive migration.
|
|
* If you choose to migrate later, we can remove these.
|
|
*/
|
|
@Prop({ type: MongooseSchema.Types.Mixed })
|
|
legacy?: any;
|
|
}
|
|
|
|
export type ClaimCaseDocument = HydratedDocument<ClaimCase>;
|
|
export const ClaimCaseSchema = SchemaFactory.createForClass(ClaimCase);
|
|
ClaimCaseSchema.index({ status: 1, "workflow.locked": 1 });
|