summaryrefslogtreecommitdiff
path: root/lib/basic-contract/actions/check-red-flag-resolution.ts
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-11-21 06:04:56 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-11-21 06:04:56 +0000
commitb845ccde2910894911233cda273657d2b52e63f9 (patch)
treef12032484952225d099b3399f800d912bfdbda88 /lib/basic-contract/actions/check-red-flag-resolution.ts
parenteacfa3f36274e495838a7114d68ff80a0f257a6a (diff)
(임수민) 준법 Red Flag 수정
Diffstat (limited to 'lib/basic-contract/actions/check-red-flag-resolution.ts')
-rw-r--r--lib/basic-contract/actions/check-red-flag-resolution.ts97
1 files changed, 97 insertions, 0 deletions
diff --git a/lib/basic-contract/actions/check-red-flag-resolution.ts b/lib/basic-contract/actions/check-red-flag-resolution.ts
new file mode 100644
index 00000000..84dcdf75
--- /dev/null
+++ b/lib/basic-contract/actions/check-red-flag-resolution.ts
@@ -0,0 +1,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;
+}
+