Refactor syncUtils module

Refactor the syncUtils module to improve code organization and maintainability by breaking it down into smaller, more focused utility functions.
This commit is contained in:
gpt-engineer-app[bot]
2025-03-15 05:12:43 +00:00
parent 8783a607fa
commit d74acdbbb8
4 changed files with 233 additions and 199 deletions

View File

@@ -0,0 +1,127 @@
import { supabase } from '@/lib/supabase';
import { isSyncEnabled } from './syncSettings';
/**
* Upload budget data from local storage to Supabase
*/
export const uploadBudgets = async (userId: string): Promise<void> => {
if (!isSyncEnabled()) return;
try {
const budgetData = localStorage.getItem('budgetData');
const categoryBudgets = localStorage.getItem('categoryBudgets');
if (budgetData) {
const parsedBudgetData = JSON.parse(budgetData);
// 기존 예산 데이터 삭제
await supabase
.from('budgets')
.delete()
.eq('user_id', userId);
// 새 예산 데이터 삽입
const { error } = await supabase.from('budgets').insert({
user_id: userId,
daily_target: parsedBudgetData.daily.targetAmount,
weekly_target: parsedBudgetData.weekly.targetAmount,
monthly_target: parsedBudgetData.monthly.targetAmount
});
if (error) throw error;
}
if (categoryBudgets) {
const parsedCategoryBudgets = JSON.parse(categoryBudgets);
// 기존 카테고리 예산 삭제
await supabase
.from('category_budgets')
.delete()
.eq('user_id', userId);
// 카테고리별 예산 데이터 변환 및 삽입
const categoryEntries = Object.entries(parsedCategoryBudgets).map(
([category, amount]) => ({
user_id: userId,
category,
amount
})
);
const { error } = await supabase
.from('category_budgets')
.insert(categoryEntries);
if (error) throw error;
}
console.log('예산 데이터 업로드 완료');
} catch (error) {
console.error('예산 데이터 업로드 실패:', error);
}
};
/**
* Download budget data from Supabase to local storage
*/
export const downloadBudgets = async (userId: string): Promise<void> => {
if (!isSyncEnabled()) return;
try {
// 예산 데이터 가져오기
const { data: budgetData, error: budgetError } = await supabase
.from('budgets')
.select('*')
.eq('user_id', userId)
.single();
if (budgetError && budgetError.code !== 'PGRST116') throw budgetError;
// 카테고리 예산 가져오기
const { data: categoryData, error: categoryError } = await supabase
.from('category_budgets')
.select('*')
.eq('user_id', userId);
if (categoryError) throw categoryError;
if (budgetData) {
// 예산 데이터 로컬 형식으로 변환
const localBudgetData = {
daily: {
targetAmount: budgetData.daily_target,
spentAmount: 0, // 지출액은 로컬에서 계산
remainingAmount: budgetData.daily_target
},
weekly: {
targetAmount: budgetData.weekly_target,
spentAmount: 0,
remainingAmount: budgetData.weekly_target
},
monthly: {
targetAmount: budgetData.monthly_target,
spentAmount: 0,
remainingAmount: budgetData.monthly_target
}
};
localStorage.setItem('budgetData', JSON.stringify(localBudgetData));
}
if (categoryData && categoryData.length > 0) {
// 카테고리 예산 로컬 형식으로 변환
const localCategoryBudgets = categoryData.reduce((acc, curr) => {
acc[curr.category] = curr.amount;
return acc;
}, {} as Record<string, number>);
localStorage.setItem('categoryBudgets', JSON.stringify(localCategoryBudgets));
}
console.log('예산 데이터 다운로드 완료');
} catch (error) {
console.error('예산 데이터 다운로드 실패:', error);
}
};

View File

@@ -0,0 +1,16 @@
// Core synchronization settings utilities
/**
* Check if synchronization is enabled in local storage
*/
export const isSyncEnabled = (): boolean => {
return localStorage.getItem('syncEnabled') === 'true';
};
/**
* Update synchronization settings in local storage
*/
export const setSyncEnabled = (enabled: boolean): void => {
localStorage.setItem('syncEnabled', enabled.toString());
};

