Policy header, all five child collections, and the insurance reference catalogs become create/edit/delete-able on the RBAC foundation. API: - Policy gains archivedAt (soft-delete); list/browser default to archivedAt=null with ?includeArchived opt-in. - PoliciesService: header create/update/archive/restore (customer FK validated for a clean 404); add/update/remove for installments, vehicles, drivers, beneficiaries, claims — each scoped to its policy so one policy's id can't touch another's rows; lookups CRUD for providers, policy types, adjusters. - PoliciesController write routes: header create/update need STAFF+ (policy:create/update), archive/restore need MANAGER+ (policy:delete), every child route needs policy:update. New LookupsController at /lookups (read open; mutate needs lookup:manage / MANAGER+). Mutations audited. - DTOs (policy header, children, lookups); dates coerced; shared coerce.ts. Web: - Generic ChildCollection editor (config-driven add/edit/remove table), reused by both the policy detail child editors and the catalogs screen. - PolicyForm (header) with type/provider selects and a debounced CustomerPicker; /polizas/nuevo (accepts ?customerId prefill) and /polizas/[id]/editar. Policy detail: gated action bar (Editar/Archivar) + "Administrar detalles" child editors for all five collections. - /catalogos admin screen (aseguradoras/tipos/ajustadores), nav-gated on lookup:manage. "Nueva póliza" buttons on the list and on the customer detail (prefilled). api.ts + types for all of the above. Verified against dev: policy create (dates coerced, archivedAt null), installment/vehicle add, VIEWER child-add 403, cross-policy child guard 404, lookups CRUD with VIEWER 403 / MANAGER 201, archive drops from the default list and includeArchived surfaces it. Both apps compile clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
79 lines
2.8 KiB
TypeScript
79 lines
2.8 KiB
TypeScript
import {
|
|
IsBoolean,
|
|
IsEmail,
|
|
IsEnum,
|
|
IsInt,
|
|
IsNumber,
|
|
IsOptional,
|
|
IsString,
|
|
} from "class-validator";
|
|
import { Currency } from "@jorgecuadros/database";
|
|
|
|
// Each child DTO covers create; updates reuse the same shape with all fields
|
|
// optional via the corresponding Update class. Route supplies the policyId.
|
|
|
|
export class InstallmentDto {
|
|
@IsInt() sequence!: number;
|
|
@IsOptional() @IsNumber() amount?: number;
|
|
@IsOptional() @IsEnum(Currency) currency?: Currency;
|
|
@IsOptional() @IsString() dueDate?: string;
|
|
@IsOptional() @IsString() paidDate?: string;
|
|
@IsOptional() @IsString() checkNumber?: string;
|
|
@IsOptional() @IsBoolean() isCash?: boolean;
|
|
}
|
|
export class UpdateInstallmentDto {
|
|
@IsOptional() @IsInt() sequence?: number;
|
|
@IsOptional() @IsNumber() amount?: number;
|
|
@IsOptional() @IsEnum(Currency) currency?: Currency;
|
|
@IsOptional() @IsString() dueDate?: string;
|
|
@IsOptional() @IsString() paidDate?: string;
|
|
@IsOptional() @IsString() checkNumber?: string;
|
|
@IsOptional() @IsBoolean() isCash?: boolean;
|
|
}
|
|
|
|
export class VehicleDto {
|
|
@IsOptional() @IsString() make?: string;
|
|
@IsOptional() @IsString() model?: string;
|
|
@IsOptional() @IsString() modelYear?: string;
|
|
@IsOptional() @IsString() bodyType?: string;
|
|
@IsOptional() @IsString() engineNumber?: string;
|
|
@IsOptional() @IsString() licensePlate?: string;
|
|
@IsOptional() @IsString() vinNumber?: string;
|
|
@IsOptional() @IsString() stateCode?: string;
|
|
@IsOptional() @IsString() notes?: string;
|
|
}
|
|
export class UpdateVehicleDto extends VehicleDto {}
|
|
|
|
export class DriverDto {
|
|
@IsOptional() @IsString() fullName?: string;
|
|
@IsOptional() @IsString() birthDate?: string;
|
|
@IsOptional() @IsString() sex?: string;
|
|
@IsOptional() @IsString() occupation?: string;
|
|
@IsOptional() @IsString() licenseNumber?: string;
|
|
@IsOptional() @IsString() licenseState?: string;
|
|
}
|
|
export class UpdateDriverDto extends DriverDto {}
|
|
|
|
export class BeneficiaryDto {
|
|
@IsOptional() @IsString() name?: string;
|
|
@IsOptional() @IsString() address?: string;
|
|
@IsOptional() @IsString() phone?: string;
|
|
@IsOptional() @IsEmail() email?: string;
|
|
}
|
|
export class UpdateBeneficiaryDto extends BeneficiaryDto {}
|
|
|
|
export class ClaimDto {
|
|
@IsOptional() @IsString() claimType?: string;
|
|
@IsOptional() @IsString() incidentDate?: string;
|
|
@IsOptional() @IsString() reportedDate?: string;
|
|
@IsOptional() @IsString() description?: string;
|
|
@IsOptional() @IsString() adjusterId?: string;
|
|
@IsOptional() @IsNumber() claimedAmount?: number;
|
|
@IsOptional() @IsNumber() settledAmount?: number;
|
|
@IsOptional() @IsString() settlementDate?: string;
|
|
@IsOptional() @IsString() checkNumber?: string;
|
|
@IsOptional() @IsBoolean() resolved?: boolean;
|
|
@IsOptional() @IsString() resolutionNotes?: string;
|
|
}
|
|
export class UpdateClaimDto extends ClaimDto {}
|