net45 UiPath 레거시 프로젝트를 Codex로 분석한 순서

약 7분 읽기

설명서 없이 소스 폴더만 넘겨받는 일은 RPA 운영에서 드물지 않다. 이번에 받은 건 net45라는 이름의 폴더였다. 열어보니 UiPath REFramework 프로젝트였고, Windows-Legacy 호환(.NET Framework 기반)에 클래식 액티비티로 만든 레거시였다. 외부 콘도 예약 사이트에 예약을 넣고 취소하는 자동화다. 요청은 하나였다. “취소 관련 흐름을 자세히 분석해줘.”

분석은 Codex CLI에게 맡겼고, 나는 범위를 정하고, 결과가 소스와 맞는지 확인했다. 이 글은 그 순서와, 중간에 막힌 지점, 그리고 분석 끝에 고친 로직 하나를 정리한 기록이다.

로봇 사진 — 처음에는 디컴파일러 툴을 이용해 DLL 내부를 들여다보려고 했
Photo by Pavel Danilyuk on Pexels

전체를 읽히지 말고 연결부부터

REFramework 프로젝트는 XAML 파일이 많다. 처음에 전체를 검색하게 했더니 결과가 너무 커서 오히려 흐름이 안 보였다. 그래서 범위를 좁혔다.

  1. Main.xaml과 Process.xaml의 연결부만 먼저 읽는다. REFramework는 Process.xaml이 실제 업무 로직의 입구다.
  2. 그다음 해당 사이트 전용 워크플로가 모인 Custom 폴더만 본다. 1번부터 4번까지 번호가 붙어 있었다.
  3. 번호 순서가 실제 호출 순서와 같은지 Process.xaml에서 확인한다.

이 순서로 보니 취소 경로가 바로 나왔다. 전체 검색으로는 한참 걸리던 일이 연결부 두 파일을 읽는 것으로 정리됐다. Process.xaml의 예약취소 분기에서 2번 → 3번 → 3-1번 → 4번 순으로 워크플로를 부른다. 레거시 프로젝트에서 가장 먼저 찾아야 할 건 “어디서 시작해서 어디로 넘어가는가”이고, 개별 파일의 세부는 그다음이다.

설정 파일이 엑셀이 아니었다

REFramework는 보통 Data/Config.xlsx에 사이트 주소, 큐 이름, 재시도 횟수 같은 설정을 둔다. 그런데 이 파일을 열려고 하니 엑셀(ZIP) 형식이 아니라 OpenPGP 공개키 형식으로 인식됐다. 암호화된 파일이었다. 설정값을 직접 읽을 수 없으니, XAML 안에 드러난 인수, 로그 메시지, UI 선택자를 근거로 분석을 이어갔다.

이게 생각보다 문제가 되지 않았다. 로그 메시지는 개발자가 “지금 무엇을 하는지” 적어둔 문장이라 흐름을 읽는 데 오히려 도움이 됐고, 선택자는 어느 화면의 어떤 버튼을 누르는지 정확히 알려준다.

하나 더 조심한 게 있다. 원본 XAML 주석에 계정 정보가 적혀 있었다. 다른 모델에게 교차 검토를 맡길 때는 그 값을 브리프에 절대 넣지 않고, 흐름만 요약해서 넘겼다. 레거시 소스를 외부 도구에 넘길 때는 주석까지 비밀값이 있는지 먼저 봐야 한다.

취소는 취소 버튼을 누르는 게 아니었다

흐름을 따라가며 가장 놀란 부분이다. 사이트 취소는 예약 화면의 취소 버튼을 누르는 방식이 아니었다. 3번에서 ‘결제대기’ 상태 예약을 찾고, 4번에서 예약 상세의 이용자명과 연락처를 회사 공용값으로 덮어쓴 뒤 ‘변경하기’를 누른다. 예약을 지우는 게 아니라, 개인에게 잡혀 있던 예약을 회사 쪽으로 되돌려 받는 방식이다. 숙박 기간이 여러 날이면 1박 단위로 반복한다.

순서에도 규칙이 있었다. 아래는 Process.xaml의 흐름을 이해하기 쉽게 다시 적은 의사 코드다.

For Each row In dt예약
    ' 1) 사내 시스템 취소가 먼저 — 끝나면 행에 O 표시
    If row("구분") = "취소" AndAlso row("EHR변경") <> "O" Then
        ' 사내 시스템에서 '취소요청' 건을 찾아 상태 변경
        row("EHR변경") = "O"
    End If

    ' 2) 사이트 취소는 사내 시스템 취소가 끝난 건만
    If row("EHR변경") = "O" AndAlso row("콘도변경여부") <> "O" Then
        ' 2 → 3 → 3-1 → 4 순서로 워크플로 호출
    End If