View File

@@ -0,0 +1,76 @@
import { supabase } from '@/lib/supabase';
import { Transaction } from '@/components/TransactionCard';
import { isSyncEnabled } from './syncSettings';
/**
* Upload transaction data from local storage to Supabase
*/
export const uploadTransactions = async (userId: string): Promise<void> => {
if (!isSyncEnabled()) return;
try {
const localTransactions = localStorage.getItem('transactions');
if (!localTransactions) return;
const transactions: Transaction[] = JSON.parse(localTransactions);
// 기존 데이터 삭제 후 새로 업로드
await supabase
.from('transactions')
.delete()
.eq('user_id', userId);
// 트랜잭션 배치 처리
const { error } = await supabase.from('transactions').insert(
transactions.map(t => ({
user_id: userId,
title: t.title,
amount: t.amount,
date: t.date,
category: t.category,
type: t.type,
transaction_id: t.id // 로컬 ID 보존
}))
);
if (error) throw error;
console.log('트랜잭션 업로드 완료');
} catch (error) {
console.error('트랜잭션 업로드 실패:', error);
}
};
/**
* Download transaction data from Supabase to local storage
*/
export const downloadTransactions = async (userId: string): Promise<void> => {
if (!isSyncEnabled()) return;
try {
const { data, error } = await supabase
.from('transactions')
.select('*')
.eq('user_id', userId);
if (error) throw error;
if (data && data.length > 0) {
// Supabase 형식에서 로컬 형식으로 변환
const transactions = data.map(t => ({
id: t.transaction_id || t.id,
title: t.title,
amount: t.amount,
date: t.date,
category: t.category,
type: t.type
}));
localStorage.setItem('transactions', JSON.stringify(transactions));
console.log('트랜잭션 다운로드 완료');
}
} catch (error) {
console.error('트랜잭션 다운로드 실패:', error);
}
};

View File

