Files
invyone/frontend/hooks/queries/useCodeDetail.ts
T
DDD1542 2348800e68
Build & Deploy to K8s / build-and-deploy (push) Successful in 9m22s
refactor(common-code): 마스터-디테일 재설계 — code_info(그룹) + code_detail(재귀 트리)
카테고리/캐스케이딩 시스템 (B/C/D) 전부 폐기:
- BE: mapper/Service/Controller 9세트 삭제 (cascading*, categoryTree, tableCategoryValue, categoryValueCascading, codeMerge)
- FE: 페이지 3 + API 8 + hooks 2 + 폐기 컴포넌트 6 삭제, 14곳 의존성 정리
- DB: 12 테이블 DROP, TABLE_TYPE_COLUMNS.CODE_CATEGORY → CODE_INFO rename

신설 commonCode 마스터-디테일:
- code_info: 1레벨 그룹 마스터
- code_detail: 2~∞ depth 재귀 트리 (parent_detail_id self-FK, depth 자동 계산)
- API: /api/common-codes/{info,detail}
- CodeCategoryFormModal/Panel → CodeInfoFormModal/Panel rename
- code_category 컬럼명 전부 code_info 로 치환 (mapper/Java/FE)
- 옛 commonCode API URL (/categories/...) → getCodeOptions 어댑터 + /detail?code_info=... 전환

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 16:50:50 +09:00

102 lines
2.9 KiB
TypeScript

import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import {
createCodeDetail,
deleteCodeDetail,
getCodeDetailInfo,
getCodeDetailTree,
updateCodeDetail,
} from "@/lib/api/commonCode";
import { queryKeys } from "@/lib/queryKeys";
import type { CodeDetailFilter } from "@/lib/schemas/commonCode";
/**
* 그룹의 전체 디테일 트리 조회 (평탄화 리스트, depth+sort_order 정렬)
*
* BE 가 트리를 평탄화해서 한 번에 내려주므로 페이징 없음.
* 평탄화 리스트 + parent_detail_id 로 FE 에서 트리 indentation 처리.
*/
export function useCodeDetailTree(codeInfo: string | undefined, filters?: CodeDetailFilter) {
return useQuery({
queryKey: queryKeys.codeDetail.tree(codeInfo || "", filters),
queryFn: () =>
getCodeDetailTree({
code_info: codeInfo!,
search: filters?.search,
is_active: filters?.active,
}),
enabled: !!codeInfo,
select: (data) => data.data || [],
staleTime: 5 * 60 * 1000,
});
}
/**
* 디테일 단건
*/
export function useCodeDetailInfo(codeDetailId: number | string | undefined) {
return useQuery({
queryKey: queryKeys.codeDetail.detail(codeDetailId ?? ""),
queryFn: () => getCodeDetailInfo(codeDetailId!),
enabled: codeDetailId !== undefined && codeDetailId !== null && codeDetailId !== "",
select: (data) => data.data,
});
}
/**
* 디테일 생성
*/
export function useCreateCodeDetail() {
const qc = useQueryClient();
return useMutation({
mutationFn: (data: Record<string, any>) => createCodeDetail(data),
onSuccess: () => {
qc.invalidateQueries({ queryKey: queryKeys.codeDetail.all });
},
onError: (error) => {
console.error("디테일 생성 실패:", error);
},
});
}
/**
* 디테일 수정
*/
export function useUpdateCodeDetail() {
const qc = useQueryClient();
return useMutation({
mutationFn: ({
codeDetailId,
data,
}: {
codeDetailId: number | string;
data: Record<string, any>;
}) => updateCodeDetail(codeDetailId, data),
onSuccess: (_, variables) => {
qc.invalidateQueries({
queryKey: queryKeys.codeDetail.detail(variables.codeDetailId),
});
qc.invalidateQueries({ queryKey: queryKeys.codeDetail.all });
},
onError: (error) => {
console.error("디테일 수정 실패:", error);
},
});
}
/**
* 디테일 삭제 (CASCADE)
*/
export function useDeleteCodeDetail() {
const qc = useQueryClient();
return useMutation({
mutationFn: (codeDetailId: number | string) => deleteCodeDetail(codeDetailId),
onSuccess: (_, codeDetailId) => {
qc.invalidateQueries({ queryKey: queryKeys.codeDetail.all });
qc.removeQueries({ queryKey: queryKeys.codeDetail.detail(codeDetailId) });
},
onError: (error) => {
console.error("디테일 삭제 실패:", error);
},
});
}