---
phase: research
agent: research-advisor
agent_version: 2
generated_at: 2026-06-29T09:04:35Z
concerns: []
source_confidence: high
workers_spawned: 2
---

# 조사 결과 — B2 dead code 삭제 안전성 + B4 의존성 업그레이드 사실조사

## 주제
bibimbap (Java21/SpringBoot/JSP/MyBatis WAR) 의 두 작업트랙:
- B2: dead code(abstracts 패키지, GameCatalog, header.jspf) 삭제 안전성
- B4: Spring Boot 최신 stable 버전 + OWASP Dependency-Check maven plugin(오프라인) 도입을 위한 사실조사

전부 read-only. 설계·구현·코드수정 없음.

---

## 트랙 B2 — dead code 삭제 안전성 (코드 사실 / 조사포인트 1)

### 포인트 1-A: abstracts 패키지
- 경로: `src/main/java/com/pandoli365/bibimbap/abstracts/`
- 요약: 4개 파일 존재 — `ErrorResult.java`, `Request.java`, `Result.java`, `Service.java`.
  - `ErrorResult` extends `Result` (status만 받는 생성자)
  - `Request` abstract, `IsReceivedAllField()` 기본 true 반환
  - `Result` abstract, status/message 필드
  - `Service<Req extends Request, Res extends Result>` 제네릭 abstract, `ChackService()`/`StartService()`
- 외부 참조 확인:
  - `rg "bibimbap\.abstracts|abstracts\."` → 4개 파일 자기 자신의 package 선언(라인1)만 hit. 패키지 밖 import/참조 **0건**.
  - **(advisor 보강)** `rg "extends (Service|Request|Result)|new ErrorResult|StartService|ChackService|IsReceivedAllField"` → hit는 전부 abstracts 패키지 **내부**의 정의/상호참조(Service.java가 ErrorResult/Request를 쓰고, ErrorResult가 Result를 extends)뿐. abstracts **외부**에서 `extends Service`/`extends Request`/`extends Result` 하는 구체 클래스 **0건**.
- 관련 파일:라인:
  - `abstracts/ErrorResult.java:3` — `public class ErrorResult extends Result`
  - `abstracts/Service.java:5` — `public abstract class Service<Req extends Request, Res extends Result>`
  - `abstracts/Service.java:13,15` — `(Res) new ErrorResult(401)` (패키지 내부 사용)
- 신뢰도: 확인됨 (rg 전수 + 직접 코드읽기 + advisor 상속 키워드 보강검증)

### 포인트 1-B: GameCatalog.java 참조
- 경로: `src/main/java/com/pandoli365/bibimbap/game/GameCatalog.java`
- 요약: `rg "GameCatalog"` 결과 참조 파일 2개뿐 — GameCatalog.java 자신 + GameController.java. 다른 컨트롤러·서비스 참조 **0건**.
- 관련 파일:라인:
  - `controller/api/GameController.java:5` — `import com.pandoli365.bibimbap.game.GameCatalog;`
  - `controller/api/GameController.java:150,155,157-162` — gameDetail() fallback 블록에서 사용
- 신뢰도: 확인됨

### 포인트 1-C: header.jspf include 여부
- 경로: `src/main/webapp/WEB-INF/jsp/fragments/header.jspf`
- 요약: `rg "header\.jspf|fragments/header"` → **0 hit**. `rg "include.*header"` → 0 hit (이 패턴으로는). header.jsp를 include하는 JSP는 총 **23개**이며 전부 `<jsp:include page="/WEB-INF/views/header.jsp"/>` 형태로 통일. `header.jspf`를 include하는 사례 **0건**.
- 관련 파일:라인: game-detail.jsp:1201, index.jsp:727, login.jsp:205 등 23개 전부 `/WEB-INF/views/header.jsp`
- 신뢰도: 확인됨

### 포인트 1-D: GameController.gameDetail() fallback 로직 (404 변경용 정확 라인)
- 경로: `src/main/java/com/pandoli365/bibimbap/controller/api/GameController.java`
- 요약: `gameDetail()` 메서드(137~173라인) 현재 흐름:
  - **140~148**: `gamesMapper.getGame(id)` DB조회 → `game != null`이면 정상 뷰 반환
  - **150**: `game == null` 진입. `if (id < Integer.MIN_VALUE || id > Integer.MAX_VALUE || !GameCatalog.isValidId((int) id))`
  - **151**: 위 조건 true이면 `return "redirect:/";`
  - **154~172**: `GameCatalog.isValidId()` true이면 `GameCatalog.toIndex(intId)`로 인덱스 구해 `NAMES/CREATORS/LIKE_COUNTS/CREATOR_NOTES/GIT_URLS` 배열값을 model 적재 후 `"game-detail"` 뷰 반환
