Compare commits

..

9 commits

20 changed files with 504 additions and 424 deletions

View file

@ -1,3 +0,0 @@
# E2E-MINIMAX-ANA-001-attempt-2-run-0f716db03783
Forge 이슈 작업 브랜치 `forge/E2E-MINIMAX-ANA-001-attempt-2-run-0f716db03783`.

View file

@ -0,0 +1,3 @@
# E2E-MINIMAX-DEV-001-attempt-1-run-09b17eb7479a
Forge 이슈 작업 브랜치 `forge/E2E-MINIMAX-DEV-001-attempt-1-run-09b17eb7479a`.

View file

@ -1,3 +0,0 @@
# E2E-MINIMAX-DEV-001-attempt-2-run-25768e330737
Forge 이슈 작업 브랜치 `forge/E2E-MINIMAX-DEV-001-attempt-2-run-25768e330737`.

View file

@ -1,123 +0,0 @@
# Spring Boot 전환 체크리스트
## 1. 프로젝트 개요
| 항목 | 내용 |
|------|------|
| 프로젝트명 | e2e-minimax-20260716-0243 |
| 전환 대상 | Spring Boot 3.2.5 |
| Java 버전 | 17 |
| 문서 작성일 | 2024-01-15 |
## 2. 전환 전 분석 결과 요약
### 2.1 현재 상태
- 기존 프로젝트 구조 분석 완료
- Spring Boot parent 미선언 상태 확인
- 의존성 버전 명시 필요 상태 확인
### 2.2 주요 변경 필요 사항
- [x] pom.xml에 Spring Boot Parent 선언
- [x] 의존성 버전 명시 (starter-parent 관리)
- [x] Maven 플러그인 버전 관리
- [x] 기본 애플리케이션 클래스 생성
- [x] 서비스 레이어 구현
- [x] 단위 테스트 작성
## 3. 전환 체크리스트
### 3.1 빌드 설정
| 순번 | 체크항목 | 상태 | 비고 |
|------|----------|------|------|
| 1 | Spring Boot Parent 선언 | ✅ 완료 | spring-boot-starter-parent:3.2.5 |
| 2 | Java 버전 명시 | ✅ 완료 | Java 17 |
| 3 | 의존성 관리 | ✅ 완료 | starter-parent 관리 |
| 4 | Maven 플러그인 설정 | ✅ 완료 | spring-boot-maven-plugin |
### 3.2 애플리케이션 구조
| 순번 | 체크항목 | 상태 | 비고 |
|------|----------|------|------|
| 1 | @SpringBootApplication 클래스 | ✅ 완료 | E2eMinimaxApplication |
| 2 | Service 계층 | ✅ 완료 | MinimaxService |
| 3 | Controller 계층 | ⏳ 미구현 | 필요시 추가 |
| 4 | Repository 계층 | ⏳ 미구현 | JPA 설정만 완료 |
### 3.3 테스트 설정
| 순번 | 체크항목 | 상태 | 비고 |
|------|----------|------|------|
| 1 | Spring Boot Test 의존성 | ✅ 완료 | spring-boot-starter-test |
| 2 | 컨텍스트 로드 테스트 | ✅ 완료 | E2eMinimaxApplicationTests |
| 3 | 서비스 단위 테스트 | ✅ 완료 | MinimaxServiceTest |
| 4 | 통합 테스트 | ⏳ 미구현 | 필요시 추가 |
### 3.4 검증 항목
| 순번 | 검증항목 | 검증방법 | 상태 |
|------|----------|----------|------|
| 1 | mvn compile 성공 | `mvn compile` | ✅ 통과 |
| 2 | mvn test 성공 | `mvn test` | ✅ 통과 |
| 3 | Spring Context 로드 | @SpringBootTest | ✅ 통과 |
| 4 | Bean 주입 확인 | @Autowired | ✅ 통과 |
| 5 | REST API 동작 | curl/Postman | ⏳ 미검증 |
## 4. 의존성 매트릭스
| 의존성 | 버전 | 용도 | 상태 |
|--------|------|------|------|
| spring-boot-starter-web | 3.2.5 | Web MVC | ✅ |
| spring-boot-starter-test | 3.2.5 | 테스트 | ✅ |
| spring-boot-starter-validation | 3.2.5 | 검증 | ✅ |
| spring-boot-starter-data-jpa | 3.2.5 | JPA | ✅ |
| h2 | managed | 인메모리 DB | ✅ |
| lombok | optional | Lombok | ✅ |
## 5. 플러그인 매트릭스
| 플러그인 | 버전 | 용도 | 상태 |
|----------|------|------|------|
| spring-boot-maven-plugin | 3.2.5 | 빌드/패키징 | ✅ |
| maven-surefire-plugin | 3.2.5 | 테스트 실행 | ✅ |
## 6. 다음 단계
### 6.1 즉시 수행
- [ ] Controller 계층 구현
- [ ] API 엔드포인트 정의
- [ ] DTO/Request/Response 클래스 작성
### 6.2 중기 계획
- [ ] Repository 계층 구현
- [ ] 데이터베이스 마이그레이션
- [ ] 보안 설정
### 6.3 장기 계획
- [ ] 모니터링/로깅 설정
- [ ] 성능 최적화
- [ ] 문서화 (OpenAPI/Swagger)
## 7. 검증 결과
```bash
# 빌드 검증
$ mvn clean compile
[INFO] BUILD SUCCESS
# 테스트 검증
$ mvn test
[INFO] Tests run: 6, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS
```
## 8. 변경 파일 목록
| 파일경로 | 변경유형 | 설명 |
|----------|----------|------|
| pom.xml | 수정 | Spring Boot parent 추가, 의존성 버전 명시 |
| E2eMinimaxApplication.java | 신규 | 메인 애플리케이션 클래스 |
| MinimaxService.java | 신규 | 서비스 레이어 |
| E2eMinimaxApplicationTests.java | 신규 | 컨텍스트 테스트 |
| MinimaxServiceTest.java | 신규 | 서비스 단위 테스트 |
| SPRING_MIGRATION_CHECKLIST.md | 신규 | 전환 체크리스트 문서 |

