summaryrefslogtreecommitdiff
path: root/lib/evaluation-target-list/validation.ts
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-06-19 09:44:28 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-06-19 09:44:28 +0000
commit95bbe9c583ff841220da1267630e7b2025fc36dc (patch)
tree5e3d5bb3302530bbaa7f7abbe8c9cf8193ccbd4c /lib/evaluation-target-list/validation.ts
parent0eb030580b5cbe5f03d570c3c9d8c519bac3b783 (diff)
(대표님) 20250619 1844 KST 작업사항
Diffstat (limited to 'lib/evaluation-target-list/validation.ts')
-rw-r--r--lib/evaluation-target-list/validation.ts169
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;
+ }
+