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

@@ -13,7 +13,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 { Board, BoardApiData, BoardFormData } from './types';
@@ -135,7 +135,7 @@ export async function getBoards(filters?: {
const boards = result.data.map(transformApiToFrontend);
return { success: true, data: boards };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[BoardActions] getBoards error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}
@@ -184,7 +184,7 @@ export async function getTenantBoards(filters?: {
const boards = result.data.map(transformApiToFrontend);
return { success: true, data: boards };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[BoardActions] getTenantBoards error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}
@@ -224,7 +224,7 @@ export async function getBoardByCode(code: string): Promise<{ success: boolean;
return { success: true, data: transformApiToFrontend(result.data) };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[BoardActions] getBoardByCode error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}
@@ -264,7 +264,7 @@ export async function getBoardById(id: string): Promise<{ success: boolean; data
return { success: true, data: transformApiToFrontend(result.data) };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[BoardActions] getBoardById error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}
@@ -313,7 +313,7 @@ export async function createBoard(
data: transformApiToFrontend(result.data),
};
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[BoardActions] createBoard error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}
@@ -363,7 +363,7 @@ export async function updateBoard(
data: transformApiToFrontend(result.data),
};
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[BoardActions] updateBoard error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}
@@ -405,7 +405,7 @@ export async function deleteBoard(id: string): Promise<{ success: boolean; error
return { success: true };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[BoardActions] deleteBoard error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}
@@ -433,7 +433,7 @@ export async function deleteBoardsBulk(ids: string[]): Promise<{ success: boolea
return { success: true };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[BoardActions] deleteBoardsBulk error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}

View File

@@ -6,7 +6,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 {
PostApiData,
@@ -62,7 +62,7 @@ export async function getDynamicBoardPosts(
return { success: true, data: result.data };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[DynamicBoardActions] getDynamicBoardPosts error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}
@@ -99,7 +99,7 @@ export async function getDynamicBoardPost(
return { success: true, data: result.data };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[DynamicBoardActions] getDynamicBoardPost error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}
@@ -142,7 +142,7 @@ export async function createDynamicBoardPost(
return { success: true, data: result.data };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[DynamicBoardActions] createDynamicBoardPost error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}
@@ -186,7 +186,7 @@ export async function updateDynamicBoardPost(
return { success: true, data: result.data };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[DynamicBoardActions] updateDynamicBoardPost error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}
@@ -222,7 +222,7 @@ export async function deleteDynamicBoardPost(
return { success: true };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[DynamicBoardActions] deleteDynamicBoardPost error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}
@@ -261,7 +261,7 @@ export async function getDynamicBoardComments(
return { success: true, data: result.data };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[DynamicBoardActions] getDynamicBoardComments error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}
@@ -299,7 +299,7 @@ export async function createDynamicBoardComment(
return { success: true, data: result.data };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[DynamicBoardActions] createDynamicBoardComment error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}
@@ -338,7 +338,7 @@ export async function updateDynamicBoardComment(
return { success: true, data: result.data };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[DynamicBoardActions] updateDynamicBoardComment error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}
@@ -375,7 +375,7 @@ export async function deleteDynamicBoardComment(
return { success: true };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[DynamicBoardActions] deleteDynamicBoardComment error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}

View File

@@ -13,7 +13,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 {
PostApiData,
@@ -103,7 +103,7 @@ export async function getPosts(
return { success: true, data: result.data, posts };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[BoardActions] getPosts error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}
@@ -156,7 +156,7 @@ export async function getMyPosts(
return { success: true, data: result.data, posts };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[BoardActions] getMyPosts error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}
@@ -193,7 +193,7 @@ export async function getPost(
return { success: true, data: transformApiToPost(result.data) };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[BoardActions] getPost error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}
@@ -236,7 +236,7 @@ export async function createPost(
return { success: true, data: transformApiToPost(result.data) };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[BoardActions] createPost error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}
@@ -280,7 +280,7 @@ export async function updatePost(
return { success: true, data: transformApiToPost(result.data) };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[BoardActions] updatePost error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}
@@ -316,7 +316,7 @@ export async function deletePost(
return { success: true };
} catch (error) {
if (isRedirectError(error)) throw error;
if (isNextRedirectError(error)) throw error;
console.error('[BoardActions] deletePost error:', error);
return { success: false, error: '서버 오류가 발생했습니다.' };
}