06ced6a863
vexplor 로코드툴의 code_category/code_info 2-테이블 구조 대신 wace_plm 원본 comm_code(847건) 위에서 직접 동작하도록 백엔드 service 전면 재작성. 영업관리 등 이미 comm_code에 의존 중인 화면들과 데이터 소스 일치. - backend service: comm_code 단일 테이블 기반(top-level=parent_code_id 빈값) 으로 재작성. 다단계 계층은 재귀 CTE로 depth/parent_code_value 산출. 단일 테넌시라 company_code/menu_objid 필터링은 시그니처만 유지하고 무시 - comm_code에 sort_order INT 컬럼 추가(드래그 정렬 유지) — DB 마이그레이션 - frontend schema: 영문명/설명을 optional로 완화(wace 컬럼 부재) - 카테고리/코드 폼 모달에서 영문명·설명 입력 필드 제거 - 패널 레이아웃을 화면 높이에 고정 + 좌우 패널 자체 스크롤로 분리 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
69 lines
3.0 KiB
TypeScript
69 lines
3.0 KiB
TypeScript
import { z } from "zod";
|
|
|
|
/**
|
|
* 공통코드 관련 Zod 스키마 정의
|
|
*/
|
|
|
|
// 카테고리 스키마
|
|
// 공통코드 저장소가 wace `comm_code` 단일 테이블이라 영문명/설명 컬럼이 없음 → 선택 입력으로 둠.
|
|
export const categorySchema = z.object({
|
|
categoryCode: z
|
|
.string()
|
|
.min(1, "카테고리 코드는 필수입니다")
|
|
.max(50, "카테고리 코드는 50자 이하여야 합니다")
|
|
.regex(/^[A-Z0-9_]+$/, "대문자, 숫자, 언더스코어(_)만 사용 가능합니다"),
|
|
categoryName: z.string().min(1, "카테고리명은 필수입니다").max(100, "카테고리명은 100자 이하여야 합니다"),
|
|
categoryNameEng: z.string().max(100, "영문 카테고리명은 100자 이하여야 합니다").optional().or(z.literal("")),
|
|
description: z.string().max(500, "설명은 500자 이하여야 합니다").optional().or(z.literal("")),
|
|
sortOrder: z.number().min(1, "정렬 순서는 1 이상이어야 합니다").max(9999, "정렬 순서는 9999 이하여야 합니다"),
|
|
});
|
|
|
|
// 카테고리 생성 스키마
|
|
export const createCategorySchema = categorySchema;
|
|
|
|
// 카테고리 수정 스키마 (카테고리 코드 제외)
|
|
export const updateCategorySchema = categorySchema.omit({ categoryCode: true }).extend({
|
|
isActive: z.enum(["Y", "N"]),
|
|
});
|
|
|
|
// 코드 스키마
|
|
export const codeSchema = z.object({
|
|
codeValue: z.string().min(1, "코드값은 필수입니다").max(50, "코드값은 50자 이하여야 합니다"),
|
|
codeName: z.string().min(1, "코드명은 필수입니다").max(100, "코드명은 100자 이하여야 합니다"),
|
|
codeNameEng: z.string().max(100, "영문 코드명은 100자 이하여야 합니다").optional().or(z.literal("")),
|
|
description: z.string().max(500, "설명은 500자 이하여야 합니다").optional().or(z.literal("")),
|
|
sortOrder: z.number().min(1, "정렬 순서는 1 이상이어야 합니다").max(9999, "정렬 순서는 9999 이하여야 합니다"),
|
|
parentCodeValue: z.string().optional().nullable(), // 계층구조: 부모 코드값 (선택)
|
|
});
|
|
|
|
// 코드 생성 스키마
|
|
export const createCodeSchema = codeSchema;
|
|
|
|
// 코드 수정 스키마 (코드값 제외)
|
|
export const updateCodeSchema = codeSchema.omit({ codeValue: true }).extend({
|
|
isActive: z.enum(["Y", "N"]),
|
|
});
|
|
|
|
// TypeScript 타입 추론
|
|
export type CategoryFormData = z.infer<typeof categorySchema>;
|
|
export type CreateCategoryData = z.infer<typeof createCategorySchema>;
|
|
export type UpdateCategoryData = z.infer<typeof updateCategorySchema>;
|
|
|
|
export type CodeFormData = z.infer<typeof codeSchema>;
|
|
export type CreateCodeData = z.infer<typeof createCodeSchema>;
|
|
export type UpdateCodeData = z.infer<typeof updateCodeSchema>;
|
|
|
|
// 검색 필터 스키마
|
|
export const categoryFilterSchema = z.object({
|
|
search: z.string().optional(),
|
|
active: z.boolean().optional(),
|
|
});
|
|
|
|
export const codeFilterSchema = z.object({
|
|
search: z.string().optional(),
|
|
active: z.boolean().optional(),
|
|
});
|
|
|
|
export type CategoryFilter = z.infer<typeof categoryFilterSchema>;
|
|
export type CodeFilter = z.infer<typeof codeFilterSchema>;
|