Next

사내 시스템의 취소가 먼저 끝나야 사이트 취소를 한다. 그리고 각 단계가 끝나면 엑셀 행에 O를 찍는다. 이 O 표시가 “이 건은 이미 처리했다”는 표식이다. 로봇이 중간에 멈춰서 다시 돌려도 O가 찍힌 행은 건너뛰니, 같은 예약을 두 번 처리하지 않는다. REFramework의 트랜잭션을 큐 대신 엑셀 행 단위로 구현한 셈이다.

미결제 취소완료 건을 처리 O로

분석이 끝나고 실제 요구가 하나 나왔다. 사이트에서 결제를 하지 않아 이미 자동 취소된 건이 있다. 이런 건은 로봇이 할 일이 없으니 엑셀에 바로 처리 O로 표시하고 싶었다.

먼저 그 상태가 화면에 어떻게 보이는지 확인했다. 사이트 화면을 HTML로 저장해서 줬는데, 렌더링된 결과가 한 줄짜리라 검색 결과가 통째로 쏟아졌다. 필요한 부분만 잘라서 보니 상태 텍스트는 붙여 쓴 미결제취소완료가 아니라 중간에 공백이 있는 미결제 취소완료였다. 내부 코드값은 CNPC로 보였다. 요구사항에 적힌 대로 공백 없이 비교했다면 한 건도 걸리지 않았을 것이다. 화면에 보이는 글자를 사람이 옮겨 적으면 이런 차이가 쉽게 사라진다. 조건에 쓸 텍스트는 원본 HTML에서 그대로 복사해야 한다.

고치는 위치도 중요했다. 이런 건을 기존 흐름대로 4번까지 태우면, 이미 취소된 예약의 정보를 바꾸려다 실패한다. 그래서 사이트 취소에 들어가기 전에 3번 조회를 ‘미결제 취소완료’ 상태로 한 번 먼저 돌리도록 했다.

Try
    3_예약상태조회.xaml
      in_ArrStr상태값 = {"미결제 취소완료"}     ' 공백 있음. "미결제취소완료" 아님
    3-1_등록가능건찾기.xaml
      in_bool_예약취소여부 = False
    If LstUi구좌.Count > 0 Then
        row("콘도변경여부") = "O"
        Log: 이미 미결제 취소완료 상태라 처리 O
        Continue For Each
    End If
Catch
    ' 없으면 기존 결제대기 취소 로직 계속 진행
End Try

찾으면 O를 찍고 다음 행으로 넘어간다. 못 찾으면 예외로 빠져서 기존 결제대기 취소 로직을 그대로 탄다. 기존 흐름은 한 줄도 바꾸지 않고 앞에 확인 단계만 붙인 것이다. 레거시 프로젝트를 고칠 때는 이렇게 기존 경로를 건드리지 않는 쪽이 가장 안전하다.

당장 Windows 호환으로 바꾸지 않은 이유

레거시 프로젝트를 보면 먼저 최신 형식으로 바꾸고 싶어진다. Studio에는 Windows-Legacy 프로젝트를 Windows 호환으로 바꾸는 기능이 있다. 하지만 이번에는 손대지 않았다. Windows 호환은 .NET 기반이 달라서 패키지 구성이 바뀌고, 클래식 액티비티는 변환 뒤에 동작을 하나하나 다시 검증해야 한다. 운영 중인 예약·취소 자동화를 요구사항 하나 때문에 통째로 다시 테스트하는 건 위험이 더 크다. 변환은 따로 일정을 잡아서 할 일이고, 이번 수정은 기존 형식 안에서 끝냈다.

레거시를 넘겨받았을 때의 순서

정리하면, 설명서 없는 UiPath 프로젝트를 받았을 때 이 순서로 본다.

  • Main과 Process의 연결부부터 읽고, 호출 순서를 먼저 잡는다.
  • 설정 파일이 안 열리면 로그 메시지와 선택자로 대신한다.
  • 엑셀이나 큐에 남기는 표식(O, 상태값)을 찾는다. 그게 재실행 시 중복을 막는 장치다.
  • 화면 텍스트는 원본 HTML로 정확히 확인한다. 공백 하나가 조건을 바꾼다.
  • 고칠 때는 기존 경로 앞에 확인 단계를 붙이고, 기존 경로는 건드리지 않는다.
  • 외부 도구에 넘기기 전에 주석까지 비밀값을 지운다.
황민

황민 (Hwang Min)

IT·RPA·AI 분야 개발자. 웹앱 개발, UiPath RPA, n8n 자동화 실무 경력 4년. AI·금융·IT 트렌드를 현장 개발자 시각으로 분석합니다.

댓글 남기기

𝕏fin