summaryrefslogtreecommitdiff
path: root/lib/approval-log/actions.ts
blob: 643939090fc46e1b370ea64d167e8d90dcb813e1 (plain)
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
'use server';

import { revalidatePath } from 'next/cache';
import { ApprovalExecutionSaga } from '@/lib/approval/approval-saga';
import { getApprovalLogDetail } from './service';
import db from '@/db/db';
import { pendingActions } from '@/db/schema/knox/pending-actions';
import { eq } from 'drizzle-orm';

/**
 * 결재 후처리 강제 실행
 * 
 * 외부 시스템(Knox) 장애 시 결재가 승인되었지만 
 * 후속 작업이 실행되지 않은 경우 강제로 실행
 * 
 * @param apInfId 결재 ID
 * @returns 성공 여부 및 결과 메시지
 */
export async function forcePostProcessApproval(apInfId: string) {
  try {
    console.log(`[ForcePostProcess] Starting forced post-process for ${apInfId}`);

    // 1. 결재 로그 및 Pending Action 조회
    const detail = await getApprovalLogDetail(apInfId);
    
    if (!detail) {
      return {
        success: false,
        error: '결재 로그를 찾을 수 없습니다.',
      };
    }

    const { pendingAction } = detail;

    // 2. Pending Action이 없는 경우
    if (!pendingAction) {
      return {
        success: false,
        error: '실행할 후처리 작업이 없습니다. 이 결재는 후처리 작업이 연결되지 않은 결재입니다.',
      };
    }

    // 3. 이미 실행된 경우
    if (pendingAction.status === 'executed') {
      return {
        success: false,
        error: '이미 후처리가 완료된 결재입니다.',
      };
    }

    // 4. Pending Action 상태를 'pending'으로 재설정 (강제 실행을 위해)
    console.log(`[ForcePostProcess] Resetting pending action status to 'pending'`);
    await db.update(pendingActions)
      .set({
        status: 'pending',
        errorMessage: null,
        executionResult: null,
      })
      .where(eq(pendingActions.apInfId, apInfId));

    // 5. ApprovalExecutionSaga를 통해 강제 실행
    console.log(`[ForcePostProcess] Executing ApprovalExecutionSaga`);
    const saga = new ApprovalExecutionSaga(apInfId);
    const result = await saga.execute();

    // 6. 캐시 무효화
    revalidatePath(`/[lng]/evcp/approval/log`, 'page');
    revalidatePath(`/[lng]/evcp/approval/log/${apInfId}`, 'page');

    console.log(`[ForcePostProcess] ✅ Post-process completed successfully`);

    return {
      success: true,
      message: '후처리가 성공적으로 실행되었습니다.',
      result,
    };

  } catch (error) {
    console.error('[ForcePostProcess] ❌ Post-process failed:', error);
    
    return {
      success: false,
      error: error instanceof Error 
        ? `후처리 실행 중 오류가 발생했습니다: ${error.message}` 
        : '후처리 실행 중 알 수 없는 오류가 발생했습니다.',
    };
  }
}