Mirrors the utility statement intake on the insurance side: a policy_ocr batch/document pair of tables, a GMX parser, a matcher keyed on Policy.policyNumber, and a "Captura" screen under /polizas that proposes policy -> customer for staff to confirm. Lifts the OCR seam out of StatementsModule into its own OcrModule so PolicyOcrModule can inject OCR_PROVIDER without taking on the rest of the statement pipeline; StatementsModule now imports it and binds nothing itself. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
85 lines
3.3 KiB
TypeScript
85 lines
3.3 KiB
TypeScript
import { Type } from "class-transformer";
|
|
import {
|
|
IsArray,
|
|
IsDateString,
|
|
IsEnum,
|
|
IsNumber,
|
|
IsObject,
|
|
IsOptional,
|
|
IsString,
|
|
MinLength,
|
|
ValidateNested,
|
|
} from "class-validator";
|
|
|
|
/** One document's confirmed-after-review state. The service reads these
|
|
* fields and writes them onto either a matched Policy or a freshly created
|
|
* one. Anything null here is not written. */
|
|
export class ConfirmPolicyDocumentDto {
|
|
@IsString() documentId!: string;
|
|
|
|
/** Required when creating a new Policy; ignored if `policyId` is set. */
|
|
@IsOptional() @IsString() customerId?: string;
|
|
/** Set when the document matched an existing Policy. */
|
|
@IsOptional() @IsString() policyId?: string;
|
|
|
|
@IsOptional() @IsString() policyNumber?: string;
|
|
@IsOptional() @IsString() insuredName?: string;
|
|
@IsOptional() @IsString() additionalInsured?: string;
|
|
@IsOptional() @IsString() agentName?: string;
|
|
@IsOptional() @IsString() legalAddress?: string;
|
|
@IsOptional() @IsString() zip?: string;
|
|
@IsOptional() @IsDateString() policyFrom?: string;
|
|
@IsOptional() @IsDateString() policyTo?: string;
|
|
@IsOptional() @IsDateString() policyDate?: string;
|
|
@IsOptional() @IsEnum(["MXN", "USD", "EUR"]) currency?: "MXN" | "USD" | "EUR";
|
|
@IsOptional() @IsNumber() netPremium?: number;
|
|
@IsOptional() @IsNumber() policyFee?: number;
|
|
@IsOptional() @IsNumber() brokerFee?: number;
|
|
@IsOptional() @IsNumber() total?: number;
|
|
@IsOptional() @IsString() premiumPayment?: string;
|
|
/** Coverages parsed off the PDF, passed through verbatim to Policy.coveragesJson. */
|
|
@IsOptional() @IsObject() coveragesJson?: unknown;
|
|
|
|
/** When true, write a Transaction(domain=INSURANCE, amount=-netPremium)
|
|
* in addition to creating/updating the Policy. Skipped if netPremium is
|
|
* null or zero. */
|
|
@IsOptional() postPremium?: boolean;
|
|
}
|
|
|
|
export class ConfirmPolicyBatchDto {
|
|
@IsArray()
|
|
@ValidateNested({ each: true })
|
|
@Type(() => ConfirmPolicyDocumentDto)
|
|
documents!: ConfirmPolicyDocumentDto[];
|
|
}
|
|
|
|
/** Staff correction of one document's extracted fields or its match. */
|
|
export class ReviewPolicyDocumentDto {
|
|
@IsOptional() @IsString() policyNumber?: string;
|
|
@IsOptional() @IsString() insuredName?: string;
|
|
@IsOptional() @IsString() additionalInsured?: string;
|
|
@IsOptional() @IsString() agentName?: string;
|
|
@IsOptional() @IsString() legalAddress?: string;
|
|
@IsOptional() @IsString() zip?: string;
|
|
@IsOptional() @IsDateString() policyFrom?: string;
|
|
@IsOptional() @IsDateString() policyTo?: string;
|
|
@IsOptional() @IsDateString() policyDate?: string;
|
|
@IsOptional() @IsString() currency?: string;
|
|
@IsOptional() @IsNumber() netPremium?: number;
|
|
@IsOptional() @IsNumber() policyFee?: number;
|
|
@IsOptional() @IsNumber() brokerFee?: number;
|
|
@IsOptional() @IsNumber() total?: number;
|
|
@IsOptional() @IsString() premiumPayment?: string;
|
|
@IsOptional() @IsObject() coveragesJson?: unknown;
|
|
|
|
/** Set by the reviewer when the document matched an existing Policy. */
|
|
@IsOptional() @IsString() matchedPolicyId?: string;
|
|
/** Set by the reviewer when creating a new Policy. */
|
|
@IsOptional() @IsString() matchedCustomerId?: string;
|
|
/** Force-confirm a doc even when the matcher left it ambiguous. */
|
|
@IsOptional() forceConfirm?: boolean;
|
|
}
|
|
|
|
export class CreatePolicyOcrBatchDto {
|
|
@IsOptional() @IsString() @MinLength(1) label?: string;
|
|
} |