- 현재 코드 사실: **DB에 없는 game ID에 대해 404를 반환하는 분기는 이 메서드에 존재하지 않는다.** GameCatalog.isValidId 통과 여부에 따라 (a) fallback 정적 뷰("game-detail") 또는 (b) 루트 redirect("redirect:/") 둘 중 하나로 귀결.
- "GameCatalog 제거 후 없는 게임 ID를 404로 바꾸려면 고쳐야 할 줄" (사실 식별, 설계 아님):
  - 150~151의 GameCatalog.isValidId 분기 + 154~172의 GameCatalog 기반 fallback 블록 전체가 제거 대상. game==null인 경로(150 진입 이후 전부)를 404 응답으로 대체해야 함. 즉 라인 150~172가 변경 영역.
- 신뢰도: 확인됨

---

## 트랙 B4 — Spring Boot / OWASP DC 버전 + 설정 (조사포인트 2,3,4)

### 포인트 2: Spring Boot 3.5.x 최신 stable(GA) 버전
- 요약: 현재 pom의 `3.5.14-SNAPSHOT`은 미출시 스냅샷. 3.5.x 계열 최신 **GA = 3.5.16** (2026-06-25 출시).
  - v3.5.14 GA 2026-04-23 / v3.5.15 GA 2026-06-10 / v3.5.16 GA 2026-06-25(최신)
  - 3.5.x 위로 4.0.x/4.1.x 별개 계열 존재(이번 트랙 범위 밖)
- 출처:
  - https://spring.io/blog/category/releases — "Spring Boot 3.5.16 available now" (2026-06-25)
  - https://github.com/spring-projects/spring-boot/releases — v3.5.16/3.5.15/3.5.14 확인
- 신뢰도: 확인됨 (spring.io 1차 + GitHub releases)

### 포인트 3-A: OWASP dependency-check-maven 최신 버전
- 요약: **12.2.2** (최신 GA).
  - 동명 disambiguation: 원 저장소 `jeremylong/DependencyCheck`는 2025-09-27 아카이브됨. 관리 이관처 `dependency-check/DependencyCheck`. **Maven groupId는 동일하게 `org.owasp` 유지** — central.sonatype.com에서 `org.owasp:dependency-check-maven:12.2.2` latest로 확인됨(다른 groupId 아님).
  - 현재 pom.xml에 OWASP DC plugin 없음(검색 0건).
- 출처:
  - https://central.sonatype.com/artifact/org.owasp/dependency-check-maven/versions — 12.2.2 latest
  - https://github.com/dependency-check/DependencyCheck/releases — v12.2.2 GA
  - https://github.com/jeremylong/DependencyCheck — 이관 안내(2025-09-27 아카이브)
- 신뢰도: 확인됨 (Maven Central 1차 + GitHub releases)

### 포인트 3-B: 오프라인/NVD 무의존 설정 방법
- 요약(공식 configuration 문서 발췌 기준 — 전수 옵션 목록 아님):
  - `autoUpdate` (기본 true): **false** 설정 시 NVD 자동 업데이트 비활성화 — 오프라인 핵심
  - `dataDirectory` (기본 `~/.m2/.../dependency-check-data/`): 사전 다운로드한 로컬 NVD 캐시 위치 지정
  - `nvdApiKey` (선택): **없어도 동작 가능**. 단 키 없으면 API 요청 간격이 8000ms로 늘어남(온라인 업데이트 시에만 영향, autoUpdate=false면 무관)
  - `nvdDatafeedUrl`: 내부 NVD 미러 서버 지정(에어갭 지원). 별도 인프라 필요 → 상세는 범위 밖
  - `failBuildOnCVSS` (기본 11=사실상 비활성, 0-10 범위): 특정 CVSS 이상 시 빌드 실패
  - `skipProvidedScope` (기본 false): true면 provided scope 의존성 분석 생략
  - 명시적 `--offline` 플래그는 **없음**. 오프라인 패턴 = `autoUpdate=false` + 사전채워진 `dataDirectory`. 한번 온라인에서 데이터 받아두면 이후 오프라인 재사용 가능.
- pom plugin 설정 예시(오프라인 친화, advisor가 검토할 후보 스니펫):
  ```xml
  <plugin>
    <groupId>org.owasp</groupId>
    <artifactId>dependency-check-maven</artifactId>
    <version>12.2.2</version>
    <configuration>
      <autoUpdate>false</autoUpdate>
      <dataDirectory>${user.home}/.m2/repository/org/owasp/dependency-check-data</dataDirectory>
      <failBuildOnCVSS>7</failBuildOnCVSS>
      <skipProvidedScope>true</skipProvidedScope>
    </configuration>
  </plugin>
  ```
- 출처: https://jeremylong.github.io/DependencyCheck/dependency-check-maven/configuration.html
- 신뢰도: 확인됨 (옵션 존재·역할). 단 `failBuildOnCVSS=7`/`skipProvidedScope=true`의 구체 값 선택은 advisor 설계 결정(조사 산출 아님). 옵션 목록은 "공식 문서 발췌"이지 "전수 열거"가 아님.

