refactor(WEB): 전체 actions.ts에 공통 API 유틸 적용

- buildApiUrl / executePaginatedAction 패턴으로 전환 (40+ actions 파일)
- 직접 URLSearchParams 조립 → buildApiUrl 유틸 사용
- 수동 페이지네이션 메타 변환 → executePaginatedAction 자동 처리
- HandoverReportDocumentModal, OrderDocumentModal 개선
- 급여관리 SalaryManagement 코드 개선
- CLAUDE.md Server Action 공통 유틸 규칙 정리

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
유병철
2026-02-12 20:59:59 +09:00
parent 31be9d4a25
commit cbb38d48b9
51 changed files with 1050 additions and 1405 deletions

View File

@@ -2,11 +2,10 @@
import { executeServerAction, type ActionResult } from '@/lib/api/execute-server-action';
import { buildApiUrl } from '@/lib/api/query-params';
import { isNextRedirectError } from '@/lib/utils/redirect-error';
import type { Board, BoardApiData, BoardFormData } from './types';
const API_URL = process.env.NEXT_PUBLIC_API_URL;
// ===== 변환 =====
function transformApiToFrontend(apiData: BoardApiData): Board {
const extraSettings = apiData.extra_settings || {};
@@ -50,12 +49,11 @@ function transformFrontendToApi(data: BoardFormData & { boardCode?: string; desc
export async function getBoards(filters?: {
board_type?: string; search?: string;
}): Promise<ActionResult<Board[]>> {
const params = new URLSearchParams();
if (filters?.board_type) params.append('board_type', filters.board_type);
if (filters?.search) params.append('search', filters.search);
const queryString = params.toString();
return executeServerAction({
url: `${API_URL}/api/v1/boards/tenant${queryString ? `?${queryString}` : ''}`,
url: buildApiUrl('/api/v1/boards/tenant', {
board_type: filters?.board_type,
search: filters?.search,
}),
transform: (data: BoardApiData[]) => (Array.isArray(data) ? data : []).map(transformApiToFrontend),
errorMessage: '게시판 목록 조회에 실패했습니다.',
});
@@ -65,12 +63,11 @@ export async function getBoards(filters?: {
export async function getTenantBoards(filters?: {
board_type?: string; search?: string;
}): Promise<ActionResult<Board[]>> {
const params = new URLSearchParams();
if (filters?.board_type) params.append('board_type', filters.board_type);
if (filters?.search) params.append('search', filters.search);
const queryString = params.toString();
return executeServerAction({
url: `${API_URL}/api/v1/boards/tenant${queryString ? `?${queryString}` : ''}`,
url: buildApiUrl('/api/v1/boards/tenant', {
board_type: filters?.board_type,
search: filters?.search,
}),
transform: (data: BoardApiData[]) => data.map(transformApiToFrontend),
errorMessage: '테넌트 게시판 목록 조회에 실패했습니다.',
});
@@ -79,7 +76,7 @@ export async function getTenantBoards(filters?: {
// ===== 게시판 상세 조회 (코드 기반) =====
export async function getBoardByCode(code: string): Promise<ActionResult<Board>> {
return executeServerAction({
url: `${API_URL}/api/v1/boards/${code}`,
url: buildApiUrl(`/api/v1/boards/${code}`),
transform: (data: BoardApiData) => transformApiToFrontend(data),
errorMessage: '게시판을 찾을 수 없습니다.',
});
@@ -88,7 +85,7 @@ export async function getBoardByCode(code: string): Promise<ActionResult<Board>>
// ===== 게시판 상세 조회 (ID 기반) =====
export async function getBoardById(id: string): Promise<ActionResult<Board>> {
return executeServerAction({
url: `${API_URL}/api/v1/boards/${id}`,
url: buildApiUrl(`/api/v1/boards/${id}`),
transform: (data: BoardApiData) => transformApiToFrontend(data),
errorMessage: '게시판을 찾을 수 없습니다.',
});
@@ -99,7 +96,7 @@ export async function createBoard(
data: BoardFormData & { boardCode: string; description?: string }
): Promise<ActionResult<Board>> {
return executeServerAction({
url: `${API_URL}/api/v1/boards`,
url: buildApiUrl('/api/v1/boards'),
method: 'POST',
body: transformFrontendToApi(data),
transform: (d: BoardApiData) => transformApiToFrontend(d),
@@ -113,7 +110,7 @@ export async function updateBoard(
data: BoardFormData & { boardCode?: string; description?: string }
): Promise<ActionResult<Board>> {
return executeServerAction({
url: `${API_URL}/api/v1/boards/${id}`,
url: buildApiUrl(`/api/v1/boards/${id}`),
method: 'PUT',
body: transformFrontendToApi(data, true),
transform: (d: BoardApiData) => transformApiToFrontend(d),
@@ -124,7 +121,7 @@ export async function updateBoard(
// ===== 게시판 삭제 =====
export async function deleteBoard(id: string): Promise<ActionResult> {
return executeServerAction({
url: `${API_URL}/api/v1/boards/${id}`,
url: buildApiUrl(`/api/v1/boards/${id}`),
method: 'DELETE',
errorMessage: '게시판 삭제에 실패했습니다.',
});
@@ -143,4 +140,4 @@ export async function deleteBoardsBulk(ids: string[]): Promise<ActionResult> {
if (isNextRedirectError(error)) throw error;
return { success: false, error: '서버 오류가 발생했습니다.' };
}
}
}