import { z } from "zod"; import { isDiagnosticToken, MODEL_REPLAY_LIMITS, replayModelRun, calibrateBfPriorFromModel, type ModelRun, type ModelPriorCalibrationRequest, type ModelPriorCalibrationResult } from "@actuarial-ts/core"; import { alignedExposureInputSchema, analysisSnapshotSchema, bfPriorCalibrationRequestSchema, modelRequestSchema } from "./reviewContracts.js"; import { parseReviewBoundary } from "./reviewBoundary.js"; const token = z.string().refine(isDiagnosticToken, "Expected a valid identifier"); export const modelReplayLimitsSchema = z.object({ maximumInputCharacters: z.number().int().positive().max(MODEL_REPLAY_LIMITS.maximumInputCharacters) }).strict(); /** Internal graph builder: retained results are checked by full core replay, not a shape assertion. */ export function modelPriorCalibrationSchemaForRun(run: T) { return z.object({ id: token, version: token, run, exposure: alignedExposureInputSchema, snapshots: z.array(analysisSnapshotSchema), selection: bfPriorCalibrationRequestSchema.shape.selection, sourceRelationship: bfPriorCalibrationRequestSchema.shape.sourceRelationship, assumption: bfPriorCalibrationRequestSchema.shape.assumption, limits: modelReplayLimitsSchema }).strict(); } // Validate the actual request while preserving every supplied result field for core checks/replay. export const retainedModelInputSchema = z.unknown().superRefine((value, context) => { const parsed = z.object({ request: modelRequestSchema }).passthrough().safeParse(value); if (!parsed.success) for (const issue of parsed.error.issues) context.addIssue(issue); }); export const modelPriorCalibrationRequestSchema = modelPriorCalibrationSchemaForRun(retainedModelInputSchema); export function parseModelPriorCalibrationRequest(input: unknown): ModelPriorCalibrationRequest { return parseReviewBoundary(modelPriorCalibrationRequestSchema, input) as ModelPriorCalibrationRequest; } export function replayModelRunFromInput(input: unknown): ModelRun { const raw = parseReviewBoundary(z.object({ run: retainedModelInputSchema, limits: modelReplayLimitsSchema }).strict(), input); return replayModelRun({ ...raw, run: raw.run as ModelRun }); } export function calibrateBfPriorFromModelInput(input: unknown): ModelPriorCalibrationResult { return calibrateBfPriorFromModel(parseModelPriorCalibrationRequest(input)); }