@@ -1,206 +1,21 @@
import { supabase } from '@/lib/supabase'; import { isSyncEnabled, setSyncEnabled } from './sync/syncSettings';
import { Transaction } from '@/components/TransactionCard'; import { uploadTransactions, downloadTransactions } from './sync/transactionSync';
import { uploadBudgets, downloadBudgets } from './sync/budgetSync';
// 동기화 상태 확인 // Export all utility functions to maintain the same public API
export const isSyncEnabled = (): boolean => { export {
return localStorage.getItem('syncEnabled') === 'true'; isSyncEnabled,
setSyncEnabled,
uploadTransactions,
downloadTransactions,
uploadBudgets,
downloadBudgets
}; };
// 동기화 설정 변경 /**
export const setSyncEnabled = (enabled: boolean): void => { * Synchronize all data with Supabase
localStorage.setItem('syncEnabled', enabled.toString()); */
};
// 로컬 트랜잭션 데이터를 Supabase에 업로드
export const uploadTransactions = async (userId: string): Promise<void> => {
if (!isSyncEnabled()) return;
try {
const localTransactions = localStorage.getItem('transactions');
if (!localTransactions) return;
const transactions: Transaction[] = JSON.parse(localTransactions);
// 기존 데이터 삭제 후 새로 업로드
await supabase
.from('transactions')
.delete()
.eq('user_id', userId);
// 트랜잭션 배치 처리
const { error } = await supabase.from('transactions').insert(
transactions.map(t => ({
user_id: userId,
title: t.title,
amount: t.amount,
date: t.date,
category: t.category,
type: t.type,
transaction_id: t.id // 로컬 ID 보존
}))
);
if (error) throw error;
console.log('트랜잭션 업로드 완료');
} catch (error) {
console.error('트랜잭션 업로드 실패:', error);
}
};
// Supabase에서 트랜잭션 데이터 다운로드
export const downloadTransactions = async (userId: string): Promise<void> => {
if (!isSyncEnabled()) return;
try {
const { data, error } = await supabase
.from('transactions')
.select('*')
.eq('user_id', userId);
if (error) throw error;
if (data && data.length > 0) {
// Supabase 형식에서 로컬 형식으로 변환
const transactions = data.map(t => ({
id: t.transaction_id || t.id,
title: t.title,
amount: t.amount,
date: t.date,
category: t.category,
type: t.type
}));
localStorage.setItem('transactions', JSON.stringify(transactions));
console.log('트랜잭션 다운로드 완료');
}
} catch (error) {
console.error('트랜잭션 다운로드 실패:', error);
}
};
// 예산 데이터 업로드
export const uploadBudgets = async (userId: string): Promise<void> => {
if (!isSyncEnabled()) return;
try {
const budgetData = localStorage.getItem('budgetData');
const categoryBudgets = localStorage.getItem('categoryBudgets');
if (budgetData) {
const parsedBudgetData = JSON.parse(budgetData);
// 기존 예산 데이터 삭제
await supabase
.from('budgets')
.delete()
.eq('user_id', userId);
// 새 예산 데이터 삽입
const { error } = await supabase.from('budgets').insert({
user_id: userId,
daily_target: parsedBudgetData.daily.targetAmount,
weekly_target: parsedBudgetData.weekly.targetAmount,
monthly_target: parsedBudgetData.monthly.targetAmount
});
if (error) throw error;
}
if (categoryBudgets) {
const parsedCategoryBudgets = JSON.parse(categoryBudgets);
// 기존 카테고리 예산 삭제
await supabase
.from('category_budgets')
.delete()
.eq('user_id', userId);
// 카테고리별 예산 데이터 변환 및 삽입
const categoryEntries = Object.entries(parsedCategoryBudgets).map(
([category, amount]) => ({
user_id: userId,
category,
amount
})
);
const { error } = await supabase
.from('category_budgets')
.insert(categoryEntries);
if (error) throw error;
}
console.log('예산 데이터 업로드 완료');
} catch (error) {
console.error('예산 데이터 업로드 실패:', error);
}
};
// 예산 데이터 다운로드
export const downloadBudgets = async (userId: string): Promise<void> => {
if (!isSyncEnabled()) return;
try {
// 예산 데이터 가져오기
const { data: budgetData, error: budgetError } = await supabase
.from('budgets')
.select('*')
.eq('user_id', userId)
.single();
if (budgetError && budgetError.code !== 'PGRST116') throw budgetError;
// 카테고리 예산 가져오기
const { data: categoryData, error: categoryError } = await supabase
.from('category_budgets')
.select('*')
.eq('user_id', userId);
if (categoryError) throw categoryError;
if (budgetData) {
// 예산 데이터 로컬 형식으로 변환
const localBudgetData = {
daily: {
targetAmount: budgetData.daily_target,
spentAmount: 0, // 지출액은 로컬에서 계산
remainingAmount: budgetData.daily_target
},
weekly: {
targetAmount: budgetData.weekly_target,
spentAmount: 0,
remainingAmount: budgetData.weekly_target
},
monthly: {
targetAmount: budgetData.monthly_target,
spentAmount: 0,
remainingAmount: budgetData.monthly_target
}
};
localStorage.setItem('budgetData', JSON.stringify(localBudgetData));
}
if (categoryData && categoryData.length > 0) {
// 카테고리 예산 로컬 형식으로 변환
const localCategoryBudgets = categoryData.reduce((acc, curr) => {
acc[curr.category] = curr.amount;
return acc;
}, {} as Record<string, number>);
localStorage.setItem('categoryBudgets', JSON.stringify(localCategoryBudgets));
}
console.log('예산 데이터 다운로드 완료');
} catch (error) {
console.error('예산 데이터 다운로드 실패:', error);
}
};
// 전체 데이터 동기화
export const syncAllData = async (userId: string): Promise<void> => { export const syncAllData = async (userId: string): Promise<void> => {
if (!userId || !isSyncEnabled()) return; if (!userId || !isSyncEnabled()) return;