From 1532c1bf4a3236ce9056f33e51ddfebeff79ed5a Mon Sep 17 00:00:00 2001 From: dujinkim Date: Mon, 17 Nov 2025 07:06:52 +0000 Subject: (최겸) 구매 피드백 처리 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/vendor-investigation/validations.ts | 89 ++++++++++++++++++++++++++++++--- 1 file changed, 81 insertions(+), 8 deletions(-) (limited to 'lib/vendor-investigation/validations.ts') diff --git a/lib/vendor-investigation/validations.ts b/lib/vendor-investigation/validations.ts index 891ef178..84361ef9 100644 --- a/lib/vendor-investigation/validations.ts +++ b/lib/vendor-investigation/validations.ts @@ -98,6 +98,20 @@ export const updateVendorInvestigationProgressSchema = z message: "실사 수행 예정일은 필수입니다.", }) } + + // 날짜 순서 검증: forecastedAt과 confirmedAt 간의 관계 검증 + if (data.forecastedAt && data.confirmedAt) { + const forecastedDate = new Date(data.forecastedAt); + const confirmedDate = new Date(data.confirmedAt); + + if (confirmedDate < forecastedDate) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + path: ["confirmedAt"], + message: "실사 계획 확정일은 실사 수행 예정일보다 과거일 수 없습니다.", + }); + } + } }) export type UpdateVendorInvestigationProgressSchema = z.infer @@ -114,15 +128,33 @@ export const updateVendorInvestigationResultSchema = z.object({ z.string().transform((str) => str ? new Date(str) : undefined) ]), + // 실사의뢰일 (날짜 검증을 위해 추가) + requestedAt: z.union([ + z.date(), + z.string().transform((str) => str ? new Date(str) : undefined) + ]).optional(), + evaluationScore: z.number() .int("평가 점수는 정수여야 합니다.") .min(0, "평가 점수는 0점 이상이어야 합니다.") .max(100, "평가 점수는 100점 이하여야 합니다."), evaluationResult: z.enum(["APPROVED", "SUPPLEMENT", "SUPPLEMENT_REINSPECT", "SUPPLEMENT_DOCUMENT", "REJECTED", "RESULT_SENT"]), investigationNotes: z.string().max(1000, "QM 의견은 1000자 이내로 입력해주세요.").optional(), - attachments: z.any({ - required_error: "첨부파일은 필수입니다." - }), + attachments: z.array(z.any()).min(1, "최소 1개의 첨부파일이 필요합니다."), +}).superRefine((data, ctx) => { + // 날짜 검증: 실제 실사일이 실사의뢰일보다 과거가 되지 않도록 검증 + if (data.requestedAt && data.completedAt) { + const requestedDate = new Date(data.requestedAt); + const completedDate = new Date(data.completedAt); + + if (completedDate < requestedDate) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + path: ["completedAt"], + message: "실제 실사일은 실사의뢰일보다 과거일 수 없습니다.", + }); + } + } }) export type UpdateVendorInvestigationResultSchema = z.infer @@ -137,28 +169,28 @@ export const updateVendorInvestigationSchema = z.object({ }), investigationAddress: z.string().optional(), investigationMethod: z.enum(["PURCHASE_SELF_EVAL", "DOCUMENT_EVAL", "PRODUCT_INSPECTION", "SITE_VISIT_EVAL"]).optional(), - + // 날짜 필드들 forecastedAt: z.union([ z.date(), z.string().transform((str) => str ? new Date(str) : undefined) ]).optional(), - + requestedAt: z.union([ z.date(), z.string().transform((str) => str ? new Date(str) : undefined) ]).optional(), - + confirmedAt: z.union([ z.date(), z.string().transform((str) => str ? new Date(str) : undefined) ]).optional(), - + completedAt: z.union([ z.date(), z.string().transform((str) => str ? new Date(str) : undefined) ]).optional(), - + evaluationScore: z.number() .int("평가 점수는 정수여야 합니다.") .min(0, "평가 점수는 0점 이상이어야 합니다.") @@ -167,6 +199,47 @@ export const updateVendorInvestigationSchema = z.object({ evaluationResult: z.enum(["APPROVED", "SUPPLEMENT", "SUPPLEMENT_REINSPECT", "SUPPLEMENT_DOCUMENT", "REJECTED", "RESULT_SENT"]).optional(), investigationNotes: z.string().max(1000, "QM 의견은 1000자 이내로 입력해주세요.").optional(), attachments: z.any().optional(), // File 업로드를 위한 필드 +}).superRefine((data, ctx) => { + // 날짜 검증: 실사의뢰일(requestedAt)이 있는 경우 다른 날짜들이 실사의뢰일보다 과거가 되지 않도록 검증 + if (data.requestedAt) { + const requestedDate = new Date(data.requestedAt); + + // 실사수행/계획일(forecastedAt) 검증 + if (data.forecastedAt) { + const forecastedDate = new Date(data.forecastedAt); + if (forecastedDate < requestedDate) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + path: ["forecastedAt"], + message: "실사 수행 예정일은 실사의뢰일보다 과거일 수 없습니다.", + }); + } + } + + // 실사 계획 확정일(confirmedAt) 검증 + if (data.confirmedAt) { + const confirmedDate = new Date(data.confirmedAt); + if (confirmedDate < requestedDate) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + path: ["confirmedAt"], + message: "실사 계획 확정일은 실사의뢰일보다 과거일 수 없습니다.", + }); + } + } + + // 실제 실사일(completedAt) 검증 + if (data.completedAt) { + const completedDate = new Date(data.completedAt); + if (completedDate < requestedDate) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + path: ["completedAt"], + message: "실제 실사일은 실사의뢰일보다 과거일 수 없습니다.", + }); + } + } + } }) export type UpdateVendorInvestigationSchema = z.infer \ No newline at end of file -- cgit v1.2.3