forked from Yara724/api
187 lines
6.2 KiB
TypeScript
187 lines
6.2 KiB
TypeScript
import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// Query helpers
|
||
// ---------------------------------------------------------------------------
|
||
|
||
export type ExpertKindFilter = "all" | "expert" | "damage_expert";
|
||
|
||
export class InsurerReportQueryDto {
|
||
@ApiPropertyOptional({ description: "Start of date range (ISO string)" })
|
||
from?: string;
|
||
|
||
@ApiPropertyOptional({ description: "End of date range (ISO string)" })
|
||
to?: string;
|
||
|
||
@ApiPropertyOptional({
|
||
enum: ["all", "expert", "damage_expert"],
|
||
description:
|
||
"Filter by expert kind. `expert` = blame-panel expert; `damage_expert` = claim damage expert; `all` (default) = both.",
|
||
})
|
||
expertKind?: ExpertKindFilter;
|
||
}
|
||
|
||
export class InsurerWorkLogQueryDto extends InsurerReportQueryDto {
|
||
@ApiPropertyOptional({ type: Number, description: "Page number (1-based)" })
|
||
page?: number;
|
||
|
||
@ApiPropertyOptional({ type: Number, description: "Items per page" })
|
||
limit?: number;
|
||
}
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// Statistics
|
||
// ---------------------------------------------------------------------------
|
||
|
||
export class InsurerStatisticsBreakdownDto {
|
||
@ApiProperty({ description: "Files that have an insurer rating" })
|
||
filesWithInsurerRating: number;
|
||
|
||
@ApiProperty({ description: "Files that have a bot rating" })
|
||
filesWithBotRating: number;
|
||
|
||
@ApiProperty({ description: "Files that have any user rating" })
|
||
filesWithUserRating: number;
|
||
|
||
@ApiProperty({ description: "Files that have an objection" })
|
||
filesWithObjection: number;
|
||
|
||
@ApiProperty({ description: "Average insurer rating (0–5)" })
|
||
averageInsurerRating: number;
|
||
|
||
@ApiProperty({ description: "Average bot rating (0–5)" })
|
||
averageBotRating: number;
|
||
}
|
||
|
||
export class InsurerStatisticsDto {
|
||
@ApiProperty({
|
||
description:
|
||
"تعداد کل پروندههای بررسیشده — distinct tenant claim files with at least one expert CHECKED activity.",
|
||
})
|
||
totalFilesReviewed: number;
|
||
|
||
@ApiProperty({
|
||
description:
|
||
"رضایت کاربران از روند پرونده — average of progressSpeed + registrationEase + overallEvaluation across rated claim files, normalised to 0–100. Formula: (avg of three dimensions across all rated files / 5) * 100.",
|
||
})
|
||
averageUserRatingPercentage: number;
|
||
|
||
@ApiProperty({
|
||
description:
|
||
"پروندههای همراه — blame files where expertInitiated === true AND creationMethod === IN_PERSON.",
|
||
})
|
||
inPersonAccompaniedCount: number;
|
||
|
||
@ApiProperty({ description: "Claim files created in the current calendar month." })
|
||
filesCreatedThisMonth: number;
|
||
|
||
@ApiProperty({ description: "Total claim files scoped to this insurer." })
|
||
totalFiles: number;
|
||
|
||
@ApiProperty({
|
||
description:
|
||
"Percentage of total claim files that have any user rating recorded. (NOT a satisfaction metric — do not render as رضایت کاربران.)",
|
||
deprecated: true,
|
||
})
|
||
filesWithUserRatingPercentage: number;
|
||
|
||
@ApiProperty({ description: "Percentage of files with an objection." })
|
||
objectionPercentage: number;
|
||
|
||
@ApiProperty({ description: "Insurer-to-bot rating ratio (0–100)." })
|
||
insurerToBotRatingPercentage: number;
|
||
|
||
@ApiProperty({ type: InsurerStatisticsBreakdownDto })
|
||
breakdown: InsurerStatisticsBreakdownDto;
|
||
}
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// Top files
|
||
// ---------------------------------------------------------------------------
|
||
|
||
export class TopFileUserRatingDto {
|
||
@ApiPropertyOptional({ description: "User's free-text comment" })
|
||
comment?: string | null;
|
||
|
||
@ApiPropertyOptional({ description: "User's overall evaluation score (0–5)" })
|
||
overallEvaluation?: number | null;
|
||
}
|
||
|
||
export class InsurerTopFileDto {
|
||
@ApiProperty({ description: "Public file ID — use for front-end link مشاهده پرونده" })
|
||
publicId: string;
|
||
|
||
@ApiProperty({ description: "ISO creation datetime" })
|
||
createdAt: string;
|
||
|
||
@ApiProperty({ description: "Combined insurer + user rating blend (0–5)" })
|
||
combinedScore: number;
|
||
|
||
@ApiProperty({ type: TopFileUserRatingDto })
|
||
userRating: TopFileUserRatingDto;
|
||
}
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// Top experts
|
||
// ---------------------------------------------------------------------------
|
||
|
||
export class InsurerTopExpertDto {
|
||
@ApiProperty()
|
||
_id: string;
|
||
|
||
@ApiProperty()
|
||
fullName: string;
|
||
|
||
@ApiProperty({ enum: ["blame", "claim"] })
|
||
expertKind: "blame" | "claim";
|
||
|
||
@ApiPropertyOptional({ description: "Overall average combined rating (0–5)" })
|
||
overallAverageRating: number | null;
|
||
|
||
@ApiProperty({ description: "Activity stats from expertFileActivity log" })
|
||
requestStats: { totalHandled: number; totalChecked: number };
|
||
}
|
||
|
||
export class InsurerTopExpertsDto {
|
||
@ApiProperty({ type: [InsurerTopExpertDto], description: "Top blame-panel experts" })
|
||
blameExperts: InsurerTopExpertDto[];
|
||
|
||
@ApiProperty({ type: [InsurerTopExpertDto], description: "Top damage experts (claim)" })
|
||
claimExperts: InsurerTopExpertDto[];
|
||
}
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// Work-log (mirrors reports.dto.ts shapes; exposed from this module for swagger)
|
||
// ---------------------------------------------------------------------------
|
||
|
||
export class InsurerWorkLogEntryDto {
|
||
@ApiProperty()
|
||
expertId: string;
|
||
|
||
@ApiProperty()
|
||
fullName: string;
|
||
|
||
@ApiProperty({ enum: ["expert", "damage_expert"] })
|
||
expertKind: "expert" | "damage_expert";
|
||
|
||
@ApiProperty({ description: "Distinct files in HANDLED state up to cutoff" })
|
||
totalHandled: number;
|
||
|
||
@ApiProperty({ description: "Distinct files currently CHECKED but not yet HANDLED" })
|
||
currentlyChecking: number;
|
||
|
||
@ApiProperty({
|
||
description:
|
||
"Distinct files with at least one CHECKED event in the reporting window (all-time when no date range given; restricted to from–to otherwise).",
|
||
})
|
||
distinctFilesCheckedInPeriod: number;
|
||
}
|
||
|
||
export class InsurerWorkLogResponseDto {
|
||
@ApiProperty({ type: [InsurerWorkLogEntryDto] })
|
||
experts: InsurerWorkLogEntryDto[];
|
||
|
||
@ApiProperty({ description: "Total experts in roster" })
|
||
total: number;
|
||
}
|