Improve sync logging
Add more detailed logging for sync functionality to improve issue tracking.
This commit is contained in:
@@ -3,18 +3,25 @@ import { supabase } from '@/lib/supabase';
|
||||
import { Transaction } from '@/components/TransactionCard';
|
||||
import { isSyncEnabled } from '../syncSettings';
|
||||
import { formatDateForDisplay } from './dateUtils';
|
||||
import { getDeletedTransactions } from './deletedTransactionsTracker';
|
||||
import { getDeletedTransactions, isTransactionDeleted } from './deletedTransactionsTracker';
|
||||
|
||||
/**
|
||||
* Download transaction data from Supabase to local storage
|
||||
* 서버에서 로컬 스토리지로 데이터 다운로드 (병합 방식)
|
||||
*/
|
||||
export const downloadTransactions = async (userId: string): Promise<void> => {
|
||||
if (!isSyncEnabled()) return;
|
||||
if (!isSyncEnabled()) {
|
||||
console.log('[동기화] 다운로드: 동기화 비활성화 상태, 작업 건너뜀');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
console.log('[동기화] 서버에서 트랜잭션 데이터 다운로드 시작');
|
||||
|
||||
// 다운로드 시간 기록 (충돌 감지용)
|
||||
const downloadStartTime = new Date().toISOString();
|
||||
console.log(`[동기화] 다운로드 시작 시간: ${downloadStartTime}`);
|
||||
|
||||
// 대용량 데이터 처리를 위한 페이지네이션 설정
|
||||
const pageSize = 500; // 한 번에 가져올 최대 레코드 수
|
||||
let lastId = null;
|
||||
@@ -53,25 +60,31 @@ export const downloadTransactions = async (userId: string): Promise<void> => {
|
||||
if (data.length < pageSize) {
|
||||
hasMore = false;
|
||||
}
|
||||
|
||||
console.log(`[동기화] 페이지 다운로드 완료: ${data.length}개 항목`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`[동기화] 서버 데이터 다운로드 완료: 총 ${allServerData.length}개 항목`);
|
||||
|
||||
if (allServerData.length === 0) {
|
||||
console.log('[동기화] 서버에 저장된 트랜잭션 없음');
|
||||
return; // 서버에 데이터가 없으면 로컬 데이터 유지
|
||||
}
|
||||
|
||||
console.log(`[동기화] 서버에서 ${allServerData.length}개의 트랜잭션 다운로드`);
|
||||
|
||||
// 삭제된 트랜잭션 ID 목록 가져오기
|
||||
const deletedIds = getDeletedTransactions();
|
||||
console.log(`[동기화] 삭제된 트랜잭션 ${deletedIds.length}개 필터링 적용`);
|
||||
|
||||
if (deletedIds.length > 0) {
|
||||
console.log(`[동기화] 삭제 추적 항목: ${deletedIds.slice(0, 5).join(', ')}${deletedIds.length > 5 ? '...' : ''}`);
|
||||
}
|
||||
|
||||
// 서버 데이터를 로컬 형식으로 변환 (삭제된 항목 제외)
|
||||
const serverTransactions = allServerData
|
||||
.filter(t => {
|
||||
const transactionId = t.transaction_id || t.id;
|
||||
const isDeleted = deletedIds.includes(transactionId);
|
||||
const isDeleted = isTransactionDeleted(transactionId);
|
||||
if (isDeleted) {
|
||||
console.log(`[동기화] 삭제된 트랜잭션 필터링: ${transactionId}`);
|
||||
}
|
||||
@@ -108,7 +121,8 @@ export const downloadTransactions = async (userId: string): Promise<void> => {
|
||||
date: formattedDate,
|
||||
category: t.category || '기타',
|
||||
type: t.type || 'expense',
|
||||
notes: t.notes || ''
|
||||
notes: t.notes || '',
|
||||
serverTimestamp: t.updated_at || t.created_at || downloadStartTime
|
||||
};
|
||||
} catch (itemError) {
|
||||
console.error(`[동기화] 트랜잭션 변환 오류 (ID: ${t.transaction_id || t.id}):`, itemError);
|
||||
@@ -120,14 +134,19 @@ export const downloadTransactions = async (userId: string): Promise<void> => {
|
||||
date: new Date().toLocaleString('ko-KR'),
|
||||
category: '기타',
|
||||
type: 'expense',
|
||||
notes: '데이터 변환 중 오류 발생'
|
||||
notes: '데이터 변환 중 오류 발생',
|
||||
serverTimestamp: downloadStartTime
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`[동기화] 서버 트랜잭션 변환 완료: ${serverTransactions.length}개 항목`);
|
||||
|
||||
// 기존 로컬 데이터 불러오기
|
||||
const localDataStr = localStorage.getItem('transactions');
|
||||
const localTransactions = localDataStr ? JSON.parse(localDataStr) : [];
|
||||
const localTransactions: Transaction[] = localDataStr ? JSON.parse(localDataStr) : [];
|
||||
|
||||
console.log(`[동기화] 로컬 트랜잭션: ${localTransactions.length}개 항목`);
|
||||
|
||||
// 로컬 데이터와 서버 데이터 병합 (ID 기준)
|
||||
const transactionMap = new Map();
|
||||
@@ -135,26 +154,63 @@ export const downloadTransactions = async (userId: string): Promise<void> => {
|
||||
// 로컬 데이터를 맵에 추가
|
||||
localTransactions.forEach((tx: Transaction) => {
|
||||
if (tx && tx.id) { // 유효성 검사 추가
|
||||
transactionMap.set(tx.id, tx);
|
||||
// 로컬 항목에 타임스탬프 추가 (없는 경우)
|
||||
const txWithTimestamp = {
|
||||
...tx,
|
||||
localTimestamp: tx.localTimestamp || downloadStartTime
|
||||
};
|
||||
transactionMap.set(tx.id, txWithTimestamp);
|
||||
}
|
||||
});
|
||||
|
||||
// 서버 데이터로 맵 업데이트 (서버 데이터 우선)
|
||||
// 충돌 카운터
|
||||
let overwrittenCount = 0;
|
||||
let preservedCount = 0;
|
||||
|
||||
// 서버 데이터로 맵 업데이트 (타임스탬프 비교)
|
||||
serverTransactions.forEach(tx => {
|
||||
if (tx && tx.id) { // 유효성 검사 추가
|
||||
transactionMap.set(tx.id, tx);
|
||||
const existingTx = transactionMap.get(tx.id);
|
||||
|
||||
if (!existingTx) {
|
||||
// 로컬에 없는 새 항목
|
||||
transactionMap.set(tx.id, tx);
|
||||
console.log(`[동기화] 새 항목 추가: ${tx.id} - ${tx.title}`);
|
||||
} else {
|
||||
// 타임스탬프 비교로 최신 데이터 결정
|
||||
const serverTime = tx.serverTimestamp || downloadStartTime;
|
||||
const localTime = existingTx.localTimestamp || '1970-01-01T00:00:00Z';
|
||||
|
||||
if (serverTime > localTime) {
|
||||
// 서버 데이터가 더 최신
|
||||
transactionMap.set(tx.id, tx);
|
||||
overwrittenCount++;
|
||||
console.log(`[동기화] 서버 데이터로 업데이트: ${tx.id} - ${tx.title} (서버: ${serverTime}, 로컬: ${localTime})`);
|
||||
} else {
|
||||
// 로컬 데이터 유지
|
||||
preservedCount++;
|
||||
console.log(`[동기화] 로컬 데이터 유지: ${tx.id} - ${existingTx.title} (서버: ${serverTime}, 로컬: ${localTime})`);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 최종 병합된 데이터 생성
|
||||
const mergedTransactions = Array.from(transactionMap.values());
|
||||
|
||||
console.log(`[동기화] 병합 결과: 총 ${mergedTransactions.length}개 항목 (서버 데이터로 업데이트: ${overwrittenCount}, 로컬 데이터 유지: ${preservedCount})`);
|
||||
|
||||
// 로컬 스토리지에 저장
|
||||
localStorage.setItem('transactions', JSON.stringify(mergedTransactions));
|
||||
console.log(`[동기화] 총 ${mergedTransactions.length}개의 트랜잭션 병합 완료`);
|
||||
console.log(`[동기화] 병합된 트랜잭션 저장 완료`);
|
||||
|
||||
// 백업 저장
|
||||
localStorage.setItem('transactions_backup', JSON.stringify(mergedTransactions));
|
||||
console.log(`[동기화] 트랜잭션 백업 저장 완료`);
|
||||
|
||||
// 이벤트 발생시켜 UI 업데이트
|
||||
window.dispatchEvent(new Event('transactionUpdated'));
|
||||
console.log(`[동기화] 트랜잭션 업데이트 이벤트 발생`);
|
||||
} catch (error) {
|
||||
console.error('[동기화] 트랜잭션 다운로드 중 오류:', error);
|
||||
console.error('[동기화] 오류 상세:', JSON.stringify(error, null, 2));
|
||||
|
||||
Reference in New Issue
Block a user