import { z } from "zod"; import { isDiagnosticToken, isRealIsoDate, REVIEW_DEVELOPMENT_ADJUSTMENT_LIMITS, adjustReviewDevelopment, validateReviewDevelopmentAdjustmentRequest, type ReviewDevelopmentAdjustmentRequest, type ReviewDevelopmentAdjustment } from "@actuarial-ts/core"; import { analysisReferenceSchema, modelDevelopmentSourceSchema, analysisContextSchema, quantitySemanticsSchema, analysisSnapshotSchema, assumptionSnapshotSchema, reviewCountDefinitionSchema } from "./reviewContracts.js"; import { parseReviewBoundary } from "./reviewBoundary.js"; const token = z.string().refine(isDiagnosticToken, "Expected a valid identifier"), date = z.string().refine(isRealIsoDate, "Expected a real ISO date"); /** Builders are lazy because source bindings retain complete adjustment requests. */ export function reviewDevelopmentAdjustmentSchemaForInput() { const operand = z.object({ source: modelDevelopmentSourceSchema, context: analysisContextSchema, quantity: quantitySemanticsSchema }).strict(); return z.object({ id: token, version: token, method: z.literal("berquistCaseAdequacy"), inputs: z.object({ paid: operand, incurred: operand, openCounts: operand.extend({ countDefinition: reviewCountDefinitionSchema }).strict() }).strict(), severityTrend: assumptionSnapshotSchema, originPeriodMonths: z.union([z.literal(1), z.literal(3), z.literal(12)]), snapshots: z.array(analysisSnapshotSchema), relationships: z.array(z.object({ operand: z.enum(["incurred", "openCounts"]), relationship: z.literal("same-covered-claims"), rationale: token, evidence: z.array(analysisReferenceSchema) }).strict()).length(2), declaration: z.object({ actorId: token, knownDate: date, rationale: token }).strict(), policies: z.object({ missingInputs: z.enum(["retain-unavailable", "reject-incomplete"]), unavailableDiagonal: z.enum(["reject", "retain-unadjusted-qualified"]) }).strict(), limits: z.object({ maximumOrigins: z.number().int().positive().max(REVIEW_DEVELOPMENT_ADJUSTMENT_LIMITS.maximumOrigins), maximumCells: z.number().int().positive().max(REVIEW_DEVELOPMENT_ADJUSTMENT_LIMITS.maximumCells), maximumInputCharacters: z.number().int().positive().max(REVIEW_DEVELOPMENT_ADJUSTMENT_LIMITS.maximumInputCharacters), maximumTransformationDepth: z.number().int().positive().max(REVIEW_DEVELOPMENT_ADJUSTMENT_LIMITS.maximumTransformationDepth), maximumAncestrySources: z.number().int().positive().max(REVIEW_DEVELOPMENT_ADJUSTMENT_LIMITS.maximumAncestrySources) }).strict(), }).strict(); } export const reviewDevelopmentAdjustmentRequestSchema: z.ZodType = z.lazy(reviewDevelopmentAdjustmentSchemaForInput); export function parseReviewDevelopmentAdjustmentRequest(input: unknown): ReviewDevelopmentAdjustmentRequest { return parseReviewBoundary(reviewDevelopmentAdjustmentRequestSchema, input); } export function validateReviewDevelopmentAdjustmentFromInput(input: unknown): { readonly request: ReviewDevelopmentAdjustmentRequest; readonly findings: ReviewDevelopmentAdjustment["findings"] } { return validateReviewDevelopmentAdjustmentRequest(parseReviewDevelopmentAdjustmentRequest(input)); } export function adjustReviewDevelopmentFromInput(input: unknown): ReviewDevelopmentAdjustment { return adjustReviewDevelopment(parseReviewDevelopmentAdjustmentRequest(input)); }