ERP-node/docs/조건부_연결_구현_계획.md

7.5 KiB

🔗 조건부 연결 기능 구현 계획

📋 프로젝트 개요

현재 DataFlow 시스템에서 3가지 연결 종류를 지원하고 있으며, 이 중 데이터 저장외부 호출 기능에 실행 조건 로직을 추가해야 합니다.

현재 연결 종류

  1. 단순 키값 연결 - 조건 설정 불필요 (기존 방식 유지)
  2. 데이터 저장 - 실행 조건 설정 필요
  3. 외부 호출 - 실행 조건 설정 필요

🎯 기능 요구사항

데이터 저장 기능

"from 테이블의 컬럼이 특정 조건을 만족하면 to 테이블에 특정 액션을 취할 것"

예시 시나리오:

  • work_order 테이블의 status = 'APPROVED' 이고 quantity > 0 일 때
  • material_requirement 테이블에 자재 소요량 데이터 INSERT

외부 호출 기능

"from테이블의 컬럼이 특정 조건을 만족하면 외부 api호출이나 이메일 발송 등의 동작을 취해야 함"

예시 시나리오:

  • employee_master 테이블의 employment_status = 'APPROVED' 일 때
  • 외부 이메일 API 호출하여 환영 메일 발송

🗄️ 데이터베이스 스키마 변경

1. 컬럼 추가

-- 기존 데이터 삭제 후 dataflow_diagrams 테이블에 3개 컬럼 추가
DELETE FROM dataflow_diagrams;  -- 기존 데이터 전체 삭제

ALTER TABLE dataflow_diagrams
ADD COLUMN control JSONB,      -- 조건 설정
ADD COLUMN category JSONB,     -- 연결 종류 설정
ADD COLUMN plan JSONB;         -- 실행 계획 설정

-- 인덱스 추가
CREATE INDEX idx_dataflow_control_trigger ON dataflow_diagrams USING GIN ((control->'triggerType'));
CREATE INDEX idx_dataflow_category_type ON dataflow_diagrams USING GIN ((category->'type'));

2. 데이터 구조 설계

control 컬럼 - 조건 설정

{
  "triggerType": "insert",
  "conditionTree": {
    "type": "group",
    "operator": "AND",
    "children": [
      {
        "type": "condition",
        "field": "status",
        "operator": "=",
        "value": "APPROVED"
      }
    ]
  }
}

category 컬럼 - 연결 종류

{
  "type": "data-save" // "simple-key" | "data-save" | "external-call"
}

plan 컬럼 - 실행 계획

{
  "sourceTable": "work_order",
  "targetActions": [
    {
      "id": "action_1",
      "actionType": "insert",
      "targetTable": "material_requirement",
      "enabled": true,
      "fieldMappings": [
        {
          "sourceField": "work_order_id",
          "targetField": "order_id"
        }
      ]
    }
  ]
}

🎨 프론트엔드 UI 개선

ConnectionSetupModal.tsx 재설계

현재 구조 문제점

  • 모든 연결 종류에 동일한 UI 적용
  • 조건 설정 기능 없음
  • 단순 키값 연결과 조건부 연결의 구분 없음

개선 방안

1. 연결 종류별 UI 분기
// 연결 종류 선택 후 조건부 렌더링
{
  config.connectionType === "simple-key" && <SimpleKeyConnectionSettings />;
}

{
  (config.connectionType === "data-save" ||
    config.connectionType === "external-call") && (
    <ConditionalConnectionSettings />
  );
}
2. 조건 설정 섹션 추가
// control.html의 제어 조건 설정 섹션을 참조하여 구현
<div className="control-conditions">
  <h4>📋 실행 조건 설정</h4>
  <ConditionBuilder
    conditions={conditions}
    onConditionsChange={setConditions}
    availableFields={fromTableColumns}
  />