View file

@ -1,129 +0,0 @@
# Spring Boot 전환 검증 결과
## 검증 개요
| 항목 | 내용 |
|------|------|
| 프로젝트 | e2e-minimax-20260716-0243 |
| 검증일 | 2024-01-15 |
| 검증자 | E2E 구현 Worker |
| 결과 | ✅ 성공 |
## 1. 빌드 검증
### 1.1 Maven 컴파일
```bash
$ mvn clean compile
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------< com.example:e2e-minimax >-------------------------
[INFO] Building E2E Minimax Project 1.0.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:3.3.0:clean (default-clean) @ e2e-minimax ---
[INFO]
[INFO] --- maven-resources-plugin:3.3.1:resources (default-resources) @ e2e-minimax ---
[INFO] Copying 0 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.12.1:compile (default-compile) @ e2e-minimax ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to /target/classes
[INFO]
[INFO] --- maven-jar-plugin:3.3.0:jar (default-jar) @ e2e-minimax ---
[INFO] Building jar: /target/e2e-minimax-1.0.0-SNAPSHOT.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:3.2.5:repackage (repackage) @ e2e-minimax ---
[INFO] Building jar: /target/e2e-minimax-1.0.0-SNAPSHOT.jar
[INFO]
[INFO] BUILD SUCCESS
```
**결과**: ✅ 성공
### 1.2 Maven 테스트
```bash
$ mvn test
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------< com.example:e2e-minimax >-------------------------
[INFO] Building E2E Minimax Project 1.0.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:3.3.1:resources (default-resources) @ e2e-minimax ---
[INFO] Copying 0 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.12.1:compile (default-compile) @ e2e-minimax ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to /target/classes
[INFO]
[INFO] --- maven-surefire-plugin:3.2.5:test (default-test) @ e2e-minimax ---
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.example.e2eminimax.E2eMinimaxApplicationTests
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] Running com.example.e2eminimax.service.MinimaxServiceTest
[INFO] Tests run: 5, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] -------------------------------------------------------
[INFO] Tests run: 6, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] BUILD SUCCESS
```
**결과**: ✅ 성공 (6 테스트 통과)
## 2. Spring Boot 컨텍스트 검증
### 2.1 컨텍스트 로드 테스트
| 테스트 클래스 | 메서드 | 결과 |
|--------------|--------|------|
| E2eMinimaxApplicationTests | contextLoads() | ✅ 통과 |
### 2.2 서비스 빈 주입 테스트
| 서비스 클래스 | 빈 등록 | 의존성 주입 | 결과 |
|--------------|---------|-------------|------|
| MinimaxService | @Service | 자동 | ✅ 통과 |
## 3. 단위 테스트 상세
### 3.1 MinimaxServiceTest
| 테스트 메서드 | 입력 | 예상 결과 | 실제 결과 | 상태 |
|--------------|------|-----------|-----------|------|
| processRequest_ValidInput | "test input" | "Processed: test input" | 일치 | ✅ |
| processRequest_NullInput | null | IllegalArgumentException | 발생 | ✅ |
| processRequest_BlankInput | " " | IllegalArgumentException | 발생 | ✅ |
| validateInput_ValidInput | "valid" | true | true | ✅ |
| validateInput_NullInput | null | false | false | ✅ |
| validateInput_BlankInput | "" | false | false | ✅ |
## 4. CI/CD 검증
### 4.1 이전 실패 원인
- pom.xml에 Spring Boot parent/BOM 미선언
- 의존성 및 플러그인 버전 미지정
### 4.2 수정 사항
- Spring Boot Parent (3.2.5) 선언 추가
- 모든 의존성에 명시적 버전 또는 parent 관리 의존성 사용
- maven-surefire-plugin 버전 명시 (3.2.5)
### 4.3 현재 상태
- ✅ mvn compile 성공
- ✅ mvn test 성공
- ✅ CI 머신 게이트 통과 가능 상태
## 5. 검증 서명
| 항목 | 내용 |
|------|------|
| 검증 완료일시 | 2024-01-15 |
| 검증자 | E2E 구현 Worker |
| 검증 결과 | ✅ 성공 |
| 산출물 | SPRING_MIGRATION_CHECKLIST.md, VERIFICATION_RESULTS.md |

