diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-06-19 09:44:28 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-06-19 09:44:28 +0000 |
| commit | 95bbe9c583ff841220da1267630e7b2025fc36dc (patch) | |
| tree | 5e3d5bb3302530bbaa7f7abbe8c9cf8193ccbd4c /lib/evaluation-target-list/validation.ts | |
| parent | 0eb030580b5cbe5f03d570c3c9d8c519bac3b783 (diff) | |
(대표님) 20250619 1844 KST 작업사항
Diffstat (limited to 'lib/evaluation-target-list/validation.ts')
| -rw-r--r-- | lib/evaluation-target-list/validation.ts | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/lib/evaluation-target-list/validation.ts b/lib/evaluation-target-list/validation.ts new file mode 100644 index 00000000..e42f536b --- /dev/null +++ b/lib/evaluation-target-list/validation.ts @@ -0,0 +1,169 @@ +import { + createSearchParamsCache, + parseAsArrayOf, + parseAsInteger, + parseAsString, + parseAsStringEnum, + } from "nuqs/server"; + import * as z from "zod"; + + import { getFiltersStateParser, getSortingStateParser } from "@/lib/parsers"; + + // ============= 메인 검색 파라미터 스키마 ============= + + export const searchParamsEvaluationTargetsCache = createSearchParamsCache({ + flags: parseAsArrayOf(z.enum(["advancedTable", "floatingBar"])).withDefault([]), + page: parseAsInteger.withDefault(1), + perPage: parseAsInteger.withDefault(10), + sort: getSortingStateParser<any>().withDefault([ + { id: "createdAt", desc: true }, + ]), + + // 기본 필터들 + evaluationYear: parseAsInteger.withDefault(new Date().getFullYear()), + division: parseAsString.withDefault(""), + status: parseAsString.withDefault(""), + domesticForeign: parseAsString.withDefault(""), + materialType: parseAsString.withDefault(""), + consensusStatus: parseAsString.withDefault(""), + + // 고급 필터 + filters: getFiltersStateParser().withDefault([]), + joinOperator: parseAsStringEnum(["and", "or"]).withDefault("and"), + + // 베이직 필터 (커스텀 필터 패널용) + basicFilters: getFiltersStateParser().withDefault([]), + basicJoinOperator: parseAsStringEnum(["and", "or"]).withDefault("and"), + + // 검색 + search: parseAsString.withDefault(""), + }); + + // ============= 타입 정의 ============= + + export type GetEvaluationTargetsSchema = Awaited< + ReturnType<typeof searchParamsEvaluationTargetsCache.parse> + >; + + export type EvaluationTargetStatus = "PENDING" | "CONFIRMED" | "EXCLUDED"; + export type Division = "OCEAN" | "SHIPYARD"; + export type MaterialType = "EQUIPMENT" | "BULK" | "EQUIPMENT_BULK"; + export type DomesticForeign = "DOMESTIC" | "FOREIGN"; + + // ============= 필터 옵션 상수들 ============= + + export const EVALUATION_TARGET_FILTER_OPTIONS = { + DIVISIONS: [ + { value: "OCEAN", label: "해양" }, + { value: "SHIPYARD", label: "조선" }, + ], + STATUSES: [ + { value: "PENDING", label: "검토 중" }, + { value: "CONFIRMED", label: "확정" }, + { value: "EXCLUDED", label: "제외" }, + ], + DOMESTIC_FOREIGN: [ + { value: "DOMESTIC", label: "내자" }, + { value: "FOREIGN", label: "외자" }, + ], + MATERIAL_TYPES: [ + { value: "EQUIPMENT", label: "기자재" }, + { value: "BULK", label: "벌크" }, + { value: "EQUIPMENT_BULK", label: "기자재/벌크" }, + ], + CONSENSUS_STATUS: [ + { value: "true", label: "의견 일치" }, + { value: "false", label: "의견 불일치" }, + { value: "null", label: "검토 중" }, + ], + } as const; + + // ============= 유효성 검사 함수들 ============= + + export function validateEvaluationYear(year: number): boolean { + const currentYear = new Date().getFullYear(); + return year >= 2020 && year <= currentYear + 1; + } + + export function validateDivision(division: string): division is Division { + return ["OCEAN", "SHIPYARD"].includes(division); + } + + export function validateStatus(status: string): status is EvaluationTargetStatus { + return ["PENDING", "CONFIRMED", "EXCLUDED"].includes(status); + } + + export function validateMaterialType(materialType: string): materialType is MaterialType { + return ["EQUIPMENT", "BULK", "EQUIPMENT_BULK"].includes(materialType); + } + + export function validateDomesticForeign(domesticForeign: string): domesticForeign is DomesticForeign { + return ["DOMESTIC", "FOREIGN"].includes(domesticForeign); + } + + // ============= 기본값 제공 함수들 ============= + + export function getDefaultEvaluationYear(): number { + return new Date().getFullYear(); + } + + export function getDefaultSearchParams(): GetEvaluationTargetsSchema { + return { + flags: [], + page: 1, + perPage: 10, + sort: [{ id: "createdAt", desc: true }], + evaluationYear: getDefaultEvaluationYear(), + division: "", + status: "", + domesticForeign: "", + materialType: "", + consensusStatus: "", + filters: [], + joinOperator: "and", + basicFilters: [], + basicJoinOperator: "and", + search: "", + }; + } + + // ============= 편의 함수들 ============= + + // 상태별 라벨 반환 + export function getStatusLabel(status: EvaluationTargetStatus): string { + const statusMap = { + PENDING: "검토 중", + CONFIRMED: "확정", + EXCLUDED: "제외" + }; + return statusMap[status] || status; + } + + // 구분별 라벨 반환 + export function getDivisionLabel(division: Division): string { + const divisionMap = { + OCEAN: "해양", + SHIPYARD: "조선" + }; + return divisionMap[division] || division; + } + + // 자재구분별 라벨 반환 + export function getMaterialTypeLabel(materialType: MaterialType): string { + const materialTypeMap = { + EQUIPMENT: "기자재", + BULK: "벌크", + EQUIPMENT_BULK: "기자재/벌크" + }; + return materialTypeMap[materialType] || materialType; + } + + // 내외자별 라벨 반환 + export function getDomesticForeignLabel(domesticForeign: DomesticForeign): string { + const domesticForeignMap = { + DOMESTIC: "내자", + FOREIGN: "외자" + }; + return domesticForeignMap[domesticForeign] || domesticForeign; + } + |
