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:
@@ -1,6 +1,7 @@
|
||||
'use server';
|
||||
|
||||
import { executeServerAction } from '@/lib/api/execute-server-action';
|
||||
import { buildApiUrl } from '@/lib/api/query-params';
|
||||
import type { PaginatedApiResponse } from '@/lib/api/types';
|
||||
|
||||
// ============================================================================
|
||||
@@ -777,8 +778,6 @@ function transformQuoteItemForSelect(apiItem: ApiQuoteItem): QuotationItem {
|
||||
// API 함수
|
||||
// ============================================================================
|
||||
|
||||
const API_URL = process.env.NEXT_PUBLIC_API_URL;
|
||||
|
||||
/**
|
||||
* 수주 목록 조회
|
||||
*/
|
||||
@@ -797,21 +796,18 @@ export async function getOrders(params?: {
|
||||
error?: string;
|
||||
__authError?: boolean;
|
||||
}> {
|
||||
const searchParams = new URLSearchParams();
|
||||
if (params?.page) searchParams.set('page', String(params.page));
|
||||
if (params?.size) searchParams.set('size', String(params.size));
|
||||
if (params?.q) searchParams.set('q', params.q);
|
||||
if (params?.status) {
|
||||
const apiStatus = FRONTEND_TO_API_STATUS[params.status as OrderStatus];
|
||||
if (apiStatus) searchParams.set('status', apiStatus);
|
||||
}
|
||||
if (params?.order_type) searchParams.set('order_type', params.order_type);
|
||||
if (params?.client_id) searchParams.set('client_id', String(params.client_id));
|
||||
if (params?.date_from) searchParams.set('date_from', params.date_from);
|
||||
if (params?.date_to) searchParams.set('date_to', params.date_to);
|
||||
|
||||
const apiStatus = params?.status ? FRONTEND_TO_API_STATUS[params.status as OrderStatus] : undefined;
|
||||
const result = await executeServerAction<PaginatedApiResponse<ApiOrder>>({
|
||||
url: `${API_URL}/api/v1/orders?${searchParams.toString()}`,
|
||||
url: buildApiUrl('/api/v1/orders', {
|
||||
page: params?.page,
|
||||
size: params?.size,
|
||||
q: params?.q,
|
||||
status: apiStatus,
|
||||
order_type: params?.order_type,
|
||||
client_id: params?.client_id,
|
||||
date_from: params?.date_from,
|
||||
date_to: params?.date_to,
|
||||
}),
|
||||
errorMessage: '목록 조회에 실패했습니다.',
|
||||
});
|
||||
if (result.__authError) return { success: false, __authError: true };
|
||||
@@ -837,7 +833,7 @@ export async function getOrderById(id: string): Promise<{
|
||||
__authError?: boolean;
|
||||
}> {
|
||||
const result = await executeServerAction({
|
||||
url: `${API_URL}/api/v1/orders/${id}`,
|
||||
url: buildApiUrl(`/api/v1/orders/${id}`),
|
||||
transform: (data: ApiOrder) => transformApiToFrontend(data),
|
||||
errorMessage: '조회에 실패했습니다.',
|
||||
});
|
||||
@@ -856,7 +852,7 @@ export async function createOrder(data: OrderFormData | Record<string, unknown>)
|
||||
}> {
|
||||
const apiData = transformFrontendToApi(data);
|
||||
const result = await executeServerAction({
|
||||
url: `${API_URL}/api/v1/orders`,
|
||||
url: buildApiUrl('/api/v1/orders'),
|
||||
method: 'POST',
|
||||
body: apiData,
|
||||
transform: (d: ApiOrder) => transformApiToFrontend(d),
|
||||
@@ -877,7 +873,7 @@ export async function updateOrder(id: string, data: OrderFormData | Record<strin
|
||||
}> {
|
||||
const apiData = transformFrontendToApi(data);
|
||||
const result = await executeServerAction({
|
||||
url: `${API_URL}/api/v1/orders/${id}`,
|
||||
url: buildApiUrl(`/api/v1/orders/${id}`),
|
||||
method: 'PUT',
|
||||
body: apiData,
|
||||
transform: (d: ApiOrder) => transformApiToFrontend(d),
|
||||
@@ -896,7 +892,7 @@ export async function deleteOrder(id: string): Promise<{
|
||||
__authError?: boolean;
|
||||
}> {
|
||||
const result = await executeServerAction({
|
||||
url: `${API_URL}/api/v1/orders/${id}`,
|
||||
url: buildApiUrl(`/api/v1/orders/${id}`),
|
||||
method: 'DELETE',
|
||||
errorMessage: '삭제에 실패했습니다.',
|
||||
});
|
||||
@@ -918,7 +914,7 @@ export async function updateOrderStatus(id: string, status: OrderStatus): Promis
|
||||
return { success: false, error: '유효하지 않은 상태입니다.' };
|
||||
}
|
||||
const result = await executeServerAction({
|
||||
url: `${API_URL}/api/v1/orders/${id}/status`,
|
||||
url: buildApiUrl(`/api/v1/orders/${id}/status`),
|
||||
method: 'PATCH',
|
||||
body: { status: apiStatus },
|
||||
transform: (d: ApiOrder) => transformApiToFrontend(d),
|
||||
@@ -938,7 +934,7 @@ export async function getOrderStats(): Promise<{
|
||||
__authError?: boolean;
|
||||
}> {
|
||||
const result = await executeServerAction<ApiOrderStats>({
|
||||
url: `${API_URL}/api/v1/orders/stats`,
|
||||
url: buildApiUrl('/api/v1/orders/stats'),
|
||||
errorMessage: '통계 조회에 실패했습니다.',
|
||||
});
|
||||
if (result.__authError) return { success: false, __authError: true };
|
||||
@@ -1009,7 +1005,7 @@ export async function createOrderFromQuote(
|
||||
if (data?.memo) apiData.memo = data.memo;
|
||||
|
||||
const result = await executeServerAction({
|
||||
url: `${API_URL}/api/v1/orders/from-quote/${quoteId}`,
|
||||
url: buildApiUrl(`/api/v1/orders/from-quote/${quoteId}`),
|
||||
method: 'POST',
|
||||
body: apiData,
|
||||
transform: (d: ApiOrder) => transformApiToFrontend(d),
|
||||
@@ -1049,7 +1045,7 @@ export async function createProductionOrder(
|
||||
if (data?.memo) apiData.memo = data.memo;
|
||||
|
||||
const result = await executeServerAction<ApiProductionOrderResponse>({
|
||||
url: `${API_URL}/api/v1/orders/${orderId}/production-order`,
|
||||
url: buildApiUrl(`/api/v1/orders/${orderId}/production-order`),
|
||||
method: 'POST',
|
||||
body: apiData,
|
||||
errorMessage: '생산지시 생성에 실패했습니다.',
|
||||
@@ -1087,7 +1083,7 @@ export async function revertProductionOrder(orderId: string): Promise<{
|
||||
previous_status: string;
|
||||
}
|
||||
const result = await executeServerAction<RevertResponse>({
|
||||
url: `${API_URL}/api/v1/orders/${orderId}/revert-production`,
|
||||
url: buildApiUrl(`/api/v1/orders/${orderId}/revert-production`),
|
||||
method: 'POST',
|
||||
errorMessage: '생산지시 되돌리기에 실패했습니다.',
|
||||
});
|
||||
@@ -1118,7 +1114,7 @@ export async function revertOrderConfirmation(orderId: string): Promise<{
|
||||
}> {
|
||||
interface RevertConfirmResponse { order: ApiOrder; previous_status: string }
|
||||
const result = await executeServerAction<RevertConfirmResponse>({
|
||||
url: `${API_URL}/api/v1/orders/${orderId}/revert-confirmation`,
|
||||
url: buildApiUrl(`/api/v1/orders/${orderId}/revert-confirmation`),
|
||||
method: 'POST',
|
||||
errorMessage: '수주확정 되돌리기에 실패했습니다.',
|
||||
});
|
||||
@@ -1144,7 +1140,7 @@ export async function getQuoteByIdForSelect(id: string): Promise<{
|
||||
__authError?: boolean;
|
||||
}> {
|
||||
const result = await executeServerAction({
|
||||
url: `${API_URL}/api/v1/quotes/${id}?with_items=true`,
|
||||
url: buildApiUrl(`/api/v1/quotes/${id}`, { with_items: true }),
|
||||
transform: (data: ApiQuoteForSelect) => transformQuoteForSelect(data),
|
||||
errorMessage: '견적 조회에 실패했습니다.',
|
||||
});
|
||||
@@ -1166,16 +1162,15 @@ export async function getQuotesForSelect(params?: {
|
||||
error?: string;
|
||||
__authError?: boolean;
|
||||
}> {
|
||||
const searchParams = new URLSearchParams();
|
||||
searchParams.set('status', 'finalized');
|
||||
searchParams.set('with_items', 'true');
|
||||
searchParams.set('for_order', 'true');
|
||||
if (params?.q) searchParams.set('q', params.q);
|
||||
if (params?.page) searchParams.set('page', String(params.page));
|
||||
if (params?.size) searchParams.set('size', String(params.size || 50));
|
||||
|
||||
const result = await executeServerAction<PaginatedApiResponse<ApiQuoteForSelect>>({
|
||||
url: `${API_URL}/api/v1/quotes?${searchParams.toString()}`,
|
||||
url: buildApiUrl('/api/v1/quotes', {
|
||||
status: 'finalized',
|
||||
with_items: 'true',
|
||||
for_order: 'true',
|
||||
q: params?.q,
|
||||
page: params?.page,
|
||||
size: params?.size || 50,
|
||||
}),
|
||||
errorMessage: '견적 목록 조회에 실패했습니다.',
|
||||
});
|
||||
if (result.__authError) return { success: false, __authError: true };
|
||||
|
||||
Reference in New Issue
Block a user