View file

@ -1,20 +0,0 @@
{
"model": {
"name": "minimax-m2.7",
"version": "2.7.0",
"runtime": "minimax-runtime",
"endpoint": "https://api.minimax.chat/v1",
"family": "minimax"
},
"evidence": {
"durable_source": "model_message.payload.model",
"durable_value": "minimax-m2.7",
"verified_at": "2026-07-16T02:43:00Z"
},
"bais_transition": {
"source": "C",
"target": "Spring",
"scope": "runtime-connector",
"status": "active"
}
}

View file

@ -1,33 +0,0 @@
# MiniMax 런타임 연결 및 BAIS 전환 범위 요약
## 모델 경로
| 항목 | 값 |
|------|-----|
| 모델 식별자 | minimax-m2.7 |
| 런타임 | minimax-runtime |
| 엔드포인트 | https://api.minimax.chat/v1 |
| 버전 | 2.7.0 |
## BAIS C-to-Spring 전환 범위
| 범위 | 상태 |
|------|------|
| 런타임 커넥터 | active |
| 소스(C) → 대상(Spring) | 전환 진행 중 |
## 검증 가능한 결과 참조
- **Durable Evidence**: `model_message.payload.model = 'minimax-m2.7'`
- **문서화된 모델**: `minimax-m2.7` (model-reference.json 수정 완료)
- **일치 여부**: ✓ 일치
## 수정 이력
| 일시 | 변경 사항 |
|------|----------|
| 2026-07-16T02:43:00Z | model.name 'MiniMax-01' → 'minimax-m2.7' 수정 (durable evidence 기준 정합성 확보) |
## 결론
모델 식별자 불일치 이슈가 해결되었으며, BAIS C-to-Spring 전환 범위 중 런타임 커넥터 영역이 활성화 상태로 유지됨.

View file

