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
|
"use server";
import { BasicContractView } from "@/db/schema";
import { getComplianceResponseByBasicContractId } from "@/lib/compliance/services";
import { syncSpecificApprovalStatusAction } from "@/lib/knox-api/approval/approval";
/**
* 여러 계약서에 대한 RED FLAG 해제 상태를 한 번에 확인
*/
export async function checkRedFlagResolutionForContracts(
contracts: BasicContractView[]
): Promise<Record<number, { resolved: boolean; resolvedAt: Date | null }>> {
const result: Record<number, { resolved: boolean; resolvedAt: Date | null }> = {};
// 준법서약 템플릿인 계약서만 필터링
const complianceContracts = contracts.filter(contract =>
contract.templateName?.includes('준법')
);
if (complianceContracts.length === 0) {
return result;
}
// 1. 먼저 DB에서 현재 상태 조회
const initialChecks = await Promise.all(
complianceContracts.map(async (contract) => {
try {
const response = await getComplianceResponseByBasicContractId(contract.id);
return {
contractId: contract.id,
response
};
} catch (error) {
console.error(`Error fetching compliance response for contract ${contract.id}:`, error);
return {
contractId: contract.id,
response: null
};
}
})
);
// 2. 진행 중인 결재(해소요청)가 있는지 확인하고 Knox 상태 동기화
const pendingApprovalIds: string[] = [];
initialChecks.forEach(check => {
const { response } = check;
// 해소요청은 했으나(approvalId 있음) 아직 해소되지 않은(resolvedAt 없음) 경우
if (response?.redFlagResolutionApprovalId && !response.redFlagResolvedAt) {
pendingApprovalIds.push(response.redFlagResolutionApprovalId);
}
});
if (pendingApprovalIds.length > 0) {
try {
// Knox API를 통해 최신 결재 상태 동기화
// 이 과정에서 결재가 완료되었다면 DB의 redFlagResolvedAt도 업데이트됨 (syncSpecificApprovalStatusAction 내부 로직)
await syncSpecificApprovalStatusAction(pendingApprovalIds);
} catch (error) {
console.error('Error syncing approval status:', error);
}
}
// 3. 동기화 후 최종 상태 다시 확인
// (동기화 과정에서 DB가 업데이트되었을 수 있으므로 다시 조회하거나,
// 성능을 위해 위에서 동기화된 건만 다시 조회하는 방식도 가능하지만,
// 여기서는 안전하게 다시 조회하는 방식을 택함)
const finalChecks = await Promise.all(
complianceContracts.map(async (contract) => {
try {
const response = await getComplianceResponseByBasicContractId(contract.id);
return {
contractId: contract.id,
resolved: response?.redFlagResolvedAt !== null && response?.redFlagResolvedAt !== undefined,
resolvedAt: response?.redFlagResolvedAt || null
};
} catch (error) {
return {
contractId: contract.id,
resolved: false,
resolvedAt: null
};
}
})
);
// 결과를 Record 형태로 변환
finalChecks.forEach(check => {
result[check.contractId] = {
resolved: check.resolved,
resolvedAt: check.resolvedAt
};
});
return result;
}
|