summaryrefslogtreecommitdiff
path: root/hooks/use-sync-status.ts
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-08-04 09:36:14 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-08-04 09:36:14 +0000
commit92eda21e45d902663052575aaa4c4f80bfa2faea (patch)
tree8483702edf82932d4359a597a854fa8e1b48e94b /hooks/use-sync-status.ts
parentf0213de0d2fb5fcb931b3ddaddcbb6581cab5d28 (diff)
(대표님) 벤더 문서 변경사항, data-table 변경, sync 변경
Diffstat (limited to 'hooks/use-sync-status.ts')
-rw-r--r--hooks/use-sync-status.ts102
1 files changed, 51 insertions, 51 deletions
diff --git a/hooks/use-sync-status.ts b/hooks/use-sync-status.ts
index 99810fdc..52a67343 100644
--- a/hooks/use-sync-status.ts
+++ b/hooks/use-sync-status.ts
@@ -11,7 +11,7 @@ interface SyncStatus {
failedChanges: number
lastSyncAt?: string | null
error?: string | null
- contractId?: number
+ projectId?: number
targetSystem?: string
lastUpdated?: string
}
@@ -23,7 +23,7 @@ interface ApiError extends Error {
interface SyncBatch {
id: string
- contractId: number
+ projectId: number
targetSystem: string
status: 'PENDING' | 'RUNNING' | 'COMPLETED' | 'FAILED'
startedAt?: string
@@ -35,7 +35,7 @@ interface SyncBatch {
}
interface SyncConfig {
- contractId: number
+ projectId: number
targetSystem: string
autoSyncEnabled: boolean
syncInterval: number
@@ -77,21 +77,21 @@ const fetcher = async (url: string): Promise<any> => {
}
// 🔧 안전한 기본값 생성
-const createDefaultSyncStatus = (error?: string, contractId?: number): SyncStatus => ({
+const createDefaultSyncStatus = (error?: string, projectId?: number): SyncStatus => ({
syncEnabled: false,
pendingChanges: 0,
syncedChanges: 0,
failedChanges: 0,
lastSyncAt: null,
error,
- contractId,
+ projectId,
lastUpdated: new Date().toISOString()
})
// ✅ 단일 계약 동기화 상태 조회
-export function useSyncStatus(contractId: number | null, targetSystem: string = 'SHI') {
- const key = contractId
- ? `/api/sync/status?contractId=${contractId}&targetSystem=${targetSystem}`
+export function useSyncStatus(projectId: number | null, targetSystem: string = 'SHI') {
+ const key = projectId
+ ? `/api/sync/status?projectId=${projectId}&targetSystem=${targetSystem}`
: null
const { data, error, isLoading, mutate: localMutate } = useSWR<SyncStatus>(
@@ -130,7 +130,7 @@ export function useSyncStatus(contractId: number | null, targetSystem: string =
failedChanges: Number(data.failedChanges) || 0,
lastSyncAt: data.lastSyncAt || null,
error: data.error || (error ? (error as ApiError).message : null),
- contractId: contractId || data.contractId,
+ projectId: projectId || data.projectId,
targetSystem: targetSystem,
lastUpdated: new Date().toISOString()
}
@@ -138,13 +138,13 @@ export function useSyncStatus(contractId: number | null, targetSystem: string =
return createDefaultSyncStatus(
error ? (error as ApiError).message : undefined,
- contractId || undefined
+ projectId || undefined
)
- }, [data, error, contractId, targetSystem])
+ }, [data, error, projectId, targetSystem])
return {
syncStatus: safeData,
- isLoading: isLoading && Boolean(contractId),
+ isLoading: isLoading && Boolean(projectId),
error: error as ApiError | null,
refetch
}
@@ -154,16 +154,16 @@ export function useSyncStatus(contractId: number | null, targetSystem: string =
// 대신 useDynamicSyncStatus 사용 권장
// ✅ 다중 계약 동기화 상태 조회 (Hook 규칙 준수)
-export function useDynamicSyncStatus(contractIds: number[], targetSystem: string = 'SHI') {
+export function useDynamicSyncStatus(projectIds: number[], targetSystem: string = 'SHI') {
// Hook 규칙 준수: 고정된 수의 Hook 호출
const paddedContractIds = React.useMemo(() => {
// 입력 검증 및 경고
- if (contractIds.length > MAX_CONTRACTS) {
- console.warn(`Contract count (${contractIds.length}) exceeds maximum (${MAX_CONTRACTS}). Only first ${MAX_CONTRACTS} will be processed.`)
+ if (projectIds.length > MAX_CONTRACTS) {
+ console.warn(`Contract count (${projectIds.length}) exceeds maximum (${MAX_CONTRACTS}). Only first ${MAX_CONTRACTS} will be processed.`)
}
// 🔥 명시적 타입 선언
- const padded: (number | null)[] = [...contractIds.slice(0, MAX_CONTRACTS)]
+ const padded: (number | null)[] = [...projectIds.slice(0, MAX_CONTRACTS)]
// null로 패딩
while (padded.length < MAX_CONTRACTS) {
@@ -171,17 +171,17 @@ export function useDynamicSyncStatus(contractIds: number[], targetSystem: string
}
return padded
- }, [contractIds])
+ }, [projectIds])
// 각 contractId에 대해 고정된 수의 Hook 호출
- const allResults = paddedContractIds.map((contractId) => {
- const result = useSyncStatus(contractId, targetSystem)
- return contractId ? { contractId, ...result } : null
+ const allResults = paddedContractIds.map((projectId) => {
+ const result = useSyncStatus(projectId, targetSystem)
+ return projectId ? { projectId, ...result } : null
})
// 유효한 결과만 필터링
const validResults = React.useMemo(() => {
return allResults.filter((result): result is {
- contractId: number
+ projectId: number
syncStatus: SyncStatus
isLoading: boolean
error: ApiError | null
@@ -214,9 +214,9 @@ export function useDynamicSyncStatus(contractIds: number[], targetSystem: string
totalFailed,
hasError,
isLoading,
- canSync: totalPending > 0 && !hasError && contractIds.length > 0
+ canSync: totalPending > 0 && !hasError && projectIds.length > 0
}
- }, [validResults, contractIds.length])
+ }, [validResults, projectIds.length])
const refetchAll = React.useCallback(() => {
validResults.forEach(({ refetch }) => {
@@ -236,7 +236,7 @@ export function useDynamicSyncStatus(contractIds: number[], targetSystem: string
}
// ✅ 클라이언트 전용 동기화 상태 조회 (서버 사이드 렌더링 호환)
-export function useClientSyncStatus(contractIds: number[], targetSystem: string = 'SHI') {
+export function useClientSyncStatus(projectIds: number[], targetSystem: string = 'SHI',) {
const [isClient, setIsClient] = React.useState(false)
React.useEffect(() => {
@@ -244,7 +244,7 @@ export function useClientSyncStatus(contractIds: number[], targetSystem: string
}, [])
const syncResult = useDynamicSyncStatus(
- isClient ? contractIds : [],
+ isClient ? projectIds : [],
targetSystem
)
@@ -268,9 +268,9 @@ export function useClientSyncStatus(contractIds: number[], targetSystem: string
}
// ✅ 동기화 배치 목록 조회
-export function useSyncBatches(contractId: number | null, targetSystem: string = 'SHI') {
- const key = contractId
- ? `/api/sync/batches?contractId=${contractId}&targetSystem=${targetSystem}`
+export function useSyncBatches(projectId: number | null, targetSystem: string = 'SHI') {
+ const key = projectId
+ ? `/api/sync/batches?projectId=${projectId}&targetSystem=${targetSystem}`
: null
const { data, error, isLoading } = useSWR<SyncBatch[]>(
@@ -285,15 +285,15 @@ export function useSyncBatches(contractId: number | null, targetSystem: string =
return {
syncBatches: data || [],
- isLoading: isLoading && Boolean(contractId),
+ isLoading: isLoading && Boolean(projectId),
error: error as ApiError | null
}
}
// ✅ 동기화 설정 조회
-export function useSyncConfig(contractId: number | null, targetSystem: string = 'SHI') {
- const key = contractId
- ? `/api/sync/config?contractId=${contractId}&targetSystem=${targetSystem}`
+export function useSyncConfig(projectId: number | null, targetSystem: string = 'SHI') {
+ const key = projectId
+ ? `/api/sync/config?projectId=${projectId}&targetSystem=${targetSystem}`
: null
const { data, error, isLoading, mutate: localMutate } = useSWR<SyncConfig>(
@@ -313,7 +313,7 @@ export function useSyncConfig(contractId: number | null, targetSystem: string =
return {
syncConfig: data,
- isLoading: isLoading && Boolean(contractId),
+ isLoading: isLoading && Boolean(projectId),
error: error as ApiError | null,
refetch
}
@@ -323,7 +323,7 @@ export function useSyncConfig(contractId: number | null, targetSystem: string =
export function useTriggerSync() {
const { trigger, isMutating, error } = useSWRMutation(
'/api/sync/trigger',
- async (url: string, { arg }: { arg: { contractId: number; targetSystem?: string } }) => {
+ async (url: string, { arg }: { arg: { projectId: number; targetSystem?: string } }) => {
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
@@ -342,14 +342,14 @@ export function useTriggerSync() {
}
)
- const triggerSync = React.useCallback(async (arg: { contractId: number; targetSystem?: string }) => {
+ const triggerSync = React.useCallback(async (arg: { projectId: number; targetSystem?: string }) => {
try {
const result = await trigger(arg)
// 성공 후 관련 캐시 무효화
const targetSystem = arg.targetSystem || 'SHI'
- const statusKey = `/api/sync/status?contractId=${arg.contractId}&targetSystem=${targetSystem}`
- const batchesKey = `/api/sync/batches?contractId=${arg.contractId}&targetSystem=${targetSystem}`
+ const statusKey = `/api/sync/status?projectId=${arg.projectId}&targetSystem=${targetSystem}`
+ const batchesKey = `/api/sync/batches?projectId=${arg.projectId}&targetSystem=${targetSystem}`
globalMutate(statusKey)
globalMutate(batchesKey)
@@ -372,7 +372,7 @@ export function useTriggerSync() {
export function useUpdateSyncConfig() {
const { trigger, isMutating, error } = useSWRMutation(
'/api/sync/config',
- async (url: string, { arg }: { arg: Partial<SyncConfig> & { contractId: number; targetSystem: string } }) => {
+ async (url: string, { arg }: { arg: Partial<SyncConfig> & { projectId: number; targetSystem: string } }) => {
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
@@ -393,13 +393,13 @@ export function useUpdateSyncConfig() {
)
// ✅ 수동 캐시 무효화를 포함한 래핑 함수
- const updateConfig = React.useCallback(async (arg: Partial<SyncConfig> & { contractId: number; targetSystem: string }) => {
+ const updateConfig = React.useCallback(async (arg: Partial<SyncConfig> & { projectId: number; targetSystem: string }) => {
try {
const result = await trigger(arg)
// ✅ 성공 후 수동으로 캐시 무효화
- const { contractId, targetSystem } = arg
- const configKey = `/api/sync/config?contractId=${contractId}&targetSystem=${targetSystem}`
+ const { projectId, targetSystem } = arg
+ const configKey = `/api/sync/config?projectId=${projectId}&targetSystem=${targetSystem}`
globalMutate(configKey)
return result
@@ -416,9 +416,9 @@ export function useUpdateSyncConfig() {
}
}
// ✅ 실시간 동기화 상태 훅 (높은 갱신 빈도)
-export function useRealtimeSyncStatus(contractId: number | null, targetSystem: string = 'SHI') {
- const key = contractId
- ? `/api/sync/status?contractId=${contractId}&targetSystem=${targetSystem}&realtime=true`
+export function useRealtimeSyncStatus(projectId: number | null, targetSystem: string = 'SHI') {
+ const key = projectId
+ ? `/api/sync/status?projectId=${projectId}&targetSystem=${targetSystem}&realtime=true`
: null
const { data, error, isLoading } = useSWR<SyncStatus>(
@@ -436,13 +436,13 @@ export function useRealtimeSyncStatus(contractId: number | null, targetSystem: s
const safeData = React.useMemo(() => {
return data || createDefaultSyncStatus(
error ? (error as ApiError).message : undefined,
- contractId || undefined
+ projectId || undefined
)
- }, [data, error, contractId])
+ }, [data, error, projectId])
return {
syncStatus: safeData,
- isLoading: isLoading && Boolean(contractId),
+ isLoading: isLoading && Boolean(projectId),
error: error as ApiError | null
}
}
@@ -450,10 +450,10 @@ export function useRealtimeSyncStatus(contractId: number | null, targetSystem: s
// 🔧 유틸리티 함수들
export const syncUtils = {
// 캐시 수동 무효화
- invalidateCache: (contractId: number, targetSystem: string = 'SHI') => {
- const statusKey = `/api/sync/status?contractId=${contractId}&targetSystem=${targetSystem}`
- const batchesKey = `/api/sync/batches?contractId=${contractId}&targetSystem=${targetSystem}`
- const configKey = `/api/sync/config?contractId=${contractId}&targetSystem=${targetSystem}`
+ invalidateCache: (projectId: number, targetSystem: string = 'SHI') => {
+ const statusKey = `/api/sync/status?projectId=${projectId}&targetSystem=${targetSystem}`
+ const batchesKey = `/api/sync/batches?projectId=${projectId}&targetSystem=${targetSystem}`
+ const configKey = `/api/sync/config?projectId=${projectId}&targetSystem=${targetSystem}`
globalMutate(statusKey)
globalMutate(batchesKey)