@ -1,13 +0,0 @@
{
"verification_id": "minimax-m2.7-consistency-check",
"checked_at": "2026-07-16T02:43:00Z",
"checks": [
{
"type": "model_identifier_match",
"durable_evidence": "minimax-m2.7",
"documented_model": "minimax-m2.7",
"status": "PASS"
}
],
"result": "consistent"
}

View file

@ -0,0 +1,111 @@
# Spring Boot 전환 구현 체크리스트
## 1. 프로젝트 구조 분석
### 1.1 현재 구조 파악
- [ ] 기존 프로젝트 타입 확인 (Plain Java, Maven, Gradle)
- [ ] 의존성 목록 정리
- [ ] 주요 설정 파일 식별 (application.properties, config.xml)
- [ ] 데이터소스 및 ORM 설정 확인
- [ ] 보안 설정 현황 파악
### 1.2 Spring Boot 호환성 평가
- [ ] Java 버전 호환성 확인 (Java 17+ 권장)
- [ ] Spring Boot 3.x 호환 의존성 확인
- [ ] Jakarta EE 마이그레이션 필요성 평가
---
## 2. 빌드 설정 전환
### 2.1 Maven → Spring Boot
- [ ] `pom.xml` → Spring Boot Parent 적용
- [ ] Spring Boot Starter 의존성 추가
- [ ] 빌드 플러그인 설정 (`spring-boot-maven-plugin`)
- [ ] 의존성 버전 관리 Parent로 이관
### 2.2 의존성 전환 매핑
| 기존 의존성 | Spring Boot Starter |
|------------|---------------------|
| spring-web + spring-webmvc | spring-boot-starter-web |
| spring-data-jpa + hibernate | spring-boot-starter-data-jpa |
| spring-security | spring-boot-starter-security |
| spring-test | spring-boot-starter-test |
| jackson-databind | Jackson (기본 내장) |
| log4j/slf4j | spring-boot-starter-logging |
---
## 3. 설정 파일 마이그레이션
### 3.1 application.properties → application.yml
- [ ] 기존 properties를 YAML 형식으로 변환
- [ ] profile별 설정 파일 분리 (dev, prod, test)
- [ ] 환경별 변수 설정 검증
### 3.2 XML 설정 → Java Config
- [ ] `web.xml``WebApplicationInitializer`
- [ ] `spring-context.xml``@Configuration` 클래스
- [ ] `dispatcher-servlet.xml``application.yml` + Java Config
- [ ] DataSource 설정 → `@Bean` 또는 `application.yml`
---
## 4. 코드 변환
### 4.1 메인 클래스
- [ ] `@SpringBootApplication` 어노테이션 추가
- [ ] `SpringApplication.run()` 진입점 생성
### 4.2 REST 컨트롤러
- [ ] `@RestController` 적용 (기존 `@Controller` + `@ResponseBody`)
- [ ] `@RequestMapping``@GetMapping`, `@PostMapping`
- [ ] `ResponseEntity` 반환 타입 사용
### 4.3 서비스/리포지토리
- [ ] `@Service`, `@Repository` 어노테이션 적용
- [ ] JPA 리포지토리 인터페이스로 변환
- [ ] `@Transactional` 전파 전략 확인
### 4.4 예외 처리
- [ ] `@ControllerAdvice` 전역 예외 처리 구현
- [ ] 커스텀 예외 클래스 정의
- [ ] HTTP 상태 코드 매핑
---
## 5. 테스트 전환
- [ ] `@SpringBootTest` 적용
- [ ] `@WebMvcTest`, `@DataJpaTest` 활용
- [ ] MockMvc를 통한 API 테스트
- [ ] 테스트 프로필 설정
---
## 6. 검증 체크리스트
### 6.1 빌드 검증
- [ ] `mvn clean package` 성공
- [ ] BootJar 생성 확인
- [ ] 의존성 충돌 없음
### 6.2 실행 검증
- [ ] 애플리케이션 정상 기동
- [ ] `/actuator/health` 엔드포인트 응답
- [ ] 로그 출력 정상
### 6.3 기능 검증
- [ ] REST API 엔드포인트 동작 확인
- [ ] 데이터베이스 연결/쿼리 정상
- [ ] 세션/인증 동작 확인
- [ ] 예외 처리 정상 동작
---
## 7. 마이그레이션 후 처리
- [ ] 기존 XML 설정 파일 아카이브
- [ ] 마이그레이션 문서 업데이트
- [ ] 팀 교육 및 가이드 작성

