Wave H: Oracle 계보(As-Is) 심기 + 시스템 조망 재편(운영 콘솔)

■ Oracle 계보 — "원본은 Oracle 19c + Pro*C 였다"
현행 코드(ECPG/PostgreSQL)가 Oracle 시스템의 1차 이관본임을 콘크리트하게 보존.
- legacy-oracle/proc/*.pc (7본): ACQUIRE/AUTH_APPROVE/ST_MDR/SETTLE/RECONCILE/
  CL_DAILY/PAY_FILEGEN. 순수 Oracle Pro*C 방언 — sqlca/oraca, VARCHAR,
  WHENEVER SQLERROR GOTO, NVL/DECODE/SYSDATE/DUAL/ROWNUM/(+)/CONNECT BY/
  .NEXTVAL/TO_DATE, PL/SQL 패키지 호출, COMMIT WORK. 컴파일 대상 아님(As-Is 원본).
- legacy-oracle/plsql/*.sql (2본): PKG_SETTLE(정산), PKG_LEDGER(복식부기 기표).
  VARCHAR2/%TYPE/%ROWTYPE/CURSOR/EXCEPTION/RAISE_APPLICATION_ERROR.
- docs/ORACLE_PROVENANCE.md: As-Is(Oracle)→현행(ECPG)→To-Be(Spring Boot) 3단 계보
  + Oracle→PostgreSQL 방언 이관 매핑 15종 + "왜 DB는 PostgreSQL인가".
- gen_metrics.py: legacy-oracle 실측(원본 9파일 1,827LOC, 방언 12종 히트) →
  마이그레이션 난이도 화면에 "④ Oracle 계보" 패널 추가.

■ 시스템 조망 재편 — 실제 매입시스템 운영 콘솔
"마이그레이션 난이도"(Forge 관점 메타)를 시스템 조망에서 분리하고, 시스템 자체의
상태·아키텍처를 보여주는 운영 화면 신설.
- 신규 "시스템 현황"(#sys): 헬스 KPI(서버11/서비스1466/미결2PC/당일매입/채널UP/
  큐적체/오류) + 아키텍처 토폴로지(채널·카드망→전문GW→승인·매입→정산·지급→
  원장·마감·대사·검증→마스터·공통 계층도) + 채널상태 + 큐적체 + 처리량·오류율
  + 정산사이클(마감·순액정산·클리어링·프레젠트먼트). 전부 실측 조회.
- nav 재편: [시스템 조망]=시스템현황·아키텍처토폴로지·정산경제,
  [전환 분석(Forge)]=마이그레이션난이도.
- 토폴로지 모듈박스 렌더 버그(return ASI) 수정.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
hyeongwoo 2026-07-23 12:10:37 +09:00
parent 2ac4c3c920
commit e1729d6edc
14 changed files with 2054 additions and 7 deletions

69
docs/ORACLE_PROVENANCE.md Normal file
View file

@ -0,0 +1,69 @@
# Oracle 계보 (As-Is) — acquire-core-x
> **이 시스템의 원본은 Oracle 이다.** BC 매입시스템 As-Is 는 Oracle 19c + Pro\*C +
> Tuxedo/ATMI 였고(BAIS RFI 기준), 본 저장소의 현행 코드는 그 시스템을 오픈 스택
> (Enduro/X + ECPG + PostgreSQL)으로 **이식한 1차 이관본**이다. Klaro Forge 가
> 수행할 다음 이관은 이 레거시 → Java Spring Boot 다.
>
> `legacy-oracle/` 에 **As-Is Oracle Pro\*C 역사 원본**을 보존한다(컴파일 대상 아님).
> 현행 이식본(`app/src/**/*.pgc`, ECPG/PostgreSQL)과 1:1로 대조 가능하다.
## 3단 계보
```
┌── As-Is ───────────┐ ┌── 현행(1차 이관본) ─────┐ ┌── To-Be (Forge) ──────┐
│ Oracle 19c │ │ PostgreSQL 16 │ │ PostgreSQL 16 │
│ Pro*C (proc) │ → │ ECPG (EXEC SQL) │ → │ JPA / MyBatis │
│ Tuxedo/ATMI │ │ Enduro/X (open ATMI) │ │ Spring Boot 3.x │
│ PL/SQL 패키지 │ │ (패키지→서비스 인라인) │ │ @Service / @Transactional
│ legacy-oracle/*.pc │ │ app/src/**/*.pgc │ │ (target) │
└─────────────────────┘ └─────────────────────────┘ └────────────────────────┘
```
- As-Is → 현행: **DB 엔진 이관**(Oracle→PostgreSQL)은 끝났다. Oracle 방언·Pro\*C·PL/SQL
패키지를 PostgreSQL/ECPG 로 옮긴 결과가 현행 코드다.
- 현행 → To-Be: 남은 난제는 **애플리케이션 계층**(ATMI·임베디드SQL·UBF·XA)이며,
이게 Forge 가 다룰 대상이다. DB 엔진은 이미 PostgreSQL 이라 To-Be 와 일치한다.
## Oracle → PostgreSQL 방언 이관 매핑 (1차 이관에서 실제로 옮긴 것들)
| Oracle (As-Is, Pro\*C) | PostgreSQL (현행, ECPG) | 이관 난이도·주의 |
|---|---|---|
| `VARCHAR2(n)` / Pro\*C `VARCHAR h[n]` | `TEXT` / `char h[n]` | 널·공백 트림 의미 차이 |
| `NVL(x, d)` | `COALESCE(x, d)` | 인자 개수 차이(NVL2→CASE) |
| `DECODE(e, k1,v1, k2,v2, d)` | `CASE WHEN e=k1 THEN v1 ... ELSE d END` | 다분기 전개, NULL 동등성 차이 |
| `SYSDATE` / `SYSTIMESTAMP` | `now()` / `current_date` | 시간대·타입 차이 |
| `... FROM DUAL` | (FROM 절 생략) | 시퀀스·스칼라 조회 재작성 |
| `seq.NEXTVAL` / `seq.CURRVAL` | `nextval('seq')` / `currval('seq')` | 문법·세션 시맨틱 차이 |
| `ROWNUM = 1` / `ROWNUM <= n` | `LIMIT 1` / `LIMIT n` | ROWNUM 은 정렬 前 적용 → 의미 함정 |
| 외부조인 `t1.a (+) = t2.b` | `LEFT/RIGHT JOIN ... ON` | 구식 `(+)` 전면 재작성 |
| `CONNECT BY PRIOR` 계층질의 | `WITH RECURSIVE` CTE | 계층 재귀 완전 재작성(최난이도) |
| `TO_DATE(s,'YYYYMMDD')` / `TO_CHAR(d,fmt)` | `to_date`/`to_char` (포맷토큰 일부 상이) | 포맷 마스크 검증 필요 |
| `(+)`/`MINUS`/`ROWID` | `EXCEPT`/`ctid`(비권장) | 세트연산·행식별자 대체 |
| Pro\*C `EXEC SQL WHENEVER SQLERROR GOTO` | ECPG 동일 문 + `sqlca.sqlcode` 분기 | 라벨분기 유지 가능 |
| Pro\*C `EXEC SQL INCLUDE oraca` / `EXEC ORACLE OPTION` | (해당 없음) | Oracle 전용 진단영역 제거 |
| **PL/SQL 패키지** (`pkg_x.proc`) | ECPG 서비스 인라인 / 함수 | 패키지 상태·오버로드 소실, 로직 서비스로 흡수 |
| `RAISE_APPLICATION_ERROR(-20001,...)` | `RAISE EXCEPTION` / 리턴코드 | 예외 프로토콜 재설계 |
| `UTL_FILE` 파일 I/O | 서버 파일 I/O / COPY | 배치 파일생성 재작성 |
## As-Is 원본 보존 목록 (`legacy-oracle/`)
| 원본 (Oracle Pro\*C / PL-SQL) | 현행 이식본 (ECPG) | 업무 |
|---|---|---|
| `proc/ACQUIRE.pc` | `app/src/ac/svc/ACQUIRE.pgc` | 매입 접수 |
| `proc/AUTH_APPROVE.pc` | `app/src/au/svc/AUTH_APPROVE.pgc` | 승인 확정 |
| `proc/ST_MDR.pc` | `app/src/st/svc/ST_MDR.pgc` | MDR 수수료 기표 |
| `proc/SETTLE.pc` | `app/src/st/svc/SETTLE.pgc` | 정산 확정 |
| `proc/RECONCILE.pc` | `app/src/rc/svc/RECONCILE.pgc` | 대사 (CONNECT BY) |
| `proc/CL_DAILY.pc` | `app/src/cl/svc/CL_DAILY.pgc` | 일마감 배치 |
| `proc/PAY_FILEGEN.pc` | `app/src/py/svc/PAY_FILEGEN.pgc` | 지급파일 생성 배치 |
| `plsql/PKG_SETTLE.sql` | (서비스로 인라인) | 정산 PL/SQL 패키지 |
| `plsql/PKG_LEDGER.sql` | (서비스로 인라인) | 원장 기표 PL/SQL 패키지 |
## 왜 DB 는 PostgreSQL 인가 (Oracle 로 되돌리지 않는 이유)
- **To-Be 가 PostgreSQL** 이다(BAIS RFI: Oracle 19c → PostgreSQL 16). DB 이관은 이미
완료 상태로 두고, Forge 가 다룰 **애플리케이션 이관**(ATMI/임베디드SQL/UXA)에 집중한다.
- 라이선스·재현성: 오픈 스택이라 `docker compose up` 한 번으로 어디서든 실동작.
- 마이그레이션 난이도의 본질은 DB 엔진이 아니라 그 위의 Pro\*C·Tuxedo·XA 계층이며,
그 난이도는 위 원본들에서 그대로 확인된다.