### 포인트 4: 현 설정파일 정확 라인 (코드 사실)

#### 4-A: pom.xml 구조 (`/Users/wemadeplay/workspace/stz/bibimbap/pom.xml`)
- `spring-boot.version` property: **라인 29**, 값 `3.5.14-SNAPSHOT`
- `<repositories>` 블록: **라인 210~219** — spring-snapshots 1개(`https://repo.spring.io/snapshot`, releases disabled)
- `<pluginRepositories>` 블록: **라인 220~229** — spring-snapshots 1개(동일 URL, releases disabled)
- `<build><pluginManagement><plugins>`: 라인 100~155 — 9개 플러그인(clean/compiler/deploy/failsafe/install/resources/surefire/war/spring-boot)
- `<build><plugins>` (실행): **라인 157~208** — spring-boot-maven-plugin(157~169) + maven-compiler-plugin(170~207) 2개만. **OWASP plugin 추가 위치 = 이 블록 내**.
- profiles 빌드: dev(256~266), live(293~302)에 각각 spring-boot-maven-plugin profile용 추가
- 신뢰도: 확인됨

#### 4-B: application.properties (`src/main/resources/application.properties`, 31라인)
- `spring.profiles.active`: **라인 1** — `@app.profile@` (Maven 필터링 치환)
- 세션 쿠키 설정(`server.servlet.session.cookie.*`): **0건 (없음)**
- `logging.level.org.apache.ibatis`: **라인 30** — `TRACE`
- multipart: **라인 15~17** — `spring.servlet.multipart.max-file-size=1GB`, `max-request-size=1GB`, `server.tomcat.max-http-form-post-size=1GB`
- (참고) 라인 21에 `spring.config.import`로 profile별 db.properties 로드
- 신뢰도: 확인됨

#### 4-C: profile별 properties 파일 존재 여부
- `application-dev.properties` / `application-live.properties` 형식 파일: **존재하지 않음**
- 대신 디렉토리 기반:
  - `dev/db.properties` (존재, 8라인) + `dev/db.properties.example`
  - `live/db.properties.example`만 존재 — **`live/db.properties`는 없음**
- `dev/db.properties` 내용: postgresql driver, url(localhost:5433/bibimbap?currentSchema=dev), username=bibimbap, password=change_me_local_dev, app.upload.game-storage-path, app.webgl.asset-origin(빈값), app.webgl.frame-ancestors=self
- 사실: B4가 "application-dev.properties/application-live.properties 신규/수정 대상"으로 가정한다면, **현재 그런 파일은 없고** profile 설정은 `dev/`·`live/` 디렉토리 + `spring.config.import` 패턴으로 관리됨. → 가정과 현행 구조 불일치(아래 미해결 참조)
- 신뢰도: 확인됨

---

## 종합 판단

### 삭제 안전성 판정 (B2)
| 대상 | 외부 참조 | 삭제 안전성 |
|---|---|---|
| `abstracts/` 패키지 4파일 | 패키지 외부 0건 (상속 구체클래스 0, import 0) | **삭제 안전** (컴파일·런타임 파손 없음) |
| `GameCatalog.java` | GameController.gameDetail()만 참조 | **GameController 동시수정 필요** — fallback 로직(라인 150~172) 제거/404대체 후라야 안전 |
| `header.jspf` | include 0건 | **삭제 안전** (어떤 JSP도 참조 안 함, 전부 /WEB-INF/views/header.jsp 사용) |

### 확정 버전값 (B4)
| 항목 | 확정값 | 신뢰도 |
|---|---|---|
| Spring Boot 3.5.x 최신 GA | **3.5.16** | 확인됨 |
| OWASP dependency-check-maven 최신 GA | **12.2.2** (groupId `org.owasp` 유지) | 확인됨 |

전 항목 1차 출처(spring.io / Maven Central / 프로젝트 코드 직접읽기)로 확인됨 → `source_confidence: high`. 차단 출처 fallback 없음.

## 미해결
- **B4 가정 vs 현행 구조 불일치**: 작업트랙 B4 설명이 "application-dev.properties / application-live.properties 신규/수정 대상"이라 가정하나, 현 프로젝트는 그런 파일이 없고 `dev/db.properties`·`live/db.properties`(+ `spring.config.import`) 패턴을 쓴다. 설정 추가를 어느 파일에 넣을지는 design-advisor가 현행 패턴 기준으로 재결정해야 함. (조사로 사실 확인 완료, 결정은 다운스트림)
- `live/db.properties` 부재 — live profile 활성 시 어디서 DB 설정을 받는지(배포 시 주입 등)는 이번 조사 범위 밖.
- GameCatalog.java의 배열 실제 값(NAMES/CREATORS 등 fallback이 제공하던 게임 목록)은 미조회 — 404 전환 시 사라지는 정적 게임 목록의 내용·개수가 필요하면 별도 조사.
- `nvdDatafeedUrl` 내부 미러 상세 구성은 별도 인프라 필요로 범위 밖.
