1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
/**
* 정규업체 등록 관련 결재 서버 액션
*
* 사용자가 UI에서 호출하는 함수들
* withApproval()을 사용하여 결재 프로세스를 시작
*/
'use server';
import { ApprovalSubmissionSaga } from '@/lib/approval';
import { mapRegistrationToTemplateVariables } from './handlers';
import { debugLog, debugError, debugSuccess } from '@/lib/debug-utils';
import type { RegistrationRequestData } from '@/components/vendor-regular-registrations/registration-request-dialog';
import db from '@/db/db';
import { eq } from 'drizzle-orm';
import { vendorRegularRegistrations } from '@/db/schema/vendorRegistrations';
/**
* 결재를 거쳐 정규업체 등록을 처리하는 서버 액션
*
* 사용법 (클라이언트 컴포넌트에서):
* ```typescript
* const result = await registerVendorWithApproval({
* registrationId: 123,
* requestData: registrationData,
* currentUser: { id: 1, epId: 'EP001', email: 'user@example.com' },
* approvers: ['EP002', 'EP003']
* });
*
* if (result.status === 'pending_approval') {
* console.log('결재 ID:', result.approvalId);
* }
* ```
*/
export async function registerVendorWithApproval(data: {
registrationId: number;
requestData: RegistrationRequestData;
vendorId?: number; // vendors 테이블에서 정보를 가져오기 위한 vendorId
currentUser: { id: number; epId: string | null; email?: string };
approvers?: string[]; // Knox EP ID 배열 (결재선)
}) {
debugLog('[VendorRegistrationApproval] 정규업체 등록 결재 서버 액션 시작', {
registrationId: data.registrationId,
companyName: data.requestData.companyNameKor,
businessNumber: data.requestData.businessNumber,
userId: data.currentUser.id,
hasEpId: !!data.currentUser.epId,
});
// 입력 검증
if (!data.currentUser.epId) {
debugError('[VendorRegistrationApproval] Knox EP ID 없음');
throw new Error('Knox EP ID가 필요합니다');
}
if (!data.registrationId) {
debugError('[VendorRegistrationApproval] 등록 ID 없음');
throw new Error('등록 ID가 필요합니다');
}
// 1. 템플릿 변수 매핑
debugLog('[VendorRegistrationApproval] 템플릿 변수 매핑 시작');
const requestedAt = new Date();
const variables = await mapRegistrationToTemplateVariables({
requestData: data.requestData,
requestedAt,
vendorId: data.vendorId,
});
debugLog('[VendorRegistrationApproval] 템플릿 변수 매핑 완료', {
variableKeys: Object.keys(variables),
});
// 2. 결재 워크플로우 시작 (Saga 패턴)
debugLog('[VendorRegistrationApproval] ApprovalSubmissionSaga 생성');
const saga = new ApprovalSubmissionSaga(
// actionType: 핸들러를 찾을 때 사용할 키
'vendor_regular_registration',
// actionPayload: 결재 승인 후 핸들러에 전달될 데이터
{
registrationId: data.registrationId,
requestData: data.requestData,
},
// approvalConfig: 결재 상신 정보 (템플릿 포함)
{
title: `정규업체 등록 - ${data.requestData.companyNameKor}`,
description: `${data.requestData.companyNameKor} 정규업체 등록 요청`,
templateName: '정규업체 등록', // 한국어 템플릿명
variables, // 치환할 변수들
approvers: data.approvers,
currentUser: data.currentUser,
}
);
debugLog('[VendorRegistrationApproval] Saga 실행 시작');
const result = await saga.execute();
// 3. 결재 상신 성공 시 상태를 pending_approval로 변경
if (result.status === 'pending_approval') {
debugLog('[VendorRegistrationApproval] 상태를 pending_approval로 변경');
await db.update(vendorRegularRegistrations)
.set({
status: 'pending_approval',
updatedAt: new Date()
})
.where(eq(vendorRegularRegistrations.id, data.registrationId));
}
debugSuccess('[VendorRegistrationApproval] 결재 워크플로우 완료', {
approvalId: result.approvalId,
status: result.status,
});
return result;
}
|