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; }