import { z } from "zod"; import { isDiagnosticToken, isRealIsoDate, REVIEW_DEVELOPMENT_LIMITS, transformReviewDevelopment, viewReviewDevelopment, type ReviewDevelopmentTransformRequest, type ReviewDevelopmentViewRequest, type ReviewDevelopmentTransformation, type ReviewDevelopmentView, accumulateReviewDevelopment, validateIncrementalDevelopmentSource, type IncrementalDevelopmentSource, type ReviewDevelopmentAccumulationRequest, type ReviewDevelopmentAccumulation } from "@actuarial-ts/core"; import { developmentCalendarInputSchema, analysisReferenceSchema, modelDevelopmentSourceSchema, analysisContextSchema, quantitySemanticsSchema, analysisSnapshotSchema, developmentOriginAggregationRequestSchema, developmentIntervalViewSchema } from "./reviewContracts.js"; import { parseReviewBoundary } from "./reviewBoundary.js"; const token = z.string().refine(isDiagnosticToken, "Expected a valid identifier"); const date = z.string().refine(isRealIsoDate, "Expected a real ISO date"); /** Internal builder shared with closed graph link positions. Lazy public schemas avoid recursive module initialization. */ export function reviewDevelopmentSchemaForInput() { return z.object({ id: token, version: token, source: modelDevelopmentSourceSchema, context: analysisContextSchema, quantity: quantitySemanticsSchema, snapshots: z.array(analysisSnapshotSchema), declaration: z.object({ actorId: token, knownDate: date, rationale: token }).strict(), limits: z.object({ maximumOrigins: z.number().int().positive().max(REVIEW_DEVELOPMENT_LIMITS.maximumOrigins), maximumCells: z.number().int().positive().max(REVIEW_DEVELOPMENT_LIMITS.maximumCells), maximumInputCharacters: z.number().int().positive().max(REVIEW_DEVELOPMENT_LIMITS.maximumInputCharacters), maximumTransformationDepth: z.number().int().positive().max(REVIEW_DEVELOPMENT_LIMITS.maximumTransformationDepth) }).strict(), }).strict(); } export const reviewDevelopmentTransformOperationSchema = z.lazy(() => z.discriminatedUnion("kind", [ z.object({ kind: z.literal("truncate"), cutoff: date }).strict(), z.object({ kind: z.literal("aggregate-origins"), targets: developmentOriginAggregationRequestSchema.shape.targets, partialPeriodPolicy: developmentOriginAggregationRequestSchema.shape.partialPeriodPolicy, exposurePolicy: z.literal("require-realignment") }).strict(), ])); export const reviewDevelopmentViewOperationSchema = z.lazy(() => z.discriminatedUnion("kind", [ z.object({ kind: z.literal("intervals"), opening: developmentIntervalViewSchema.shape.opening }).strict(), z.object({ kind: z.literal("maturity"), maturityMonths: z.number().int().safe().nonnegative() }).strict(), z.object({ kind: z.literal("calendar") }).strict(), ])); export const reviewDevelopmentTransformRequestSchema: z.ZodType = z.lazy(() => reviewDevelopmentSchemaForInput().extend({ operation: reviewDevelopmentTransformOperationSchema })); export const reviewDevelopmentViewRequestSchema: z.ZodType = z.lazy(() => reviewDevelopmentSchemaForInput().extend({ operation: reviewDevelopmentViewOperationSchema })); export function parseReviewDevelopmentTransformRequest(input: unknown): ReviewDevelopmentTransformRequest { return parseReviewBoundary(reviewDevelopmentTransformRequestSchema, input); } export function transformReviewDevelopmentFromInput(input: unknown): ReviewDevelopmentTransformation { return transformReviewDevelopment(parseReviewDevelopmentTransformRequest(input)); } export function parseReviewDevelopmentViewRequest(input: unknown): ReviewDevelopmentViewRequest { return parseReviewBoundary(reviewDevelopmentViewRequestSchema, input); } export function viewReviewDevelopmentFromInput(input: unknown): ReviewDevelopmentView { return viewReviewDevelopment(parseReviewDevelopmentViewRequest(input)); } export const incrementalDevelopmentSourceSchema: z.ZodType = z.lazy(() => z.object({ kind: z.literal("incremental-development-source"), knownDate: date, measure: z.enum(["paid", "incurred"]), origins: developmentCalendarInputSchema.shape.origins, intervals: developmentIntervalViewSchema.shape.intervals, values: developmentIntervalViewSchema.shape.values, opening: developmentIntervalViewSchema.shape.opening, ageConvention: developmentCalendarInputSchema.shape.ageConvention, valuations: developmentCalendarInputSchema.shape.valuations, reference: analysisReferenceSchema, }).strict()); /** Internal builder for the graph's documented context, quantity and evidence link positions. */ export function reviewDevelopmentAccumulationSchemaForInput() { return reviewDevelopmentSchemaForInput().extend({ source: incrementalDevelopmentSourceSchema }); } export const reviewDevelopmentAccumulationRequestSchema: z.ZodType = z.lazy(reviewDevelopmentAccumulationSchemaForInput); export function parseIncrementalDevelopmentSource(input: unknown): IncrementalDevelopmentSource { return validateIncrementalDevelopmentSource(parseReviewBoundary(incrementalDevelopmentSourceSchema, input)); } export function parseReviewDevelopmentAccumulationRequest(input: unknown): ReviewDevelopmentAccumulationRequest { return parseReviewBoundary(reviewDevelopmentAccumulationRequestSchema, input); } export function accumulateReviewDevelopmentFromInput(input: unknown): ReviewDevelopmentAccumulation { return accumulateReviewDevelopment(parseReviewDevelopmentAccumulationRequest(input)); }