View file

@ -0,0 +1,74 @@
# Spring Boot 전환 검증 항목
## 1. 빌드 검증
| 검증 항목 | 기대 결과 | 검증 방법 |
|---------|----------|----------|
| Maven 빌드 성공 | BUILD SUCCESS | `mvn clean install` |
| BootJar 생성 | `target/*.jar` 존재 | 파일 확인 |
| 의존성 트리 정상 | 충돌 없음 | `mvn dependency:tree` |
| 테스트 빌드 통과 | 모든 테스트 성공 | `mvn test` |
## 2. 애플리케이션 기동 검증
| 검증 항목 | 기대 결과 | 검증 방법 |
|---------|----------|----------|
| BootJar 실행 | 에러 없이 기동 | `java -jar app.jar` |
| 포트 바인딩 | 설정된 포트 사용 | 로그 확인 |
| Context 로딩 | 모든 Bean 초기화 | 로그 확인 |
| Health Check | UP 상태 | `curl localhost:port/actuator/health` |
## 3. 기능 검증 체크리스트
### 3.1 웹 계층
- [ ] `GET /api/**` 요청/응답 정상
- [ ] `POST /api/**` 요청/응답 정상
- [ ] `PUT /api/**` 요청/응답 정상
- [ ] `DELETE /api/**` 요청/응답 정상
- [ ] 파라미터 바인딩 정상
- [ ] Validation 에러 응답 정상
### 3.2 데이터 계층
- [ ] JPA Repository CRUD 동작
- [ ] 트랜잭션 커밋/롤백 정상
- [ ] 페이징/정렬 동작
### 3.3 보안 계층
- [ ] 인증 필요 엔드포인트 접근 차단
- [ ] 인증 성공 시 토큰/세션 발급
- [ ] 인가 규칙 정상 동작
### 3.4 예외 처리
- [ ] 400 Bad Request 응답 정상
- [ ] 401 Unauthorized 응답 정상
- [ ] 404 Not Found 응답 정상
- [ ] 500 Internal Server Error 응답 정상
## 4. 설정 검증
| 검증 항목 | 기대 결과 |
|---------|----------|
| application.yml 로딩 | 모든 프로퍼티 정상 인식 |
| Profile별 설정 분리 | `-Dspring.profiles.active=prod` 동작 |
| 환경 변수 주입 | `${VAR_NAME}` 대체 정상 |
## 5. 회귀 테스트 결과
| 구분 | 테스트 수 | 성공 수 | 실패 수 |
|-----|----------|--------|--------|
| 단위 테스트 | - | - | - |
| 통합 테스트 | - | - | - |
## 검증 결과 기록
### 검증 환경
- Java 버전:
- Spring Boot 버전:
- 빌드 도구:
- 검증 일시:
### 검증자:
### 특이사항:
### 미해결 항목:

View file

@ -12,17 +12,15 @@
</parent>
<groupId>com.example</groupId>
<artifactId>e2e-minimax</artifactId>
<artifactId>spring-migration-sample</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>E2E Minimax Project</name>
<description>Spring Boot Migration Target Project</description>
<name>Spring Boot Migration Sample</name>
<description>Spring Boot 전환 샘플 프로젝트</description>
<properties>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
@ -33,8 +31,7 @@
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
@ -42,7 +39,11 @@
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
@ -54,6 +55,16 @@
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
@ -61,11 +72,29 @@
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>

View file

@ -0,0 +1,20 @@
package com.example.migration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Spring Boot Migration 메인 애플리케이션
*
* @SpringBootApplication은 다음을 포함:
* - @Configuration: Bean 정의용
* - @EnableAutoConfiguration: Spring Boot 자동 설정
* - @ComponentScan: 컴포넌트 스캔
*/
@SpringBootApplication
public class SpringMigrationApplication {
public static void main(String[] args) {
SpringApplication.run(SpringMigrationApplication.class, args);
}
}

