summaryrefslogtreecommitdiff
path: root/lib/evaluation-submit/validation.ts
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-07-07 01:44:45 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-07-07 01:44:45 +0000
commit90f79a7a691943a496f67f01c1e493256070e4de (patch)
tree37275fde3ae08c2bca384fbbc8eb378de7e39230 /lib/evaluation-submit/validation.ts
parentfbb3b7f05737f9571b04b0a8f4f15c0928de8545 (diff)
(대표님) 변경사항 20250707 10시 43분 - unstaged 변경사항 추가
Diffstat (limited to 'lib/evaluation-submit/validation.ts')
-rw-r--r--lib/evaluation-submit/validation.ts161
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];
+