문서 파일 정리

This commit is contained in:
hansoo
2025-03-21 16:08:43 +09:00
parent 86c0035561
commit 2d08a7962b
64 changed files with 8460 additions and 45 deletions

View File

@@ -1,6 +1,6 @@
import { supabase } from '@/lib/supabase';
import { isSyncEnabled } from '../syncSettings';
import { getModifiedBudget, getModifiedCategoryBudgets } from './modifiedBudgetsTracker';
/**
* 서버에서 예산 데이터 다운로드
@@ -107,9 +107,12 @@ async function fetchCategoryBudgetData(userId: string) {
/**
* 예산 데이터 처리 및 로컬 저장
*/
async function processBudgetData(budgetData: any, localBudgetDataStr: string | null) {
async function processBudgetData(budgetData: Record<string, any>, localBudgetDataStr: string | null) {
console.log('서버에서 예산 데이터 수신:', budgetData);
// 로컬에서 수정된 예산 정보 가져오기
const modifiedBudget = getModifiedBudget();
// 서버 예산이 0이고 로컬 예산이 있으면 로컬 데이터 유지
if (budgetData.total_budget === 0 && localBudgetDataStr) {
console.log('서버 예산이 0이고 로컬 예산이 있어 로컬 데이터 유지');
@@ -117,12 +120,51 @@ async function processBudgetData(budgetData: any, localBudgetDataStr: string | n
}
// 기존 로컬 데이터 가져오기
let localBudgetData = localBudgetDataStr ? JSON.parse(localBudgetDataStr) : {
const localBudgetData = localBudgetDataStr ? JSON.parse(localBudgetDataStr) : {
daily: { targetAmount: 0, spentAmount: 0, remainingAmount: 0 },
weekly: { targetAmount: 0, spentAmount: 0, remainingAmount: 0 },
monthly: { targetAmount: 0, spentAmount: 0, remainingAmount: 0 }
};
// 로컬에서 수정된 예산이 있고, 서버 데이터보다 최신이면 로컬 데이터 유지
if (modifiedBudget && (!budgetData.updated_at || new Date(budgetData.updated_at).getTime() < modifiedBudget.timestamp)) {
console.log('로컬에서 수정된 예산이 서버 데이터보다 최신이므로 로컬 데이터 유지');
// 서버 데이터 대신 로컬에서 수정된 예산 사용
const monthlyBudget = modifiedBudget.monthlyAmount;
const dailyBudget = Math.round(monthlyBudget / 30); // 월간 예산 / 30일
const weeklyBudget = Math.round(monthlyBudget / 4.3); // 월간 예산 / 4.3주
const updatedBudgetData = {
daily: {
targetAmount: dailyBudget,
spentAmount: localBudgetData.daily.spentAmount,
remainingAmount: dailyBudget - localBudgetData.daily.spentAmount
},
weekly: {
targetAmount: weeklyBudget,
spentAmount: localBudgetData.weekly.spentAmount,
remainingAmount: weeklyBudget - localBudgetData.weekly.spentAmount
},
monthly: {
targetAmount: monthlyBudget,
spentAmount: localBudgetData.monthly.spentAmount,
remainingAmount: monthlyBudget - localBudgetData.monthly.spentAmount
}
};
console.log('로컬 수정 데이터 기반 예산 계산:', updatedBudgetData);
// 로컬 스토리지에 저장
localStorage.setItem('budgetData', JSON.stringify(updatedBudgetData));
localStorage.setItem('budgetData_backup', JSON.stringify(updatedBudgetData));
console.log('로컬 수정 예산 데이터 유지 완료', updatedBudgetData);
// 이벤트 발생시켜 UI 업데이트
window.dispatchEvent(new Event('budgetDataUpdated'));
return;
}
// 서버 데이터로 업데이트 (지출 금액은 유지)
// 수정: 올바른 예산 계산 방식으로 변경
const monthlyBudget = budgetData.total_budget;
@@ -161,9 +203,12 @@ async function processBudgetData(budgetData: any, localBudgetDataStr: string | n
/**
* 카테고리 예산 데이터 처리 및 로컬 저장
*/
async function processCategoryBudgetData(categoryData: any[], localCategoryBudgetsStr: string | null) {
async function processCategoryBudgetData(categoryData: Record<string, any>[], localCategoryBudgetsStr: string | null) {
console.log(`${categoryData.length}개의 카테고리 예산 수신`);
// 로컬에서 수정된 카테고리 예산 정보 가져오기
const modifiedCategoryBudgets = getModifiedCategoryBudgets();
// 서버 카테고리 예산 합계 계산
const serverTotal = categoryData.reduce((sum, item) => sum + item.amount, 0);
@@ -173,6 +218,21 @@ async function processCategoryBudgetData(categoryData: any[], localCategoryBudge
return;
}
// 로컬에서 수정된 카테고리 예산이 있고, 서버 데이터보다 최신이면 로컬 데이터 유지
if (modifiedCategoryBudgets && categoryData.length > 0) {
// 서버 데이터 중 가장 최근 업데이트 시간 확인
const latestServerUpdate = categoryData.reduce((latest, curr) => {
if (!curr.updated_at) return latest;
const currTime = new Date(curr.updated_at).getTime();
return currTime > latest ? currTime : latest;
}, 0);
if (latestServerUpdate < modifiedCategoryBudgets.timestamp) {
console.log('로컬에서 수정된 카테고리 예산이 서버 데이터보다 최신이므로 로컬 데이터 유지');
return;
}
}
// 카테고리 예산 로컬 형식으로 변환
const localCategoryBudgets = categoryData.reduce((acc, curr) => {
acc[curr.category] = curr.amount;

View File

@@ -0,0 +1,138 @@
/**
* 수정된 예산 데이터를 추적하는 유틸리티
* 로컬 스토리지에 수정된 예산 정보를 저장하고 관리합니다.
*/
const MODIFIED_BUDGETS_KEY = 'modified_budgets';
const MODIFIED_CATEGORY_BUDGETS_KEY = 'modified_category_budgets';
interface ModifiedBudget {
timestamp: number; // 수정 시간 (밀리초)
monthlyAmount: number; // 월간 예산액
}
interface ModifiedCategoryBudgets {
timestamp: number; // 수정 시간 (밀리초)
categories: Record<string, number>; // 카테고리별 예산액
}
/**
* 수정된 예산 정보를 로컬 스토리지에 저장
*/
export const markBudgetAsModified = (monthlyAmount: number): void => {
try {
const modifiedBudget: ModifiedBudget = {
timestamp: Date.now(),
monthlyAmount
};
localStorage.setItem(MODIFIED_BUDGETS_KEY, JSON.stringify(modifiedBudget));
console.log(`[예산 추적] 수정된 예산 정보 저장 완료: ${monthlyAmount}`);
} catch (error) {
console.error('[예산 추적] 수정된 예산 정보 저장 실패:', error);
}
};
/**
* 수정된 카테고리 예산 정보를 로컬 스토리지에 저장
*/
export const markCategoryBudgetsAsModified = (categories: Record<string, number>): void => {
try {
const modifiedCategoryBudgets: ModifiedCategoryBudgets = {
timestamp: Date.now(),
categories
};
localStorage.setItem(MODIFIED_CATEGORY_BUDGETS_KEY, JSON.stringify(modifiedCategoryBudgets));
console.log(`[예산 추적] 수정된 카테고리 예산 정보 저장 완료: ${Object.keys(categories).length}개 카테고리`);
} catch (error) {
console.error('[예산 추적] 수정된 카테고리 예산 정보 저장 실패:', error);
}
};
/**
* 단일 카테고리 예산 정보를 수정된 것으로 표시
*/
export const markSingleCategoryBudgetAsModified = (category: string, amount: number): void => {
try {
// 기존 수정 정보 가져오기
const existing = getModifiedCategoryBudgets();
const categories = existing?.categories || {};
// 새 카테고리 예산 정보 추가
categories[category] = amount;
// 수정된 정보 저장
const modifiedCategoryBudgets: ModifiedCategoryBudgets = {
timestamp: Date.now(),
categories
};
localStorage.setItem(MODIFIED_CATEGORY_BUDGETS_KEY, JSON.stringify(modifiedCategoryBudgets));
console.log(`[예산 추적] 카테고리 '${category}' 예산 정보 저장 완료: ${amount}`);
} catch (error) {
console.error(`[예산 추적] 카테고리 '${category}' 예산 정보 저장 실패:`, error);
}
};
/**
* 수정된 예산 정보 가져오기
*/
export const getModifiedBudget = (): ModifiedBudget | null => {
try {
const data = localStorage.getItem(MODIFIED_BUDGETS_KEY);
if (!data) return null;
return JSON.parse(data) as ModifiedBudget;
} catch (error) {
console.error('[예산 추적] 수정된 예산 정보 조회 실패:', error);
return null;
}
};
/**
* 수정된 카테고리 예산 정보 가져오기
*/
export const getModifiedCategoryBudgets = (): ModifiedCategoryBudgets | null => {
try {
const data = localStorage.getItem(MODIFIED_CATEGORY_BUDGETS_KEY);
if (!data) return null;
return JSON.parse(data) as ModifiedCategoryBudgets;
} catch (error) {
console.error('[예산 추적] 수정된 카테고리 예산 정보 조회 실패:', error);
return null;
}
};
/**
* 예산 수정 정보 초기화
*/
export const clearModifiedBudget = (): void => {
try {
localStorage.removeItem(MODIFIED_BUDGETS_KEY);
console.log('[예산 추적] 수정된 예산 정보 초기화 완료');
} catch (error) {
console.error('[예산 추적] 수정된 예산 정보 초기화 실패:', error);
}
};
/**
* 카테고리 예산 수정 정보 초기화
*/
export const clearModifiedCategoryBudgets = (): void => {
try {
localStorage.removeItem(MODIFIED_CATEGORY_BUDGETS_KEY);
console.log('[예산 추적] 수정된 카테고리 예산 정보 초기화 완료');
} catch (error) {
console.error('[예산 추적] 수정된 카테고리 예산 정보 초기화 실패:', error);
}
};
/**
* 모든 수정 정보 초기화
*/
export const clearAllModifiedBudgets = (): void => {
clearModifiedBudget();
clearModifiedCategoryBudgets();
};

View File

@@ -1,6 +1,9 @@
import { supabase } from '@/lib/supabase';
import { isSyncEnabled } from '../syncSettings';
import {
clearModifiedBudget,
clearModifiedCategoryBudgets
} from './modifiedBudgetsTracker';
/**
* 예산 데이터를 서버에 업로드
@@ -18,6 +21,9 @@ export const uploadBudgets = async (userId: string): Promise<void> => {
if (budgetDataStr) {
const budgetData = JSON.parse(budgetDataStr);
await uploadBudgetData(userId, budgetData);
// 업로드 성공 후 수정 추적 정보 초기화
clearModifiedBudget();
} else {
console.log('업로드할 예산 데이터가 없음');
}
@@ -26,6 +32,9 @@ export const uploadBudgets = async (userId: string): Promise<void> => {
if (categoryBudgetsStr) {
const categoryBudgets = JSON.parse(categoryBudgetsStr);
await uploadCategoryBudgets(userId, categoryBudgets);
// 업로드 성공 후 수정 추적 정보 초기화
clearModifiedCategoryBudgets();
} else {
console.log('업로드할 카테고리 예산이 없음');
}
@@ -40,7 +49,7 @@ export const uploadBudgets = async (userId: string): Promise<void> => {
/**
* 일반 예산 데이터 업로드
*/
async function uploadBudgetData(userId: string, parsedBudgetData: any): Promise<void> {
async function uploadBudgetData(userId: string, parsedBudgetData: Record<string, any>): Promise<void> {
console.log('예산 데이터 업로드:', parsedBudgetData);
// 현재 월/년도 가져오기
@@ -66,6 +75,9 @@ async function uploadBudgetData(userId: string, parsedBudgetData: any): Promise<
console.log('업로드할 월간 예산:', monthlyTarget);
// 현재 타임스탬프
const currentTimestamp = new Date().toISOString();
// 업데이트 또는 삽입 결정
if (existingBudgets && existingBudgets.length > 0) {
// 기존 데이터 업데이트
@@ -73,7 +85,7 @@ async function uploadBudgetData(userId: string, parsedBudgetData: any): Promise<
.from('budgets')
.update({
total_budget: monthlyTarget,
updated_at: new Date().toISOString()
updated_at: currentTimestamp
})
.eq('id', existingBudgets[0].id);
@@ -91,7 +103,9 @@ async function uploadBudgetData(userId: string, parsedBudgetData: any): Promise<
user_id: userId,
month: currentMonth,
year: currentYear,
total_budget: monthlyTarget
total_budget: monthlyTarget,
created_at: currentTimestamp,
updated_at: currentTimestamp
});
if (error) {
@@ -120,13 +134,18 @@ async function uploadCategoryBudgets(userId: string, parsedCategoryBudgets: Reco
// 오류가 나도 계속 진행 (중요 데이터가 아니기 때문)
}
// 현재 타임스탬프
const currentTimestamp = new Date().toISOString();
// 카테고리별 예산 데이터 변환 및 삽입
const categoryEntries = Object.entries(parsedCategoryBudgets)
.filter(([_, amount]) => amount > 0) // 금액이 0보다 큰 것만 저장
.map(([category, amount]) => ({
user_id: userId,
category,
amount
amount,
created_at: currentTimestamp,
updated_at: currentTimestamp
}));
if (categoryEntries.length > 0) {