diff options
| author | joonhoekim <26rote@gmail.com> | 2025-11-05 11:54:08 +0900 |
|---|---|---|
| committer | joonhoekim <26rote@gmail.com> | 2025-11-05 11:54:08 +0900 |
| commit | 70aada2ef189467d1bc62dc892c629a71196e755 (patch) | |
| tree | fcca4c52c94f2d69d356bee2a7c5693236018794 /lib/vendor-investigation | |
| parent | 5994c98054a5883f8b15a204ffaca6ceaf86e013 (diff) | |
(김준회) 결재 개선, 실사의뢰/실사재의뢰 베스트프랙티스로 수정
Diffstat (limited to 'lib/vendor-investigation')
| -rw-r--r-- | lib/vendor-investigation/approval-actions.ts | 41 | ||||
| -rw-r--r-- | lib/vendor-investigation/handlers.ts | 33 |
2 files changed, 34 insertions, 40 deletions
diff --git a/lib/vendor-investigation/approval-actions.ts b/lib/vendor-investigation/approval-actions.ts index 607580d8..5da30011 100644 --- a/lib/vendor-investigation/approval-actions.ts +++ b/lib/vendor-investigation/approval-actions.ts @@ -1,8 +1,12 @@ /** * PQ 실사 관련 결재 서버 액션 * - * 사용자가 UI에서 호출하는 함수들 - * withApproval()을 사용하여 결재 프로세스를 시작 + * ✅ 베스트 프랙티스: + * - 'use server' 지시어 포함 (서버 액션) + * - UI에서 호출하는 진입점 함수들 + * - withApproval()을 사용하여 결재 프로세스 시작 + * - 템플릿 변수 준비 및 입력 검증 + * - 핸들러(Internal)에는 최소 데이터만 전달 */ 'use server'; @@ -14,13 +18,14 @@ import { debugLog, debugError, debugSuccess } from '@/lib/debug-utils'; /** * 결재를 거쳐 PQ 실사 의뢰를 생성하는 서버 액션 * - * 사용법 (클라이언트 컴포넌트에서): + * ✅ 사용법 (클라이언트 컴포넌트에서): * ```typescript * const result = await requestPQInvestigationWithApproval({ * pqSubmissionIds: [1, 2, 3], * vendorNames: "협력사A, 협력사B", * qmManagerId: 123, * qmManagerName: "홍길동", + * qmManagerEmail: "hong@example.com", * forecastedAt: new Date('2025-11-01'), * investigationAddress: "경기도 ...", * investigationNotes: "...", @@ -29,7 +34,7 @@ import { debugLog, debugError, debugSuccess } from '@/lib/debug-utils'; * }); * * if (result.status === 'pending_approval') { - * console.log('결재 ID:', result.approvalId); + * toast.success(`결재가 상신되었습니다. (ID: ${result.approvalId})`); * } * ``` */ @@ -55,7 +60,7 @@ export async function requestPQInvestigationWithApproval(data: { hasEpId: !!data.currentUser.epId, }); - // 입력 검증 + // 1. 입력 검증 if (!data.currentUser.epId) { debugError('[PQInvestigationApproval] Knox EP ID 없음'); throw new Error('Knox EP ID가 필요합니다'); @@ -66,7 +71,7 @@ export async function requestPQInvestigationWithApproval(data: { throw new Error('실사 의뢰할 PQ를 선택해주세요'); } - // 1. 템플릿 변수 매핑 + // 2. 템플릿 변수 매핑 debugLog('[PQInvestigationApproval] 템플릿 변수 매핑 시작'); const requestedAt = new Date(); const variables = await mapPQInvestigationToTemplateVariables({ @@ -82,22 +87,19 @@ export async function requestPQInvestigationWithApproval(data: { variableKeys: Object.keys(variables), }); - // 2. 결재 워크플로우 시작 (템플릿 기반) + // 3. 결재 워크플로우 시작 debugLog('[PQInvestigationApproval] withApproval 호출'); const result = await withApproval( // actionType: 핸들러를 찾을 때 사용할 키 'pq_investigation_request', - // actionPayload: 결재 승인 후 핸들러에 전달될 데이터 + // actionPayload: 결재 승인 후 핸들러에 전달될 데이터 (최소 데이터만) { pqSubmissionIds: data.pqSubmissionIds, qmManagerId: data.qmManagerId, - qmManagerName: data.qmManagerName, forecastedAt: data.forecastedAt, investigationAddress: data.investigationAddress, investigationNotes: data.investigationNotes, - vendorNames: data.vendorNames, - currentUser: data.currentUser, }, // approvalConfig: 결재 상신 정보 (템플릿 포함) @@ -123,7 +125,7 @@ export async function requestPQInvestigationWithApproval(data: { /** * 결재를 거쳐 PQ 실사 재의뢰를 처리하는 서버 액션 * - * 사용법 (클라이언트 컴포넌트에서): + * ✅ 사용법 (클라이언트 컴포넌트에서): * ```typescript * const result = await reRequestPQInvestigationWithApproval({ * investigationIds: [1, 2, 3], @@ -134,7 +136,7 @@ export async function requestPQInvestigationWithApproval(data: { * }); * * if (result.status === 'pending_approval') { - * console.log('결재 ID:', result.approvalId); + * toast.success(`재의뢰 결재가 상신되었습니다. (ID: ${result.approvalId})`); * } * ``` */ @@ -153,7 +155,7 @@ export async function reRequestPQInvestigationWithApproval(data: { hasReason: !!data.reason, }); - // 입력 검증 + // 1. 입력 검증 if (!data.currentUser.epId) { debugError('[PQReRequestApproval] Knox EP ID 없음'); throw new Error('Knox EP ID가 필요합니다'); @@ -164,7 +166,7 @@ export async function reRequestPQInvestigationWithApproval(data: { throw new Error('재의뢰할 실사를 선택해주세요'); } - // 1. 기존 실사 정보 조회 (첫 번째 실사 기준) + // 2. 기존 실사 정보 조회 (첫 번째 실사 기준 - 템플릿 변수용) debugLog('[PQReRequestApproval] 기존 실사 정보 조회'); const { default: db } = await import('@/db/db'); const { vendorInvestigations, users } = await import('@/db/schema'); @@ -197,7 +199,7 @@ export async function reRequestPQInvestigationWithApproval(data: { forecastedAt: existingInvestigation.forecastedAt, }); - // 2. 템플릿 변수 매핑 + // 3. 템플릿 변수 매핑 debugLog('[PQReRequestApproval] 템플릿 변수 매핑 시작'); const reRequestedAt = new Date(); const { mapPQReRequestToTemplateVariables } = await import('./handlers'); @@ -206,7 +208,7 @@ export async function reRequestPQInvestigationWithApproval(data: { investigationCount: data.investigationIds.length, reRequestedAt, reason: data.reason, - // 기존 실사 정보 전달 + // 기존 실사 정보 전달 (템플릿 표시용) forecastedAt: existingInvestigation.forecastedAt || undefined, investigationAddress: existingInvestigation.investigationAddress || undefined, qmManagerName: existingInvestigation.qmManagerName || undefined, @@ -216,16 +218,15 @@ export async function reRequestPQInvestigationWithApproval(data: { variableKeys: Object.keys(variables), }); - // 2. 결재 워크플로우 시작 (템플릿 기반) + // 4. 결재 워크플로우 시작 debugLog('[PQReRequestApproval] withApproval 호출'); const result = await withApproval( // actionType: 핸들러를 찾을 때 사용할 키 'pq_investigation_rerequest', - // actionPayload: 결재 승인 후 핸들러에 전달될 데이터 + // actionPayload: 결재 승인 후 핸들러에 전달될 데이터 (최소 데이터만) { investigationIds: data.investigationIds, - vendorNames: data.vendorNames, }, // approvalConfig: 결재 상신 정보 (템플릿 포함) diff --git a/lib/vendor-investigation/handlers.ts b/lib/vendor-investigation/handlers.ts index 24cad870..28a218b5 100644 --- a/lib/vendor-investigation/handlers.ts +++ b/lib/vendor-investigation/handlers.ts @@ -1,44 +1,40 @@ /** * PQ 실사 관련 결재 액션 핸들러 * - * 실제 비즈니스 로직만 포함 (결재 로직은 approval-workflow에서 처리) + * ✅ 베스트 프랙티스: + * - 'use server' 지시어 없음 (순수 비즈니스 로직만) + * - 결재 승인 후 실행될 최소한의 데이터만 처리 + * - DB 조작 및 실제 비즈니스 로직만 포함 */ -'use server'; - -import { requestInvestigationAction } from '@/lib/pq/service'; import { debugLog, debugError, debugSuccess } from '@/lib/debug-utils'; /** * PQ 실사 의뢰 핸들러 (결재 승인 후 실행됨) * - * 이 함수는 직접 호출하지 않고, 결재 워크플로우에서 자동으로 호출됨 + * ✅ Internal 함수: 결재 워크플로우에서 자동 호출됨 (직접 호출 금지) * - * @param payload - withApproval()에서 전달한 actionPayload + * @param payload - withApproval()에서 전달한 actionPayload (최소 데이터만) */ export async function requestPQInvestigationInternal(payload: { pqSubmissionIds: number[]; qmManagerId: number; - qmManagerName?: string; forecastedAt: Date; investigationAddress: string; investigationNotes?: string; - vendorNames?: string; // 복수 업체 이름 (표시용) - currentUser: { id: number; epId: string | null; email?: string }; }) { debugLog('[PQInvestigationHandler] 실사 의뢰 핸들러 시작', { pqCount: payload.pqSubmissionIds.length, qmManagerId: payload.qmManagerId, - currentUser: payload.currentUser, - vendorNames: payload.vendorNames, }); try { - // 실제 실사 의뢰 처리 - debugLog('[PQInvestigationHandler] requestInvestigationAction 호출'); + // 기존 PQ 서비스 함수 사용 (DB 트랜잭션 포함) + const { requestInvestigationAction } = await import('@/lib/pq/service'); + const result = await requestInvestigationAction( payload.pqSubmissionIds, - payload.currentUser, + { id: 0, epId: null, email: undefined }, // 핸들러에서는 currentUser 불필요 { qmManagerId: payload.qmManagerId, forecastedAt: payload.forecastedAt, @@ -104,23 +100,20 @@ export async function mapPQInvestigationToTemplateVariables(payload: { /** * PQ 실사 재의뢰 핸들러 (결재 승인 후 실행됨) * - * 이 함수는 직접 호출하지 않고, 결재 워크플로우에서 자동으로 호출됨 + * ✅ Internal 함수: 결재 워크플로우에서 자동 호출됨 (직접 호출 금지) * - * @param payload - withApproval()에서 전달한 actionPayload + * @param payload - withApproval()에서 전달한 actionPayload (최소 데이터만) */ export async function reRequestPQInvestigationInternal(payload: { investigationIds: number[]; - vendorNames?: string; // 복수 업체 이름 (표시용) }) { debugLog('[PQReRequestHandler] 실사 재의뢰 핸들러 시작', { investigationCount: payload.investigationIds.length, - vendorNames: payload.vendorNames, }); try { - // 실제 실사 재의뢰 처리 + // 기존 PQ 서비스 함수 사용 const { reRequestInvestigationAction } = await import('@/lib/pq/service'); - debugLog('[PQReRequestHandler] reRequestInvestigationAction 호출'); const result = await reRequestInvestigationAction(payload.investigationIds); |
