refactor: [작업자화면] WorkerScreen/actions.ts buildApiUrl 마이그레이션
- ${API_URL} 직접 조립 22개 함수 → buildApiUrl() 전환
- const API_URL 선언 제거
- sam-docs 코딩 컨벤션 금지 패턴 예시 보강
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -48,12 +48,18 @@ export default function Page() {
|
||||
```tsx
|
||||
// ✅ 필수
|
||||
import { buildApiUrl } from '@/lib/api/query-params';
|
||||
const url = buildApiUrl('/api/v1/items', { search, page });
|
||||
buildApiUrl('/api/v1/items', { search, page }); // 쿼리 파라미터
|
||||
buildApiUrl(`/api/v1/items/${id}`); // 동적 경로
|
||||
buildApiUrl(`/api/v1/items/${id}`, { with_details: true }); // 동적 경로 + 파라미터
|
||||
|
||||
// ❌ 금지
|
||||
// ❌ 금지 패턴 1: ${API_URL} 직접 조립
|
||||
const API_URL = process.env.NEXT_PUBLIC_API_URL;
|
||||
url: `${API_URL}/api/v1/items/${id}`,
|
||||
|
||||
// ❌ 금지 패턴 2: URLSearchParams 직접 사용
|
||||
const params = new URLSearchParams();
|
||||
params.set('search', value);
|
||||
const url = `${API_URL}/api/v1/items?${params.toString()}`;
|
||||
url: `${API_URL}/api/v1/items?${params.toString()}`,
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -214,8 +214,6 @@ function transformToWorkerScreenFormat(api: WorkOrderApiItem): WorkOrder {
|
||||
};
|
||||
}
|
||||
|
||||
const API_URL = process.env.NEXT_PUBLIC_API_URL;
|
||||
|
||||
// ===== 내 작업 목록 조회 =====
|
||||
export async function getMyWorkOrders(): Promise<{
|
||||
success: boolean;
|
||||
@@ -224,7 +222,7 @@ export async function getMyWorkOrders(): Promise<{
|
||||
}> {
|
||||
interface PaginatedWO { data: WorkOrderApiItem[] }
|
||||
const result = await executeServerAction<PaginatedWO>({
|
||||
url: `${API_URL}/api/v1/work-orders?per_page=100&worker_screen=1`,
|
||||
url: buildApiUrl('/api/v1/work-orders', { per_page: 100, worker_screen: 1 }),
|
||||
errorMessage: '작업 목록 조회에 실패했습니다.',
|
||||
});
|
||||
if (!result.success || !result.data) return { success: false, data: [], error: result.error };
|
||||
@@ -241,7 +239,7 @@ export async function completeWorkOrder(
|
||||
materials?: { materialId: number; quantity: number; lotNo?: string }[]
|
||||
): Promise<{ success: boolean; lotNo?: string; error?: string }> {
|
||||
const result = await executeServerAction({
|
||||
url: `${API_URL}/api/v1/work-orders/${id}/status`,
|
||||
url: buildApiUrl(`/api/v1/work-orders/${id}/status`),
|
||||
method: 'PATCH',
|
||||
body: { status: 'completed', materials },
|
||||
errorMessage: '작업 완료 처리에 실패했습니다.',
|
||||
@@ -258,7 +256,7 @@ export async function updateWorkOrderInfo(
|
||||
data: { scheduled_date?: string; team_id?: number | null; assignee_id?: number | null }
|
||||
): Promise<{ success: boolean; error?: string }> {
|
||||
const result = await executeServerAction({
|
||||
url: `${API_URL}/api/v1/work-orders/${id}`,
|
||||
url: buildApiUrl(`/api/v1/work-orders/${id}`),
|
||||
method: 'PUT',
|
||||
body: data,
|
||||
errorMessage: '작업정보 저장에 실패했습니다.',
|
||||
@@ -300,7 +298,7 @@ export async function getMaterialsForWorkOrder(
|
||||
work_order_item_id?: number; lot_prefix?: string; part_type?: string; category?: string;
|
||||
}
|
||||
const result = await executeServerAction<MaterialApiItem[]>({
|
||||
url: `${API_URL}/api/v1/work-orders/${workOrderId}/materials`,
|
||||
url: buildApiUrl(`/api/v1/work-orders/${workOrderId}/materials`),
|
||||
errorMessage: '자재 목록 조회에 실패했습니다.',
|
||||
});
|
||||
if (!result.success || !result.data) return { success: false, data: [], error: result.error };
|
||||
@@ -323,7 +321,7 @@ export async function registerMaterialInput(
|
||||
inputs: { stock_lot_id: number; qty: number; work_order_item_id?: number }[]
|
||||
): Promise<{ success: boolean; error?: string }> {
|
||||
const result = await executeServerAction({
|
||||
url: `${API_URL}/api/v1/work-orders/${workOrderId}/material-inputs`,
|
||||
url: buildApiUrl(`/api/v1/work-orders/${workOrderId}/material-inputs`),
|
||||
method: 'POST',
|
||||
body: { inputs },
|
||||
errorMessage: '자재 투입 등록에 실패했습니다.',
|
||||
@@ -360,7 +358,7 @@ export async function getMaterialsForItem(
|
||||
bom_group_key?: string;
|
||||
}
|
||||
const result = await executeServerAction<MaterialItemApiItem[]>({
|
||||
url: `${API_URL}/api/v1/work-orders/${workOrderId}/items/${itemId}/materials`,
|
||||
url: buildApiUrl(`/api/v1/work-orders/${workOrderId}/items/${itemId}/materials`),
|
||||
errorMessage: '개소별 자재 목록 조회에 실패했습니다.',
|
||||
});
|
||||
if (!result.success || !result.data) return { success: false, data: [], error: result.error };
|
||||
@@ -390,7 +388,7 @@ export async function registerMaterialInputForItem(
|
||||
replace = false
|
||||
): Promise<{ success: boolean; error?: string }> {
|
||||
const result = await executeServerAction({
|
||||
url: `${API_URL}/api/v1/work-orders/${workOrderId}/items/${itemId}/material-inputs`,
|
||||
url: buildApiUrl(`/api/v1/work-orders/${workOrderId}/items/${itemId}/material-inputs`),
|
||||
method: 'POST',
|
||||
body: { inputs, replace },
|
||||
errorMessage: '개소별 자재 투입 등록에 실패했습니다.',
|
||||
@@ -428,7 +426,7 @@ export async function getMaterialInputsForItem(
|
||||
input_by: number | null; input_by_name: string | null; input_at: string | null;
|
||||
}
|
||||
const result = await executeServerAction<HistoryApiItem[]>({
|
||||
url: `${API_URL}/api/v1/work-orders/${workOrderId}/items/${itemId}/material-inputs`,
|
||||
url: buildApiUrl(`/api/v1/work-orders/${workOrderId}/items/${itemId}/material-inputs`),
|
||||
errorMessage: '개소별 투입 이력 조회에 실패했습니다.',
|
||||
});
|
||||
if (!result.success || !result.data) return { success: false, data: [], error: result.error };
|
||||
@@ -449,7 +447,7 @@ export async function deleteMaterialInput(
|
||||
inputId: number
|
||||
): Promise<{ success: boolean; error?: string }> {
|
||||
const result = await executeServerAction({
|
||||
url: `${API_URL}/api/v1/work-orders/${workOrderId}/material-inputs/${inputId}`,
|
||||
url: buildApiUrl(`/api/v1/work-orders/${workOrderId}/material-inputs/${inputId}`),
|
||||
method: 'DELETE',
|
||||
errorMessage: '자재 투입 삭제에 실패했습니다.',
|
||||
});
|
||||
@@ -463,7 +461,7 @@ export async function updateMaterialInput(
|
||||
qty: number
|
||||
): Promise<{ success: boolean; data?: { id: number; qty: number; changed: boolean }; error?: string }> {
|
||||
const result = await executeServerAction<{ id: number; qty: number; changed: boolean }>({
|
||||
url: `${API_URL}/api/v1/work-orders/${workOrderId}/material-inputs/${inputId}`,
|
||||
url: buildApiUrl(`/api/v1/work-orders/${workOrderId}/material-inputs/${inputId}`),
|
||||
method: 'PATCH',
|
||||
body: { qty },
|
||||
errorMessage: '자재 투입 수정에 실패했습니다.',
|
||||
@@ -481,7 +479,7 @@ export async function reportIssue(
|
||||
}
|
||||
): Promise<{ success: boolean; error?: string }> {
|
||||
const result = await executeServerAction({
|
||||
url: `${API_URL}/api/v1/work-orders/${workOrderId}/issues`,
|
||||
url: buildApiUrl(`/api/v1/work-orders/${workOrderId}/issues`),
|
||||
method: 'POST',
|
||||
body: data,
|
||||
errorMessage: '이슈 보고에 실패했습니다.',
|
||||
@@ -523,7 +521,7 @@ export async function getProcessSteps(
|
||||
items?: { id: number; item_no: string; location: string; is_priority: boolean; spec: string; material: string; lot: string }[];
|
||||
}
|
||||
const result = await executeServerAction<StepApiItem[]>({
|
||||
url: `${API_URL}/api/v1/work-orders/${workOrderId}/process-steps`,
|
||||
url: buildApiUrl(`/api/v1/work-orders/${workOrderId}/process-steps`),
|
||||
errorMessage: '공정 단계 조회에 실패했습니다.',
|
||||
});
|
||||
if (!result.success || !result.data) return { success: false, data: [], error: result.error };
|
||||
@@ -546,7 +544,7 @@ export async function requestInspection(
|
||||
stepId: string
|
||||
): Promise<{ success: boolean; error?: string }> {
|
||||
const result = await executeServerAction({
|
||||
url: `${API_URL}/api/v1/work-orders/${workOrderId}/process-steps/${stepId}/inspection-request`,
|
||||
url: buildApiUrl(`/api/v1/work-orders/${workOrderId}/process-steps/${stepId}/inspection-request`),
|
||||
method: 'POST',
|
||||
body: {},
|
||||
errorMessage: '검사 요청에 실패했습니다.',
|
||||
@@ -580,7 +578,7 @@ export async function getStepProgress(
|
||||
error?: string;
|
||||
}> {
|
||||
const result = await executeServerAction<StepProgressItem[]>({
|
||||
url: `${API_URL}/api/v1/work-orders/${workOrderId}/step-progress`,
|
||||
url: buildApiUrl(`/api/v1/work-orders/${workOrderId}/step-progress`),
|
||||
errorMessage: '단계 진행 조회에 실패했습니다.',
|
||||
});
|
||||
if (!result.success || !result.data) return { success: false, data: [], error: result.error };
|
||||
@@ -593,7 +591,7 @@ export async function toggleStepProgress(
|
||||
progressId: number
|
||||
): Promise<{ success: boolean; data?: StepProgressItem; error?: string }> {
|
||||
const result = await executeServerAction<StepProgressItem>({
|
||||
url: `${API_URL}/api/v1/work-orders/${workOrderId}/step-progress/${progressId}/toggle`,
|
||||
url: buildApiUrl(`/api/v1/work-orders/${workOrderId}/step-progress/${progressId}/toggle`),
|
||||
method: 'PATCH',
|
||||
errorMessage: '단계 토글에 실패했습니다.',
|
||||
});
|
||||
@@ -610,7 +608,7 @@ export async function getWorkOrderDetail(
|
||||
}> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const result = await executeServerAction<any>({
|
||||
url: `${API_URL}/api/v1/work-orders/${workOrderId}`,
|
||||
url: buildApiUrl(`/api/v1/work-orders/${workOrderId}`),
|
||||
errorMessage: '작업지시 상세 조회에 실패했습니다.',
|
||||
});
|
||||
if (!result.success || !result.data) return { success: false, data: [], error: result.error };
|
||||
@@ -723,7 +721,7 @@ export async function saveItemInspection(
|
||||
inspectionData: Record<string, unknown>
|
||||
): Promise<{ success: boolean; data?: Record<string, unknown>; error?: string }> {
|
||||
const result = await executeServerAction<Record<string, unknown>>({
|
||||
url: `${API_URL}/api/v1/work-orders/${workOrderId}/items/${itemId}/inspection`,
|
||||
url: buildApiUrl(`/api/v1/work-orders/${workOrderId}/items/${itemId}/inspection`),
|
||||
method: 'POST',
|
||||
body: { process_type: processType, inspection_data: inspectionData },
|
||||
errorMessage: '검사 데이터 저장에 실패했습니다.',
|
||||
@@ -750,7 +748,7 @@ export async function getWorkOrderInspectionData(
|
||||
error?: string;
|
||||
}> {
|
||||
const result = await executeServerAction<{ work_order_id: number; items: InspectionDataItem[]; total: number }>({
|
||||
url: `${API_URL}/api/v1/work-orders/${workOrderId}/inspection-data`,
|
||||
url: buildApiUrl(`/api/v1/work-orders/${workOrderId}/inspection-data`),
|
||||
errorMessage: '검사 데이터 조회에 실패했습니다.',
|
||||
});
|
||||
return { success: result.success, data: result.data, error: result.error };
|
||||
@@ -772,7 +770,7 @@ export async function saveWorkLog(
|
||||
error?: string;
|
||||
}> {
|
||||
const result = await executeServerAction<{ document_id: number; document_no: string; status: string }>({
|
||||
url: `${API_URL}/api/v1/work-orders/${workOrderId}/work-log`,
|
||||
url: buildApiUrl(`/api/v1/work-orders/${workOrderId}/work-log`),
|
||||
method: 'POST',
|
||||
body: data,
|
||||
errorMessage: '작업일지 저장에 실패했습니다.',
|
||||
@@ -801,7 +799,7 @@ export async function getWorkLog(
|
||||
work_stats: Record<string, unknown>;
|
||||
bending_images: Record<string, string>;
|
||||
}>({
|
||||
url: `${API_URL}/api/v1/work-orders/${workOrderId}/work-log`,
|
||||
url: buildApiUrl(`/api/v1/work-orders/${workOrderId}/work-log`),
|
||||
errorMessage: '작업일지 조회에 실패했습니다.',
|
||||
});
|
||||
return { success: result.success, data: result.data, error: result.error };
|
||||
@@ -818,7 +816,7 @@ export async function getInspectionTemplate(
|
||||
error?: string;
|
||||
}> {
|
||||
const result = await executeServerAction<InspectionTemplateData>({
|
||||
url: `${API_URL}/api/v1/work-orders/${workOrderId}/inspection-template`,
|
||||
url: buildApiUrl(`/api/v1/work-orders/${workOrderId}/inspection-template`),
|
||||
errorMessage: '검사 템플릿 조회에 실패했습니다.',
|
||||
});
|
||||
return { success: result.success, data: result.data, error: result.error };
|
||||
@@ -837,7 +835,7 @@ export async function saveInspectionDocument(
|
||||
error?: string;
|
||||
}> {
|
||||
const result = await executeServerAction<{ document_id: number; document_no: string; status: string }>({
|
||||
url: `${API_URL}/api/v1/work-orders/${workOrderId}/inspection-document`,
|
||||
url: buildApiUrl(`/api/v1/work-orders/${workOrderId}/inspection-document`),
|
||||
method: 'POST',
|
||||
body: data,
|
||||
errorMessage: '검사 문서 동기화에 실패했습니다.',
|
||||
|
||||
Reference in New Issue
Block a user