diff options
Diffstat (limited to 'lib/evaluation-submit/validation.ts')
| -rw-r--r-- | lib/evaluation-submit/validation.ts | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/lib/evaluation-submit/validation.ts b/lib/evaluation-submit/validation.ts new file mode 100644 index 00000000..dc6f3f0f --- /dev/null +++ b/lib/evaluation-submit/validation.ts @@ -0,0 +1,161 @@ +import { + createSearchParamsCache, + parseAsArrayOf, + parseAsInteger, + parseAsString, + parseAsStringEnum, +} from "nuqs/server" +import * as z from "zod" + +import { getFiltersStateParser, getSortingStateParser } from "@/lib/parsers" +import { ReviewerEvaluationView } from "@/db/schema"; + + +export const getSHIEvaluationsSubmitSchema = createSearchParamsCache({ + flags: parseAsArrayOf(z.enum(["advancedTable", "floatingBar"])).withDefault( + [] + ), + page: parseAsInteger.withDefault(1), + perPage: parseAsInteger.withDefault(10), + sort: getSortingStateParser<ReviewerEvaluationView>().withDefault([ + { id: "reviewerEvaluationCreatedAt", desc: true }, + ]), + + // advanced filter + filters: getFiltersStateParser().withDefault([]), + joinOperator: parseAsStringEnum(["and", "or"]).withDefault("and"), + search: parseAsString.withDefault(""), +}); + +export type GetSHIEvaluationsSubmitSchema = Awaited<ReturnType<typeof getSHIEvaluationsSubmitSchema.parse>> + +// 리뷰어 타입 상수 정의 +export const REVIEWER_TYPES = { + EQUIPMENT_SHIP: 'equipment_ship', + EQUIPMENT_MARINE: 'equipment_marine', + BULK_SHIP: 'bulk_ship', + BULK_MARINE: 'bulk_marine', +} as const; + +// 리뷰어 타입 union type +export type ReviewerType = typeof REVIEWER_TYPES[keyof typeof REVIEWER_TYPES]; + +// 답변 옵션 타입 (각 질문에 대한 선택 가능한 답변들) +export type EvaluationAnswerOption = { + detailId: number; + detail: string; + score: number; + orderIndex: number; + isNotApplicable?: boolean; // "해당없음" 옵션 여부 + isCustomScore?: boolean; // 사용자 직접 입력 옵션 여부 +}; + +// 평가 질문 항목 타입 +// 확장된 평가 질문 항목 타입 +export type EvaluationQuestionItem = { + // 질문 정보 (regEvalCriteria) + criteriaId: number; + category: string; + category2: string; + item: string; + classification: string; + range: string | null; + remarks: string | null; + + // 평가 및 점수 유형 + scoreType: ScoreType; // fixed | variable + + // 가변 점수용 설정 + variableScoreMin?: number; // 최소 점수 (예: -3) + variableScoreMax?: number; // 최대 점수 (예: +5) + variableScoreUnit?: string; // 단위 설명 (예: "1건당 1점", "1일당 0.5점") + + // 답변 옵션들 + availableOptions: EvaluationAnswerOption[]; + + // 현재 응답 정보 + responseId: number | null; + selectedDetailId: number | null; + currentScore: string | null; + currentComment: string | null; + + // 가변 점수용 추가 필드 + customScore?: number; // 사용자가 입력한 점수 + customScoreReason?: string; // 점수 입력 근거 +}; + + +// 평가 정보 타입 +export type EvaluationInfo = { + id: number; + periodicEvaluationId: number; + evaluationTargetReviewerId: number; + isCompleted: boolean; + + // 부서 및 벤더 정보 + departmentCode: string; + division: 'SHIP' | 'PLANT'; + materialType: 'EQUIPMENT' | 'BULK' | 'EQUIPMENT_BULK'; + vendorName: string; + vendorCode: string; + + // 계산된 리뷰어 타입 + reviewerType: ReviewerType; +}; + +// 전체 평가 폼 데이터 타입 +export type EvaluationFormData = { + evaluationInfo: EvaluationInfo; + questions: EvaluationQuestionItem[]; +}; + +// 평가 응답 업데이트용 타입 +export type EvaluationResponseUpdate = { + regEvalCriteriaDetailsId: number; // 선택된 답변 옵션의 ID + score: string; // 해당 답변 옵션의 점수 + comment?: string; +}; + +// 평가 제출 목록 조회용 뷰 타입 (기존 타입에서 확장) +export type EvaluationSubmissionWithVendor = { + vendor: { + id: number; + vendorCode: string; + vendorName: string; + countryCode: string; + contactEmail: string; + }; + _count: { + generalResponses: number; + esgResponses: number; + attachments: number; + }; +}; + +// 평가 카테고리 매핑 +export const EVALUATION_CATEGORIES = { + 'customer-service': 'CS 평가', + 'administrator': '관리자 평가', + 'procurement': '구매 평가', + 'design': '설계 평가', + 'sourcing': '조달 평가', + 'quality': '품질 평가', +} as const; + +// 부서 코드별 카테고리 매핑 +export const DEPARTMENT_CATEGORY_MAPPING = { + 'ORDER_EVAL': 'procurement', + 'PROCUREMENT_EVAL': 'sourcing', + 'QUALITY_EVAL': 'quality', + 'CS_EVAL': 'customer-service', + 'DESIGN_EVAL': 'design' +} as const; + +// 점수 유형 정의 +export const SCORE_TYPES = { + FIXED: 'fixed', // 미리 정해진 점수 (기존 방식) + VARIABLE: 'variable', // 사용자 직접 입력 점수 +} as const; + +export type ScoreType = typeof SCORE_TYPES[keyof typeof SCORE_TYPES]; + |
