# ITMS 통합 프로젝트 설계서 (6개 저장소 → 단일 프로젝트)

> 작성: 2026-07-17 | 근거: 6개 저장소 전수 소스 분석 (Explore 3팀 병렬)
> 대상 루트: `C:\GUARDiA\workspace\itms\` | 원본: `C:\GUARDiA\workspace\{urpItms_00_Auth, urpItms_10_Api, urpItms_20_Front, urpItms_30_Batch, iams.nlib, ncmsToIamsDataTrans}`

---

## 1. 통합 가능성 판정: **가능 (조건부)**

| 저장소 | 세대/스택 | 역할 | 통합 적합도 |
|---|---|---|---|
| urpItms_00_Auth | Boot 2.6.2 · Java 16 · war/Undertow | OAuth2 인가서버 (JWT RSA 발급, :11000) | ★★★ 즉시 |
| urpItms_10_Api | Boot 2.6.2 · Java 11 · war/Undertow · MyBatis | OAuth2 리소스서버 — ITSM 비즈니스 API 43컨트롤러 (:11010) | ★★★ 즉시 |
| urpItms_20_Front | Boot 2.6.2 · Java 16 · JSP/Tiles/jQuery | 웹 UI 티어, DB 무접속·전부 REST 경유 (:11020) | ★★★ 즉시 |
| urpItms_30_Batch | Boot 2.6.2 · Java 16 · Quartz(DB 클러스터) · MyBatis | 배치 (KIC 인사연동·메일/알림톡·검색색인, :11030) | ★★★ 즉시 |
| ncmsToIamsDataTrans | Boot 2.6.2 · Java 11 · @Scheduled 데몬 | NCMS(kccfnova)→IAMS(uac_cltr_db) ETL + 파일복사 | ★★☆ 모듈 편입 |
| iams.nlib | **Maven · Java 8 · eGovFrame 3.8 · Spring 4.3** · JSP/Tiles WAR | nlib 도서/소장자료 포털 (독립 레거시) | ★☆☆ 레거시 격리 편입 |

**판정 근거:**
- urpItms 4종 + ncmsTrans는 전부 `com.urpsys` 그룹·Spring Boot 2.6.2·동일 Gradle 스캐폴딩·동일 저자 — 사실상 한 제품의 4-티어 + 위성 ETL. 컴파일 의존은 0 (전부 런타임 HTTP)이므로 멀티모듈로 묶어도 상호 간섭 없음.
- 포트 분리 설계(11000/11010/11020/11030) 그대로 유지 — 단일 JVM 병합이 아니라 **단일 저장소·멀티모듈·모듈별 독립 기동**이 정답.
- `iams.nlib`은 스택 세대가 2단계 낮아(Java 8·Spring 4) Gradle 컴포짓에 넣을 수 없음 → `legacy/` 폴더에 Maven 빌드 그대로 격리 편입 (빌드 파이프라인만 분리).

## 2. 목표 구조

```
workspace/itms/                         # 단일 Git 저장소 (Gitea: ythong/itms 또는 zio/itms)
├── settings.gradle                     # include: common, auth, api, front, batch, datatrans
├── build.gradle                        # 공통 플러그인/버전/저장소 (Boot 2.6.2, egovframe repo)
├── gradle/ gradlew*                    # 단일 래퍼 (7.4.2)
├── common/                             # ★신설: com.urpsys.common — 중복 6+클래스 단일화
│   └── src/main/java/com/urpsys/common/
│       ├── crypto/Aes256Cipher.java    #   (auth·api·front·batch·datatrans 5벌 → 1벌)
│       ├── exception/CustomException.java
│       ├── util/{CommonUtil, ConvertUtils, RestApiCallUtil, HtmlEmailUtil, DataSourceUtil}.java
│       └── config/{EncryptConfig, PasswordEncoderConfig}.java
├── auth/       # ← urpItms_00_Auth   (com.urpsys.baseauth, :11000)
├── api/        # ← urpItms_10_Api    (com.urpsys.baseapi + itmsapi, :11010)
├── front/      # ← urpItms_20_Front  (com.urpsys.basefront + itmsfront, :11020)
├── batch/      # ← urpItms_30_Batch  (com.urpsys.basebatch + itmsbatch + kicinsa, :11030)
├── datatrans/  # ← ncmsToIamsDataTrans (com.urpsys.kccfbat, ETL 데몬)
├── legacy/
│   └── nlib/   # ← iams.nlib (Maven·Java 8 그대로, Gradle 컴포짓 제외, 독립 빌드)
├── profiles/   # ★기관 프로파일 단일화: 16기관 × 4앱 = 64벌 yml → 기관별 1세트
│   └── {local, kic_dev, kic_rel, keiti_prod, kintex_prod, kccf, ccourt, nowon, ...}/
└── docs/       # 본 설계서 + 운영 가이드
```

## 3. 핵심 설계 결정

1. **멀티모듈 ≠ 단일 프로세스.** Auth(인가서버)와 Api(리소스서버)의 Spring Security 구성은 한 JVM에 합칠 수 없음(`@EnableAuthorizationServer` vs `@EnableResourceServer` 충돌). 모듈별 bootWar/bootJar 산출 + 기존 포트 유지.
2. **common 모듈 추출이 통합의 실질 가치.** `Aes256Cipher`·`CustomException`·`CommonUtil`·`RestApiCallUtil` 등이 5개 저장소에 복붙 포크되어 있음 — 단일 출처화로 유지보수 이중화 제거.
3. **Java 버전 통일: 17 (toolchain).** 현재 11(api·datatrans)/16(auth·front·batch) 혼재. Boot 2.6.2는 Java 17 지원 — toolchain 17로 상향 통일(코드 수정 최소). Boot 3.x/jakarta 이행은 별도 Phase(선택).
4. **기관 프로파일 체계 보존.** 15~16개 발주기관 프로파일(ccourt·hpnote·kccf·keiti·kic·kintex·kordi·nibr·nowon·sungshin·unikorea·yp21·vmware·infra_server 등)은 이 제품의 배포 모델 그 자체 — 파일명·프로파일명 불변, 위치만 모듈 밖 `profiles/`로 승격(중복 4벌 → 1벌).
5. **datatrans는 독립 모듈 유지(1단계).** Batch(Quartz DB 스케줄)와 스케줄 방식이 다르고(@Scheduled 매분 폴링 + 물리 파일복사) 대상 DB도 다름(kccfnova/uac_cltr_db). Quartz 잡으로의 흡수는 2단계 선택 과제.
6. **iams.nlib은 as-is 격리.** 재플랫폼 없이 `legacy/nlib`으로 이동만. eGovFrame 3.8→4.0 마이그레이션은 통합 범위 밖(별도 사업 규모).
7. **히스토리 보존.** 각 원본 repo를 `git subtree add`(또는 read-tree 병합)로 이식해 커밋 히스토리 유지. GUARDiA 관례상 repos/ 독립 저장소는 fresh init.

## 4. 리스크 및 정리 대상 (분석에서 발견)

| # | 항목 | 조치 |
|---|---|---|
| R1 | Auth(oauth2 2.3.4) vs Api(2.3.8) 버전 드리프트 | 2.3.8로 통일 |
| R2 | Api·datatrans의 `spring-boot-starter-logging` 전역 제외 (eGov dataaccess 충돌 회피) — Auth·Front는 미제외 | 루트 build.gradle에서 모듈별 유지, 병합 시 로깅 동작 검증 |
| R3 | datatrans `selectMultimediaAssets`에 개발용 `and id='132041' limit 1` 하드코딩 잔존 | 제거 (운영 데이터 전송 누락 원인) |
| R4 | `MailKaTalkSendKiccJob.java.20250703` 등 백업 파일, `bin/` 빌드 산출물 커밋 | 삭제 + .gitignore 정비 |
| R5 | iams.nlib `log4j-core 2.15.0` (Log4Shell 체인 미완 패치), poi 5.0.0/poi-ooxml 3.9 혼재 | legacy 편입 시 2.17.1+ 상향, poi 정합 |
| R6 | 시크릿(AES 암호문이지만 Gmail·NCP 카카오키·DB 접속정보)이 프로파일 yml ~64벌에 산재 | profiles/ 단일화 + 키파일 외부화(GUARDiA 표준 env 패턴) |
| R7 | Front 세션 인메모리(BASEJSP_JSESSIONID) — 스케일아웃 불가 | 현상 유지(문서화), 개선은 선택 |
| R8 | Boot 2.6.2·Java 16 EOL | Phase 3(선택)에서 Boot 3.x/Java 17+ 상향 |

## 5. 실행 단계 (하네스 파이프라인)

- **Phase 1 — 모노레포 조립:** itms/ 스캐폴드 + 6개 원본 subtree 이식 + 루트 Gradle 컴포짓 + 모듈별 빌드 통과 (기능 변경 0)
- **Phase 2 — common 추출·정리:** 중복 클래스 단일화(모듈별 import 전환), R1~R4 정리, 프로파일 profiles/ 승격, Java 17 toolchain 통일
- **Phase 3 — 검증·배포:** 모듈 전체 빌드 + 프로파일 스모크(local) + Gitea 신규 저장소 push + (선택) deploy_server 배선
- **Phase 4 (선택) — 현대화:** datatrans→Quartz 흡수, Boot 3/jakarta, nlib 재플랫폼

## 6. 시스템 관계도 (실측)

```
[사용자] → Front :11020 (JSP/Tiles, 세션+JWT보관)
              │ Unirest(JWT bearer)
              ├→ Auth :11000  /oauth/token, /oauth/token_key (RSA jwtkey.jks)
              └→ Api  :11010  srm·rem·bbs·cmm·pot·sta·sys (43 controllers)
                        └→ MariaDB ur_itms_db (192.168.8.131)
[Batch :11030] Quartz(QRTZ_* @ur_itms_db, clustered)
   ├→ ur_itms_db 직접 접속 (Api 미경유)
   ├→ Oracle XE :1521 (KIC 인사 kicinsadb)
   ├→ 메일/카카오 알림톡(NCP)
   └→ 외부 검색색인 서버 (api_search_server)
[datatrans] @Scheduled 매분: kccfnova(NCMS) → uac_cltr_db(IAMS) + 파일복사(NAS)
   └→ JWT 검증: Auth(:9001/:11000)
[legacy/nlib] 독립 WAR 포털 (nlib 소장자료/대출/게시판, 소셜로그인) — ITMS와 빌드 무관
```
