diff options
Diffstat (limited to 'lib/evaluation-target-list/validation.ts')
| -rw-r--r-- | lib/evaluation-target-list/validation.ts | 318 |
1 files changed, 151 insertions, 167 deletions
diff --git a/lib/evaluation-target-list/validation.ts b/lib/evaluation-target-list/validation.ts index ce5604be..b8df250b 100644 --- a/lib/evaluation-target-list/validation.ts +++ b/lib/evaluation-target-list/validation.ts @@ -1,169 +1,153 @@ 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 = "PLANT" | "SHIP"; - export type MaterialType = "EQUIPMENT" | "BULK" | "EQUIPMENT_BULK"; - export type DomesticForeign = "DOMESTIC" | "FOREIGN"; - - // ============= 필터 옵션 상수들 ============= - - export const EVALUATION_TARGET_FILTER_OPTIONS = { - DIVISIONS: [ - { value: "PLANT", label: "해양" }, - { value: "SHIP", 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 ["PLANT", "SHIP"].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 = { - PLANT: "해양", - SHIP: "조선" - }; - 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; - } + createSearchParamsCache, + parseAsArrayOf, + parseAsInteger, + parseAsString, + parseAsStringEnum, +} from "nuqs/server"; +import * as z from "zod"; + +import { getFiltersStateParser, getSortingStateParser } from "@/lib/parsers"; +import { Division, DomesticForeign, EvaluationTargetStatus, MaterialType, divisionMap, domesticForeignMap, vendortypeMap } from "@/types/evaluation"; + +// ============= 메인 검색 파라미터 스키마 ============= + +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 const EVALUATION_TARGET_FILTER_OPTIONS = { + DIVISIONS: [ + { value: "PLANT", label: "해양" }, + { value: "SHIP", 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 ["PLANT", "SHIP"].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 { + return divisionMap[division] || division; +} + +// 자재구분별 라벨 반환 +export function getMaterialTypeLabel(materialType: MaterialType): string { + return vendortypeMap[materialType] || materialType; +} + +// 내외자별 라벨 반환 +export function getDomesticForeignLabel(domesticForeign: DomesticForeign): string { + return domesticForeignMap[domesticForeign] || domesticForeign; +} |