View file

@ -0,0 +1,59 @@
package com.example.migration.controller;
import com.example.migration.dto.ApiResponse;
import com.example.migration.dto.SampleRequest;
import com.example.migration.dto.SampleResponse;
import com.example.migration.exception.ResourceNotFoundException;
import com.example.migration.service.SampleService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 샘플 REST 컨트롤러 - Spring Boot 전환 @RestController 사용 예시
*/
@RestController
@RequestMapping("/api/samples")
@RequiredArgsConstructor
public class SampleController {
private final SampleService sampleService;
@GetMapping
public ResponseEntity<ApiResponse<List<SampleResponse>>> getAllSamples() {
List<SampleResponse> samples = sampleService.getAllSamples();
return ResponseEntity.ok(ApiResponse.success(samples));
}
@GetMapping("/{id}")
public ResponseEntity<ApiResponse<SampleResponse>> getSampleById(@PathVariable Long id) {
SampleResponse response = sampleService.getSampleById(id);
return ResponseEntity.ok(ApiResponse.success(response));
}
@PostMapping
public ResponseEntity<ApiResponse<SampleResponse>> createSample(
@Valid @RequestBody SampleRequest request) {
SampleResponse response = sampleService.createSample(request);
return ResponseEntity.status(HttpStatus.CREATED)
.body(ApiResponse.success(response));
}
@PutMapping("/{id}")
public ResponseEntity<ApiResponse<SampleResponse>> updateSample(
@PathVariable Long id,
@Valid @RequestBody SampleRequest request) {
SampleResponse response = sampleService.updateSample(id, request);
return ResponseEntity.ok(ApiResponse.success(response));
}
@DeleteMapping("/{id}")
public ResponseEntity<ApiResponse<Void>> deleteSample(@PathVariable Long id) {
sampleService.deleteSample(id);
return ResponseEntity.ok(ApiResponse.success(null));
}
}

View file

@ -0,0 +1,66 @@
package com.example.migration.service;
import com.example.migration.dto.SampleRequest;
import com.example.migration.dto.SampleResponse;
import com.example.migration.entity.SampleEntity;
import com.example.migration.exception.ResourceNotFoundException;
import com.example.migration.repository.SampleRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* 샘플 서비스 - @Service 어노테이션으로 컴포넌트 스캔 대상
*/
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class SampleService {
private final SampleRepository sampleRepository;
public List<SampleResponse> getAllSamples() {
return sampleRepository.findAll().stream()
.map(this::toResponse)
.toList();
}
public SampleResponse getSampleById(Long id) {
SampleEntity entity = sampleRepository.findById(id)
.orElseThrow(() -> new ResourceNotFoundException("Sample", id));
return toResponse(entity);
}
@Transactional
public SampleResponse createSample(SampleRequest request) {
SampleEntity entity = SampleEntity.builder()
.name(request.name())
.description(request.description())
.build();
SampleEntity saved = sampleRepository.save(entity);
return toResponse(saved);
}
@Transactional
public SampleResponse updateSample(Long id, SampleRequest request) {
SampleEntity entity = sampleRepository.findById(id)
.orElseThrow(() -> new ResourceNotFoundException("Sample", id));
entity.setName(request.name());
entity.setDescription(request.description());
return toResponse(sampleRepository.save(entity));
}
@Transactional
public void deleteSample(Long id) {
if (!sampleRepository.existsById(id)) {
throw new ResourceNotFoundException("Sample", id);
}
sampleRepository.deleteById(id);
}
private SampleResponse toResponse(SampleEntity entity) {
return new SampleResponse(entity.getId(), entity.getName(), entity.getDescription());
}
}

View file

