diff --git a/src/components/security/DataResetDialog.tsx b/src/components/security/DataResetDialog.tsx index c257a19..948553f 100644 --- a/src/components/security/DataResetDialog.tsx +++ b/src/components/security/DataResetDialog.tsx @@ -33,8 +33,8 @@ const DataResetDialog: React.FC = ({ 클라우드 데이터도 함께 삭제됩니다. {syncEnabled && ( -
- 동기화 설정이 비활성화됩니다. +
+ ※ 동기화 설정이 비활성화됩니다.
)} : "이 작업은 되돌릴 수 없으며, 모든 예산, 지출 내역, 설정이 영구적으로 삭제됩니다."} diff --git a/src/hooks/useDataReset.ts b/src/hooks/useDataReset.ts index e2219c6..ef6b225 100644 --- a/src/hooks/useDataReset.ts +++ b/src/hooks/useDataReset.ts @@ -27,18 +27,29 @@ export const useDataReset = () => { const syncWasEnabled = isSyncEnabled(); console.log('데이터 초기화 전 동기화 상태:', syncWasEnabled ? '활성화' : '비활성화'); - // 클라우드 데이터 초기화 먼저 시도 (로그인 상태인 경우) + // 중요: 클라우드 데이터 초기화 먼저 시도 (로그인 상태인 경우) let cloudResetSuccess = false; if (user) { console.log('로그인 상태: 클라우드 데이터 초기화 시도'); - cloudResetSuccess = await clearCloudData(user.id); - setIsCloudResetSuccess(cloudResetSuccess); - if (cloudResetSuccess) { - console.log('클라우드 데이터 초기화 성공'); - } else { - console.warn('클라우드 데이터 초기화 실패 또는 부분 성공'); + // 여러 번 시도하여 클라우드 데이터 초기화 확실히 하기 + for (let attempt = 1; attempt <= 3; attempt++) { + console.log(`클라우드 데이터 초기화 시도 ${attempt}/3`); + cloudResetSuccess = await clearCloudData(user.id); + + if (cloudResetSuccess) { + console.log('클라우드 데이터 초기화 성공'); + break; + } else { + console.warn(`클라우드 데이터 초기화 시도 ${attempt} 실패`); + // 잠시 대기 후 재시도 + if (attempt < 3) { + await new Promise(resolve => setTimeout(resolve, 500)); + } + } } + + setIsCloudResetSuccess(cloudResetSuccess); } else { console.log('로그인하지 않음: 클라우드 초기화 건너뜀'); setIsCloudResetSuccess(null); @@ -87,13 +98,17 @@ export const useDataReset = () => { } }); - // 중요: 동기화 설정은 초기화 후 항상 비활성화 + // 중요: 동기화 설정은 초기화 후 강제로 비활성화 setSyncEnabled(false); console.log('동기화 설정이 비활성화되었습니다.'); // 마지막 동기화 시간은 초기화 localStorage.removeItem('lastSync'); + // 삭제 플래그 초기화 (강제로 삭제 목록 초기화) + localStorage.removeItem('deletedTransactions'); + localStorage.removeItem('modifiedBudgets'); + // 스토리지 이벤트 트리거하여 다른 컴포넌트에 변경 알림 window.dispatchEvent(new Event('transactionUpdated')); window.dispatchEvent(new Event('budgetDataUpdated')); diff --git a/src/utils/sync/clearCloudData.ts b/src/utils/sync/clearCloudData.ts index 8b759d6..96783f8 100644 --- a/src/utils/sync/clearCloudData.ts +++ b/src/utils/sync/clearCloudData.ts @@ -13,41 +13,80 @@ export const clearCloudData = async (userId: string): Promise => { console.log('클라우드 데이터 초기화 시작'); try { - // 모든 트랜잭션 삭제 - const { error: transactionsError } = await supabase - .from('transactions') - .delete() - .eq('user_id', userId); - - if (transactionsError) { - console.error('트랜잭션 삭제 오류:', transactionsError); - return false; - } + // 모든 테이블에서 사용자 데이터 삭제 + const tablesToClear = ['transactions', 'category_budgets', 'budgets']; + const results = await Promise.allSettled( + tablesToClear.map(async (table) => { + // 먼저 데이터가 있는지 확인 + const { data: checkData } = await supabase + .from(table) + .select('id') + .eq('user_id', userId) + .limit(1); + + // 데이터가 없으면 삭제를 건너뜀 + if (!checkData || checkData.length === 0) { + console.log(`테이블 ${table}에 삭제할 데이터가 없습니다.`); + return true; + } + + // 데이터 삭제 + console.log(`테이블 ${table}에서 사용자 데이터 삭제 시도`); + const { error } = await supabase + .from(table) + .delete() + .eq('user_id', userId); + + if (error) { + console.error(`테이블 ${table} 데이터 삭제 오류:`, error); + return false; + } + + console.log(`테이블 ${table} 데이터 삭제 성공`); + return true; + }) + ); - // 카테고리 예산 삭제 - const { error: categoryBudgetsError } = await supabase - .from('category_budgets') - .delete() - .eq('user_id', userId); - - if (categoryBudgetsError) { - console.error('카테고리 예산 삭제 오류:', categoryBudgetsError); - return false; - } + // 삭제 확인을 위해 다시 데이터 조회 + const verificationResults = await Promise.all( + tablesToClear.map(async (table) => { + const { data, error } = await supabase + .from(table) + .select('id') + .eq('user_id', userId); + + if (error) { + console.error(`테이블 ${table} 검증 오류:`, error); + return false; + } + + // 남아있는 데이터가 있는지 확인 + const isEmpty = !data || data.length === 0; + console.log(`테이블 ${table} 검증 결과: ${isEmpty ? '비어있음' : `${data.length}개 항목 남아있음`}`); + + if (!isEmpty) { + // 한 번 더 삭제 시도 + console.log(`테이블 ${table}에 데이터가 남아있어 다시 삭제 시도`); + const { error: retryError } = await supabase + .from(table) + .delete() + .eq('user_id', userId); + + if (retryError) { + console.error(`테이블 ${table} 재삭제 오류:`, retryError); + return false; + } + } + + return isEmpty; + }) + ); - // 예산 삭제 - const { error: budgetsError } = await supabase - .from('budgets') - .delete() - .eq('user_id', userId); - - if (budgetsError) { - console.error('예산 삭제 오류:', budgetsError); - return false; - } + // 모든 테이블이 성공적으로 삭제되었는지 확인 + const allTablesCleared = verificationResults.every(result => result === true); - console.log('클라우드 데이터 초기화 완료'); - return true; + console.log('클라우드 데이터 초기화 완료, 결과:', allTablesCleared ? '성공' : '일부 실패'); + return allTablesCleared; } catch (error) { console.error('클라우드 데이터 초기화 중 오류 발생:', error); return false;