summaryrefslogtreecommitdiff
path: root/hooks
diff options
context:
space:
mode:
Diffstat (limited to 'hooks')
-rw-r--r--hooks/use-sync-api.ts76
-rw-r--r--hooks/use-sync-status.ts189
2 files changed, 265 insertions, 0 deletions
diff --git a/hooks/use-sync-api.ts b/hooks/use-sync-api.ts
new file mode 100644
index 00000000..18421209
--- /dev/null
+++ b/hooks/use-sync-api.ts
@@ -0,0 +1,76 @@
+// hooks/use-sync-api.ts (API 호출 전용 훅들)
+import useSWR from 'swr'
+import useSWRMutation from 'swr/mutation'
+import { mutate } from 'swr'
+import { ApiClient } from '@/lib/api-utils'
+
+// 동기화 상태 API 훅
+export function useSyncStatusApi(contractId: number, targetSystem: string = 'SHI') {
+ const key = contractId ? `sync-status-${contractId}-${targetSystem}` : null
+
+ const { data, error, isLoading } = useSWR(
+ key,
+ async () => ApiClient.get('/sync/status', { contractId, targetSystem }),
+ {
+ refreshInterval: 30000,
+ revalidateOnFocus: true,
+ errorRetryCount: 1,
+ errorRetryInterval: 5000,
+ }
+ )
+
+ const refetch = () => {
+ if (key) mutate(key)
+ }
+
+ return {
+ syncStatus: data,
+ isLoading,
+ error,
+ refetch
+ }
+}
+
+// 동기화 트리거 API 훅
+export function useTriggerSyncApi() {
+ const { trigger, isMutating, error } = useSWRMutation(
+ 'trigger-sync',
+ async (key: string, { arg }: { arg: { contractId: number; targetSystem?: string } }) => {
+ return ApiClient.post('/sync/trigger', arg)
+ },
+ {
+ onSuccess: (data, key, config) => {
+ const { contractId, targetSystem = 'SHI' } = config.arg
+ // 관련 캐시 무효화
+ mutate(`sync-status-${contractId}-${targetSystem}`)
+ mutate(`sync-batches-${contractId}-${targetSystem}`)
+ },
+ }
+ )
+
+ return {
+ triggerSync: trigger,
+ isLoading: isMutating,
+ error
+ }
+}
+
+// 동기화 배치 API 훅
+export function useSyncBatchesApi(contractId: number, targetSystem: string = 'SHI') {
+ const key = contractId ? `sync-batches-${contractId}-${targetSystem}` : null
+
+ const { data, error, isLoading } = useSWR(
+ key,
+ async () => ApiClient.get('/sync/batches', { contractId, targetSystem }),
+ {
+ revalidateOnFocus: false,
+ errorRetryCount: 1,
+ }
+ )
+
+ return {
+ syncBatches: data,
+ isLoading,
+ error
+ }
+} \ No newline at end of file
diff --git a/hooks/use-sync-status.ts b/hooks/use-sync-status.ts
new file mode 100644
index 00000000..07cb3432
--- /dev/null
+++ b/hooks/use-sync-status.ts
@@ -0,0 +1,189 @@
+// hooks/use-sync-status.ts (수정된 버전)
+import useSWR from 'swr'
+import useSWRMutation from 'swr/mutation'
+import { mutate } from 'swr'
+
+// 단순한 fetcher 함수들
+const fetcher = async (url: string) => {
+ const response = await fetch(url)
+ if (!response.ok) {
+ const error = new Error(`HTTP ${response.status}`)
+ ;(error as any).status = response.status
+ throw error
+ }
+ return response.json()
+}
+
+// 동기화 상태 조회
+export function useSyncStatus(contractId: number, targetSystem: string = 'SHI') {
+ const key = contractId
+ ? `/api/sync/status?contractId=${contractId}&targetSystem=${targetSystem}`
+ : null
+
+ const { data, error, isLoading } = useSWR(
+ key,
+ fetcher,
+ {
+ refreshInterval: 30000, // 30초마다 갱신
+ revalidateOnFocus: true,
+ revalidateOnReconnect: true,
+ shouldRetryOnError: false, // 에러시 자동 재시도 비활성화
+ dedupingInterval: 5000, // 5초 내 중복 요청 방지
+ }
+ )
+
+ const refetch = () => {
+ if (key) {
+ mutate(key)
+ }
+ }
+
+ return {
+ syncStatus: data,
+ isLoading,
+ error,
+ refetch
+ }
+}
+
+// 동기화 배치 목록 조회
+export function useSyncBatches(contractId: number, targetSystem: string = 'SHI') {
+ const key = contractId
+ ? `/api/sync/batches?contractId=${contractId}&targetSystem=${targetSystem}`
+ : null
+
+ const { data, error, isLoading } = useSWR(
+ key,
+ fetcher,
+ {
+ revalidateOnFocus: false,
+ shouldRetryOnError: false,
+ }
+ )
+
+ return {
+ syncBatches: data,
+ isLoading,
+ error
+ }
+}
+
+// 동기화 설정 조회
+export function useSyncConfig(contractId: number, targetSystem: string = 'SHI') {
+ const key = contractId
+ ? `/api/sync/config?contractId=${contractId}&targetSystem=${targetSystem}`
+ : null
+
+ const { data, error, isLoading } = useSWR(
+ key,
+ fetcher,
+ {
+ revalidateOnFocus: false,
+ shouldRetryOnError: false,
+ }
+ )
+
+ return {
+ syncConfig: data,
+ isLoading,
+ error
+ }
+}
+
+// 동기화 트리거 (뮤테이션)
+export function useTriggerSync() {
+ const { trigger, isMutating, error } = useSWRMutation(
+ '/api/sync/trigger',
+ async (url: string, { arg }: { arg: { contractId: number; targetSystem?: string } }) => {
+ const response = await fetch(url, {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(arg)
+ })
+
+ if (!response.ok) {
+ const errorData = await response.json().catch(() => ({}))
+ const error = new Error(errorData.message || `HTTP ${response.status}`)
+ ;(error as any).status = response.status
+ throw error
+ }
+
+ return response.json()
+ },
+ {
+ onSuccess: (data, key, config) => {
+ // 관련 캐시 무효화
+ const { contractId, targetSystem = 'SHI' } = config.arg
+ const statusKey = `/api/sync/status?contractId=${contractId}&targetSystem=${targetSystem}`
+ const batchesKey = `/api/sync/batches?contractId=${contractId}&targetSystem=${targetSystem}`
+
+ mutate(statusKey)
+ mutate(batchesKey)
+ },
+ onError: (error) => {
+ console.error('Sync trigger failed:', error)
+ }
+ }
+ )
+
+ return {
+ triggerSync: trigger,
+ isLoading: isMutating,
+ error
+ }
+}
+
+// 동기화 설정 업데이트 (뮤테이션)
+export function useUpdateSyncConfig() {
+ const { trigger, isMutating, error } = useSWRMutation(
+ '/api/sync/config',
+ async (url: string, { arg }: { arg: any }) => {
+ const response = await fetch(url, {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(arg)
+ })
+
+ if (!response.ok) {
+ const errorData = await response.json().catch(() => ({}))
+ const error = new Error(errorData.message || `HTTP ${response.status}`)
+ ;(error as any).status = response.status
+ throw error
+ }
+
+ return response.json()
+ },
+ {
+ onSuccess: (data, key, config) => {
+ // 설정 캐시 무효화
+ const { contractId, targetSystem } = config.arg
+ const configKey = `/api/sync/config?contractId=${contractId}&targetSystem=${targetSystem}`
+ mutate(configKey)
+ },
+ }
+ )
+
+ return {
+ updateConfig: trigger,
+ isLoading: isMutating,
+ error
+ }
+}
+
+// 실시간 동기화 상태 훅 (높은 갱신 빈도)
+export function useRealtimeSyncStatus(contractId: number, targetSystem: string = 'SHI') {
+ const key = contractId
+ ? `/api/sync/status?contractId=${contractId}&targetSystem=${targetSystem}&realtime=true`
+ : null
+
+ return useSWR(
+ key,
+ fetcher,
+ {
+ refreshInterval: 5000, // 5초마다 갱신 (실시간)
+ revalidateOnFocus: true,
+ revalidateOnReconnect: true,
+ shouldRetryOnError: false,
+ }
+ )
+} \ No newline at end of file