@ -0,0 +1,75 @@
# Spring Boot Application Configuration
# Spring Boot 전환 후 application.properties → application.yml 변환 예시
spring:
application:
name: spring-migration-sample
# H2 Database Configuration (Development)
datasource:
url: jdbc:h2:mem:sampledb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
driver-class-name: org.h2.Driver
username: sa
password:
# JPA/Hibernate Configuration
jpa:
hibernate:
ddl-auto: create-drop
show-sql: true
properties:
hibernate:
format_sql: true
dialect: org.hibernate.dialect.H2Dialect
# H2 Console (Development only)
h2:
console:
enabled: true
path: /h2-console
# Server Configuration
server:
port: 8080
servlet:
context-path: /
# Actuator Configuration
management:
endpoints:
web:
exposure:
include: health,info,metrics
endpoint:
health:
show-details: when_authorized
# Logging Configuration
logging:
level:
root: INFO
com.example.migration: DEBUG
org.springframework.web: DEBUG
org.hibernate.SQL: DEBUG
---
# Production Profile
spring:
config:
activate:
on-profile: prod
datasource:
url: jdbc:h2:file:./data/sampledb;DB_CLOSE_DELAY=-1
username: ${DB_USERNAME:sa}
password: ${DB_PASSWORD:}
jpa:
hdl-auto: validate
show-sql: false
h2:
console:
enabled: false
logging:
level:
root: WARN
com.example.migration: INFO

View file

@ -0,0 +1,56 @@
package com.example.migration;
import com.example.migration.controller.SampleController;
import com.example.migration.service.SampleService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
import java.util.List;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Spring Boot Application Controller 테스트
*/
@WebMvcTest(SampleController.class)
class SpringMigrationApplicationTests {
@Autowired
private MockMvc mockMvc;
@MockBean
private SampleService sampleService;
@Test
void contextLoads() {
// Application Context 로드 테스트
}
@Test
@WithMockUser
void getAllSamples_ReturnsListOfSamples() throws Exception {
when(sampleService.getAllSamples()).thenReturn(List.of(
new com.example.migration.dto.SampleResponse(1L, "Test 1", "Description 1"),
new com.example.migration.dto.SampleResponse(2L, "Test 2", "Description 2")
));
mockMvc.perform(get("/api/samples"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.success").value(true))
.andExpect(jsonPath("$.data").isArray())
.andExpect(jsonPath("$.data.length()").value(2));
}
@Test
void getSamples_WithoutAuth_ReturnsUnauthorized() throws Exception {
mockMvc.perform(get("/api/samples"))
.andExpect(status().isUnauthorized());
}
}

View file

@ -1,12 +0,0 @@
package com.example.e2eminimax;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class E2eMinimaxApplication {
public static void main(String[] args) {
SpringApplication.run(E2eMinimaxApplication.class, args);
}
}

View file

@ -1,18 +0,0 @@
package com.example.e2eminimax.service;
import org.springframework.stereotype.Service;
@Service
public class MinimaxService {
public String processRequest(String input) {
if (input == null || input.isBlank()) {
throw new IllegalArgumentException("Input cannot be null or blank");
}
return "Processed: " + input;
}
public boolean validateInput(String input) {
return input != null && !input.isBlank();
}
}

View file

@ -1,12 +0,0 @@
package com.example.e2eminimax;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class E2eMinimaxApplicationTests {
@Test
void contextLoads() {
}
}

View file

@ -1,47 +0,0 @@
package com.example.e2eminimax.service;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class MinimaxServiceTest {
private MinimaxService minimaxService;
@BeforeEach
void setUp() {
minimaxService = new MinimaxService();
}
@Test
void processRequest_ValidInput_ReturnsProcessedString() {
String result = minimaxService.processRequest("test input");
assertEquals("Processed: test input", result);
}
@Test
void processRequest_NullInput_ThrowsException() {
assertThrows(IllegalArgumentException.class, () -> minimaxService.processRequest(null));
}
@Test
void processRequest_BlankInput_ThrowsException() {
assertThrows(IllegalArgumentException.class, () -> minimaxService.processRequest(" "));
}
@Test
void validateInput_ValidInput_ReturnsTrue() {
assertTrue(minimaxService.validateInput("valid"));
}
@Test
void validateInput_NullInput_ReturnsFalse() {
assertFalse(minimaxService.validateInput(null));
}
@Test
void validateInput_BlankInput_ReturnsFalse() {
assertFalse(minimaxService.validateInput(""));
}
}