chore(WEB): actions.ts 에러 핸들링 및 CEO 대시보드 개선

- 전체 모듈 actions.ts redirect 에러 핸들링 추가
- CEODashboard DetailModal 추가
- MonthlyExpenseSection 개선
- fetch-wrapper redirect 에러 처리
- redirect-error 유틸 추가

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
byeongcheolryu
2026-01-08 18:41:15 +09:00
parent 9885085259
commit 0d539628f3
61 changed files with 1226 additions and 359 deletions

View File

@@ -14,7 +14,7 @@
'use server';
import { isRedirectError } from 'next/dist/client/components/redirect';
import { isNextRedirectError } from '@/lib/utils/redirect-error';
import { serverFetch } from '@/lib/api/fetch-wrapper';
import type {
ReceivingItem,
@@ -242,7 +242,7 @@ export async function getReceivings(params?: {
},
};
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[ReceivingActions] getReceivings error:', error);
return {
success: false,
@@ -282,7 +282,7 @@ export async function getReceivingStats(): Promise<{
return { success: true, data: transformApiToStats(result.data) };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[ReceivingActions] getReceivingStats error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}
@@ -317,7 +317,7 @@ export async function getReceivingById(id: string): Promise<{
return { success: true, data: transformApiToDetail(result.data) };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[ReceivingActions] getReceivingById error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}
@@ -351,7 +351,7 @@ export async function createReceiving(
return { success: true, data: transformApiToDetail(result.data) };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[ReceivingActions] createReceiving error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}
@@ -386,7 +386,7 @@ export async function updateReceiving(
return { success: true, data: transformApiToDetail(result.data) };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[ReceivingActions] updateReceiving error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}
@@ -418,7 +418,7 @@ export async function deleteReceiving(
return { success: true };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[ReceivingActions] deleteReceiving error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}
@@ -453,7 +453,7 @@ export async function processReceiving(
return { success: true, data: transformApiToDetail(result.data) };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[ReceivingActions] processReceiving error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}

View File

@@ -11,7 +11,7 @@
'use server';
import { isRedirectError } from 'next/dist/client/components/redirect';
import { isNextRedirectError } from '@/lib/utils/redirect-error';
import { serverFetch } from '@/lib/api/fetch-wrapper';
import type {
StockItem,
@@ -259,7 +259,7 @@ export async function getStocks(params?: {
},
};
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[StockActions] getStocks error:', error);
return {
success: false,
@@ -299,7 +299,7 @@ export async function getStockStats(): Promise<{
return { success: true, data: transformApiToStats(result.data) };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[StockActions] getStockStats error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}
@@ -334,7 +334,7 @@ export async function getStockStatsByType(): Promise<{
return { success: true, data: result.data };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[StockActions] getStockStatsByType error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}
@@ -369,7 +369,7 @@ export async function getStockById(id: string): Promise<{
return { success: true, data: transformApiToDetail(result.data) };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[StockActions] getStockById error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}