</div>
3. 액션 설정 섹션
<div className="control-actions">
  <h4> 실행 액션</h4>
  {config.connectionType === "data-save" && <DataSaveActionSettings />}
  {config.connectionType === "external-call" && <ExternalCallActionSettings />}
</div>

새로운 컴포넌트 구조

ConnectionSetupModal.tsx
├── BasicConnectionInfo (공통)
├── ConnectionTypeSelector (공통)
├── SimpleKeyConnectionSettings (단순 키값 전용)
└── ConditionalConnectionSettings (조건부 연결 전용)
    ├── ConditionBuilder (조건 설정)
    ├── DataSaveActionSettings (데이터 저장 액션)
    └── ExternalCallActionSettings (외부 호출 액션)

⚙️ 백엔드 서비스 구현

1. EventTriggerService 생성

// backend-node/src/services/eventTriggerService.ts
export class EventTriggerService {
  static async executeEventTriggers(
    triggerType: "insert" | "update" | "delete",
    tableName: string,
    data: Record<string, any>,
    companyCode: string
  ): Promise<void>;

  static async executeDataSaveAction(
    action: TargetAction,
    sourceData: Record<string, any>
  ): Promise<void>;

  static async executeExternalCallAction(
    action: ExternalCallAction,
    sourceData: Record<string, any>
  ): Promise<void>;
}

2. DynamicFormService 연동

// 기존 saveFormData 메서드에 트리거 실행 추가
async saveFormData(screenId: number, tableName: string, data: Record<string, any>) {
  // 기존 저장 로직
  const result = await this.saveToDatabase(data);

  // 🔥 조건부 연결 실행
  await EventTriggerService.executeEventTriggers("insert", tableName, data, companyCode);

  return result;
}

3. API 엔드포인트 추가

// backend-node/src/routes/dataflowRoutes.ts
router.post("/diagrams/:id/test-conditions", async (req, res) => {
  // 조건 테스트 실행
});

router.post("/diagrams/:id/execute-actions", async (req, res) => {
  // 액션 수동 실행
});

📝 구현 단계별 계획

Phase 1: 데이터베이스 준비

  • dataflow_diagrams 테이블 컬럼 추가 (기존 데이터 삭제 후 진행)
  • Prisma 스키마 업데이트

Phase 2: 프론트엔드 UI 개선

  • ConnectionSetupModal.tsx 재구조화
  • ConditionBuilder 컴포넌트 개발
  • 연결 종류별 설정 컴포넌트 분리
  • control.html 참조하여 조건 설정 UI 구현

Phase 3: 백엔드 서비스 개발

  • EventTriggerService 기본 구조 생성
  • 조건 평가 엔진 구현
  • 데이터 저장 액션 실행 로직
  • DynamicFormService 연동

Phase 4: 외부 호출 기능

  • 외부 API 호출 서비스
  • 이메일 발송 기능
  • 웹훅 지원
  • 오류 처리 및 재시도 로직

🔧 기술적 고려사항

1. 성능 최적화

  • 조건 평가 시 인덱스 활용
  • 대량 데이터 처리 시 배치 처리
  • 비동기 실행으로 메인 로직 블로킹 방지

2. 오류 처리

  • 트랜잭션 롤백 지원
  • 부분 실패 시 복구 메커니즘

3. 보안

  • SQL 인젝션 방지
  • 외부 API 호출 시 인증 처리
  • 민감 데이터 마스킹

4. 확장성

  • 새로운 액션 타입 추가 용이성
  • 복잡한 조건문 지원
  • 다양한 외부 서비스 연동

📚 참고 자료

🚀 다음 단계

  1. 데이터베이스 스키마 업데이트 부터 시작
  2. UI 재설계 - control.html 참조하여 조건 설정 UI 구현
  3. 백엔드 서비스 단계별 구현
  4. 외부 호출 기능 구현

이 문서는 조건부 연결 기능 구현을 위한 전체적인 로드맵을 제시합니다. 각 단계별로 상세한 구현 계획을 수립하여 진행할 예정입니다.