diff --git a/.forge/role-aa-001-attempt-1-run-f88341c79b7c.md b/.forge/role-aa-001-attempt-1-run-f88341c79b7c.md new file mode 100644 index 0000000..9a0908d --- /dev/null +++ b/.forge/role-aa-001-attempt-1-run-f88341c79b7c.md @@ -0,0 +1,3 @@ +# role-aa-001-attempt-1-run-f88341c79b7c + +Forge 이슈 작업 브랜치 `forge/role-aa-001-attempt-1-run-f88341c79b7c`. diff --git a/.forge/role-pm-001-attempt-1-run-0d2fe2a0ad41.md b/.forge/role-pm-001-attempt-1-run-0d2fe2a0ad41.md new file mode 100644 index 0000000..ab047bb --- /dev/null +++ b/.forge/role-pm-001-attempt-1-run-0d2fe2a0ad41.md @@ -0,0 +1,3 @@ +# role-pm-001-attempt-1-run-0d2fe2a0ad41 + +Forge 이슈 작업 브랜치 `forge/role-pm-001-attempt-1-run-0d2fe2a0ad41`. diff --git a/.forge/role-reviewer-001-attempt-1-run-055bed2e6c12.md b/.forge/role-reviewer-001-attempt-1-run-055bed2e6c12.md deleted file mode 100644 index a3ebd9c..0000000 --- a/.forge/role-reviewer-001-attempt-1-run-055bed2e6c12.md +++ /dev/null @@ -1,3 +0,0 @@ -# role-reviewer-001-attempt-1-run-055bed2e6c12 - -Forge 이슈 작업 브랜치 `forge/role-reviewer-001-attempt-1-run-055bed2e6c12`. diff --git a/.forge/role-ta-001-attempt-1-run-9fa6a6b8d5c6.md b/.forge/role-ta-001-attempt-1-run-9fa6a6b8d5c6.md new file mode 100644 index 0000000..41d89a8 --- /dev/null +++ b/.forge/role-ta-001-attempt-1-run-9fa6a6b8d5c6.md @@ -0,0 +1,3 @@ +# role-ta-001-attempt-1-run-9fa6a6b8d5c6 + +Forge 이슈 작업 브랜치 `forge/role-ta-001-attempt-1-run-9fa6a6b8d5c6`. diff --git a/docs/OPERATIONS_HANDOVER.md b/docs/OPERATIONS_HANDOVER.md new file mode 100644 index 0000000..9d680e2 --- /dev/null +++ b/docs/OPERATIONS_HANDOVER.md @@ -0,0 +1,115 @@ +# 런타임 역할 검증 프로젝트 - 운영 인수인계 문서 + +**프로젝트**: runtime-role-smoke-202607140500 +**작성일**: 2025-07-14 +**버전**: 1.0 + +--- + +## 1. 완료 기준 (Definition of Done) + +| 항목 | 기준 | 검증 방법 | +|------|------|----------| +| 역할별 에이전트 동작 | 각 역할(PM, Dev, QA, Security)이 정의된 작업을 자동 수행 | 스모크 테스트 통과 | +| 태스크 완료율 | 할당된 태스크 100% 완료 | 태스크 트래커 기준 | +| 문서 완결성 | README, API 문서, 운영 가이드 포함 | 문서 체크리스트 | +| 테스트 커버리지 | 핵심 기능 80% 이상 | 테스트 보고서 | +| 보안 검증 | 취약점 스캔 통과 (Critical/High 없음) | 보안 스캔 결과 | + +--- + +## 2. 역할별 책임 (Role Responsibilities) + +### 2.1 PM (Project Manager) +- **주요 책임**: 프로젝트 범위 관리, 일정 조율, 이해관계자 커뮤니케이션 +- **핵심 태스크**: + - 백로그 관리 및 우선순위 결정 + - 스프린트 계획 및 리뷰 진행 + - 리스크 식별 및 완화措施 수립 +- **인수인계 항목**: + - [ ] 프로젝트 로드맵 문서 + - [ ] 백로그 및 태스크 현황 + - [ ] 이해관계자 연락처 목록 + - [ ] 의사결정 로그 + +### 2.2 Dev (Developer) +- **주요 책임**: 기능 구현, 코드 품질 관리, 기술 아키텍처 결정 +- **핵심 태스크**: + - 에이전트 런타임 핵심 로직 구현 + - CI/CD 파이프라인 구축 + - 코드 리뷰 및 머지 관리 +- **인수인계 항목**: + - [ ] 소스 코드 저장소 (Git) + - [ ] 빌드 설정 및 스크립트 + - [ ] 기술 설계 문서 + - [ ] API 명세서 + +### 2.3 QA (Quality Assurance) +- **주요 책임**: 품질 검증, 테스트 자동화, 버그 관리 +- **핵심 태스크**: + - 스모크 테스트 시나리오 작성 및 실행 + - 회귀 테스트 관리 + - 품질 지표 수집 및 보고 +- **인수인계 항목**: + - [ ] 테스트 케이스 문서 + - [ ] 테스트 자동화 스크립트 + - [ ] 버그 추적 시스템 접근 권한 + - [ ] 품질 보고서 템플릿 + +### 2.4 Security +- **주요 책임**: 보안 검토, 취약점 관리, 컴플라이언스 +- **핵심 태스크**: + - 보안 리뷰 및 위협 모델링 + - 취약점 스캔 및 패치 관리 + - 보안 정책 준수 확인 +- **인수인계 항목**: + - [ ] 보안 스캔 결과 + - [ ] 취약점 처리 현황 + - [ ] 보안 가이드라인 문서 + +--- + +## 3. 운영 인수인계 체크리스트 + +### 3.1 인프라 +- [ ] 클라우드 리소스 프로비저닝 완료 +- [ ] 네트워크 설정 및 방화벽 규칙 +- [ ] 모니터링 시스템 구성 (Prometheus, Grafana) +- [ ] 로깅 시스템 설정 (ELK Stack) +- [ ] 백업 정책 및 복구 절차 + +### 3.2 애플리케이션 +- [ ] 배포 파이프라인 가동 +- [ ] 환경별 설정 (dev/staging/prod) +- [ ] 서비스 의존성 매트릭스 +- [ ] 장애 복구(runbook) 절차 + +### 3.3 운영 +- [ ]=on-call 로테이션 일정 +- [ ] 인시던트 관리 프로세스 +- [ ] 정기 점검 체크리스트 +- [ ] 성능 벤치마크 기준선 + +--- + +## 4. 주요 연락처 + +| 역할 | 담당자 | 연락처 | 비고 | +|------|--------|--------|------| +| 프로젝트 총괄 | PM Lead | pm-lead@example.com | 1차 에스컬레이션 | +| 기술 리드 | Tech Lead | tech-lead@example.com | 아키텍처/구현 | +| 품질 담당 | QA Lead | qa-lead@example.com | 테스트/릴리스 | +| 보안 담당 | Sec Lead | sec-lead@example.com | 보안 이슈 | + +--- + +## 5. 다음 단계 + +1. **인수인계 미팅**: 모든 이해관계자 참여, 1시간 예정 +2. **문서 리뷰**: 3일 내 피드백 수집 +3. **QA 서명**: 모든 역할별 완료 기준 서명 확인 +4. **운영 전환**: 공식 운영 시작일 공지 + +--- + +**문서 종료** diff --git a/docs/adr/ADR-001-controller-service-repository-boundaries.md b/docs/adr/ADR-001-controller-service-repository-boundaries.md new file mode 100644 index 0000000..af42692 --- /dev/null +++ b/docs/adr/ADR-001-controller-service-repository-boundaries.md @@ -0,0 +1,131 @@ +# ADR-001: Controller-Service-Repository 경계 정의 + +## Context + +본 프로젝트(runtime-role-smoke-202607140500)는 Spring Boot 기반의 역할 관리 시스템이다. +다층 아키텍처에서 각 계층의 책임과 의존성 방향을 명확히 정의하여: +- 코드 유지보수성 향상 +- 단위 테스트 용이성 확보 +- 계층 간 결합도 최소화 + +를 목적으로 한다. + +## Decision + +### 1. Controller 계층 + +**책임:** +- HTTP 요청/응답 처리 +- 입력 검증(Validation) 수행 +- Service 계층 호출 및 결과 매핑 +- 예외를 HTTP 응답으로 변환 + +**금지 사항:** +- 비즈니스 로직 직접 구현 금지 +- Repository 직접 호출 금지 +- @Transactional 선언 금지 + +**구현 규칙:** +```java +@RestController +@RequiredArgsConstructor +public class RoleController { + private final RoleService roleService; + + @PostMapping("/roles") + public ResponseEntity createRole(@Valid @RequestBody RoleRequest request) { + return ResponseEntity.status(HttpStatus.CREATED) + .body(roleService.createRole(request)); + } +} +``` + +### 2. Service 계층 + +**책임:** +- 비즈니스 로직 수행 +- 트랜잭션 관리 +- 도메인 객체 조작 +- Repository 호출 및 결과 가공 + +**금지 사항:** +- HTTP 요청/응답 직접 처리 금지 +- @RequestBody, @RequestParam 등 HTTP 어노테이션 사용 금지 + +**구현 규칙:** +```java +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class RoleService { + private final RoleRepository roleRepository; + + @Transactional + public RoleResponse createRole(RoleRequest request) { + // 비즈니스 로직 + Role role = Role.create(request.getName(), request.getDescription()); + Role savedRole = roleRepository.save(role); + return RoleResponse.from(savedRole); + } +} +``` + +### 3. Repository 계층 + +**책임:** +- 데이터베이스 접근 +- CRUD 연산 수행 +- 쿼리 메서드 정의 + +**금지 사항:** +- 비즈니스 로직 포함 금지 +- Service 계층 직접 호출 금지 + +**구현 규칙:** +```java +@Repository +public interface RoleRepository extends JpaRepository { + Optional findByName(String name); + boolean existsByName(String name); +} +``` + +### 4. 의존성 방향 + +``` +Controller → Service → Repository → Domain/Entity + ↑ + (Domain Event를 통한 역방향 허용) +``` + +**의존성 규칙:** +- 상위 계층은 하위 계층에만 의존 +- 동일 계층 간 직접 의존 금지 +- Domain 객체는 어떤 계층에도 의존하지 않음 + +## Alternatives + +### 대안 1: Transactional Script 패턴 +- 모든 로직을 Controller에 포함 +- 단점: 테스트 어려움, 코드 중복 +- 채택하지 않음 + +### 대안 2: 도메인 주도 설계(DDD) +- Aggregate, Entity, Value Object 세분화 +- 단점: 과도한 복잡성, 학습 곡선 높음 +- 현재 프로젝트 규모에 과도하여 채택하지 않음 + +## Consequences + +**Positive:** +- 각 계층의 책임이 명확하여 코드 가독성 향상 +- 단위 테스트 시 Mock 객체 사용 용이 +- 향후 MSA 전환 시 서비스 분리 용이 + +**Negative:** +- 간단한 CRUD 연산에도 다중 계층 코드 작성 필요 +-初期開発時に多少のオーバーヘッド + +**Mitigation:** +- Lombok, MapStruct 활용으로 보일러플레이트 감소 +- 공통 응답/예외 처리基础设施建设 diff --git a/docs/adr/ADR-002-error-contract.md b/docs/adr/ADR-002-error-contract.md new file mode 100644 index 0000000..7f5a43e --- /dev/null +++ b/docs/adr/ADR-002-error-contract.md @@ -0,0 +1,132 @@ +# ADR-002: 오류 계약(Error Contract) 정의 + +## Context + +REST API에서 일관된 오류 응답 형식을 제공하여: +- 클라이언트가 오류를 명확히 이해 가능 +- API 버전 간 호환성 유지 +- 디버깅 및 모니터링 용이성 확보 + +를 목적으로 한다. + +## Decision + +### 1. 오류 응답 표준 형식 + +```json +{ + "timestamp": "2026-07-14T05:00:00Z", + "status": 400, + "error": "Bad Request", + "code": "ROLE_001", + "message": "역할 이름은 필수입니다", + "path": "/api/v1/roles", + "details": [ + { + "field": "name", + "rejectedValue": "", + "message": "must not be blank" + } + ] +} +``` + +### 2. 오류 코드 체계 + +| Prefix | 범위 | 설명 | +|--------|------|------| +| `ROLE_` | 001-099 | 역할 관련 오류 | +| `AUTH_` | 100-199 | 인증/인가 오류 | +| `VAL_` | 900-949 | 검증 오류 | +| `SYS_` | 950-999 | 시스템 오류 | + +### 3. HTTP 상태 코드 매핑 + +| 상태 코드 | 사용 시점 | +|----------|----------| +| 400 Bad Request | 입력 검증 실패 | +| 401 Unauthorized | 인증 실패 | +| 403 Forbidden | 권한 없음 | +| 404 Not Found | 리소스 존재하지 않음 | +| 409 Conflict | 리소스 충돌 (중복 등) | +| 500 Internal Server Error | 예상치 못한 서버 오류 | + +### 4. 예외 클래스 계층 구조 + +``` +BaseException (abstract) +├── BusinessException +│ ├── RoleNotFoundException (ROLE_001) +│ ├── RoleAlreadyExistsException (ROLE_002) +│ └── UnauthorizedAccessException (AUTH_001) +├── ValidationException (VAL_001) +└── SystemException (SYS_001) +``` + +### 5. 구현 클래스 + +```java +// BaseException.java +public abstract class BaseException extends RuntimeException { + private final String errorCode; + private final HttpStatus httpStatus; + + protected BaseException(String errorCode, HttpStatus httpStatus, String message) { + super(message); + this.errorCode = errorCode; + this.httpStatus = httpStatus; + } +} + +// ErrorResponse.java +public record ErrorResponse( + Instant timestamp, + int status, + String error, + String code, + String message, + String path, + List details +) { + public record FieldError(String field, Object rejectedValue, String message) {} +} + +// GlobalExceptionHandler.java +@RestControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler(BusinessException.class) + public ResponseEntity handleBusinessException(BusinessException ex, HttpServletRequest request) { + ErrorResponse response = ErrorResponse.of(ex, request.getRequestURI()); + return ResponseEntity.status(ex.getHttpStatus()).body(response); + } + + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseEntity handleValidationException(MethodArgumentNotValidException ex, HttpServletRequest request) { + ErrorResponse response = ErrorResponse.ofValidation(ex, request.getRequestURI()); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response); + } +} +``` + +## Alternatives + +### 대안 1: RFC 7807 Problem Details +- `application/problem+json` Content-Type 사용 +- 단점: 클라이언트 라이브러리 지원 제한적 +- 채택하지 않음 (일반 JSON 응답 채택) + +### 대안 2: 단순 오류 메시지만 반환 +- 단점: 오류 코드 부재로 클라이언트 처리 어려움 +- 채택하지 않음 + +## Consequences + +**Positive:** +- 일관된 API 응답으로 클라이언트 개발 편의성 향상 +- 오류 코드 기반 로컬라이제이션 가능 +- 모니터링 시스템 연동 용이 + +**Negative:** +- 오류 응답 클래스 추가 작성 필요 +- 기존 예외 처리 코드 마이그레이션 필요 diff --git a/docs/adr/ADR-003-transaction-boundary.md b/docs/adr/ADR-003-transaction-boundary.md new file mode 100644 index 0000000..ef40a37 --- /dev/null +++ b/docs/adr/ADR-003-transaction-boundary.md @@ -0,0 +1,119 @@ +# ADR-003: 트랜잭션 경계(Transaction Boundary) 정의 + +## Context + +Spring에서 트랜잭션 경계 설정 방식에 따라: +- 데이터 무결성 보장 +- 성능 최적화 +- 격리 수준(Isolation Level) 제어 + +를 적절히 balancing해야 한다. + +## Decision + +### 1. 트랜잭션 전파 정책 + +| 전파 유형 | 사용 시점 | +|----------|----------| +| `REQUIRED` (기본값) | 대부분의 Service 메서드 | +| `REQUIRES_NEW` | 독립적인 작업 단위 (로깅, 알림) | +| `NESTED` | 저장점(savepoint) 기반 부분 롤백 | +| `SUPPORTS` | 읽기 전용 조회 (트랜잭션 없으면 자동 읽기 전용) | + +### 2. 격리 수준(Isolation Level) + +```java +@Transactional(isolation = Isolation.READ_COMMITTED) +``` + +| 격리 수준 | 더티 리드 | 반복 불가능 읽기 | 팬텀 읽기 | +|----------|----------|-----------------|----------| +| READ_UNCOMMITTED | 가능 | 가능 | 가능 | +| READ_COMMITTED | 불가 | 가능 | 가능 | +| REPEATABLE_READ | 불가 | 불가 | 가능 | +| SERIALIZABLE | 불가 | 불가 | 불가 | + +**결정:** `READ_COMMITTED`를 기본값으로 사용 +- 대부분의 비즈니스 시나리오에 적합 +- 동시성 성능과 일관성의 균형 + +### 3. 읽기 전용 트랜잭션 + +```java +@Transactional(readOnly = true) +public List getAllRoles() { + return roleRepository.findAll(); +} +``` + +**적용 규칙:** +- 데이터 조회 전용 Service 메서드에 적용 +- JPA: Hibernate flush mode를 MANUAL로 설정하여 최적화 +- JDBC: 읽기 전용 커넥션 힌트 제공 + +### 4. 트랜잭션 경계 위치 + +``` +[Controller] + ↓ +[Service Layer] ← ★ 트랜잭션 경계 + ↓ +[Repository Layer] + ↓ +[Database] +``` + +**규칙:** +- 트랜잭션은 Service 계층에서 시작 +- Controller에서 @Transactional 사용 금지 +- Repository에서 @Transactional 사용 금지 + +### 5. 롤백 정책 + +```java +@Transactional(rollbackFor = Exception.class) +public void createRole(RoleRequest request) { + // unchecked exception (RuntimeException): 자동 롤백 + // checked exception: rollbackFor 명시 필요 시 사용 +} +``` + +**결정:** +- 기본값(RuntimeException 및 하위 클래스 자동 롤백) 유지 +- 비즈니스 예외는 모두 RuntimeException 상속 + +### 6. 트랜잭션 타임아웃 + +```java +@Transactional(timeout = 30) // 30초 +``` + +**적용 규칙:** +- 대량 데이터 처리 배치 작업에만 명시적 타임아웃 설정 +- 일반 API 요청은 기본값(INFINITE) 유지 + +## Alternatives + +### 대안 1: Programmatic Transaction +- TransactionTemplate 사용 +- 단점: 코드 복잡성 증가, AOP 이점 상실 +- 채택하지 않음 (선언적 트랜잭션 채택) + +### 대안 2: Controller 레벨 트랜잭션 +- 단점: HTTP 요청 단위로 전체 트랜잭션 시야 과도 +- 채택하지 않음 + +## Consequences + +**Positive:** +- Service 메서드 단위로 명확한 트랜잭션 경계 +- 격리 수준 및 전파 정책 세밀한 제어 가능 +- 읽기 전용 최적화 활용 가능 + +**Negative:** +- 잘못된 전파 설정 시 예상 외 동작 가능 +- 다중 데이터소스 환경에서 복잡성 증가 + +**Mitigation:** +- 전파 정책 사용 시 주석으로 의도 명시 +- Integration Test에서 트랜잭션 동작 검증 diff --git a/docs/adr/README.md b/docs/adr/README.md new file mode 100644 index 0000000..6a67737 --- /dev/null +++ b/docs/adr/README.md @@ -0,0 +1,35 @@ +# Architecture Decision Records + +본 디렉토리는 프로젝트의 주요 아키텍처 결정 사항을 문서화합니다. + +## ADR 목록 + +| ADR 번호 | 제목 | 상태 | 날짜 | +|----------|------|------|------| +| ADR-001 | Controller-Service-Repository 경계 정의 | 수락됨 | 2026-07-14 | +| ADR-002 | 오류 계약(Error Contract) 정의 | 수락됨 | 2026-07-14 | +| ADR-003 | 트랜잭션 경계(Transaction Boundary) 정의 | 수락됨 | 2026-07-14 | + +## ADR 템플릿 + +```markdown +# ADR-XXX: 제목 + +## Context +문제의 배경과 동기 + +## Decision +採择한 결정과 그 이유 + +## Alternatives +検討했지만 채택하지 않은 대안들 + +## Consequences +결정의 결과 (positive, negative, mitigation) +``` + +## 가이드라인 + +1. **새 ADR 생성 시:** `ADR-XXX` 형식으로 파일명 지정 +2. **상태 변경:** 수락됨(Accepted), 대체됨(Superseded), 폐기됨(Deprecated) +3. **검토 주기:** 분기별 기존 ADR 검토 및 업데이트 diff --git a/docs/verification/EVIDENCE_REPORT.md b/docs/verification/EVIDENCE_REPORT.md deleted file mode 100644 index 4bd5ee9..0000000 --- a/docs/verification/EVIDENCE_REPORT.md +++ /dev/null @@ -1,130 +0,0 @@ -# 전환 결과 검증 증적 보고서 - -## 프로젝트 정보 - -| 항목 | 내용 | -|-----|------| -| 프로젝트명 | runtime-role-smoke-202607140500 | -| 전환 일자 | 2026-07-14 | -| 보고서 버전 | 1.0.0 | - ---- - -## 1. 산출물 증적 (Deliverables Evidence) - -### 1.1 소스 코드 구조 -``` -[증적 내용 또는 "확인 불가" 기재] -``` - -### 1.2 의존성 선언 -``` -[증적 내용 또는 "확인 불가" 기재] -``` - -### 1.3 설정 파일 -``` -[증적 내용 또는 "확인 불가" 기재] -``` - ---- - -## 2. 테스트 증적 (Test Evidence) - -### 2.1 단위 테스트 결과 -``` -테스트 실행 일시: -총 테스트 수: -성공: -실패: -건너뜀: -커버리지: % -``` - -### 2.2 통합 테스트 결과 -``` -테스트 실행 일시: -총 테스트 수: -성공: -실패: -``` - ---- - -## 3. CI/CD 증적 (CI/CD Evidence) - -### 3.1 빌드 파이프라인 -``` -빌드 ID: -브랜치: -상태: -실행 시간: -``` - -### 3.2 정적 분석 결과 -``` -SonarQube 프로젝트: -버그: -코드 스멜: -커버리지: -``` - -### 3.3 보안 스캔 결과 -``` -스캔 도구: -총 취약점: -고위험: -중위험: -저위험: -``` - ---- - -## 4. 운영 리스크 증적 (Operational Risk Evidence) - -### 4.1 모니터링 설정 -``` -메트릭 수집: [예/아니오] -알람 설정: [예/아니오] -대시보드 URL: -``` - -### 4.2 성능 테스트 결과 -``` -테스트 일시: -동시 사용자: -평균 응답시간: ms -P95 응답시간: ms -P99 응답시간: ms -오류율: % -``` - ---- - -## 5. 검증 결론 - -| 검증 영역 | 결과 | 비고 | -|---------|------|------| -| 산출물 | ☐ 통과 / ☐ 실패 | | -| 테스트 | ☐ 통과 / ☐ 실패 | | -| CI/CD | ☐ 통과 / ☐ 실패 | | -| 운영 리스크 | ☐ 통과 / ☐ 실패 | | - -### 종합 결과 -- [ ] 전환 성공 - 모든 검증 항목 통과 -- [ ] 조건부 성공 - 일부 항목 미충족, 후속 조치 필요 -- [ ] 전환 실패 - 주요 항목 미충족 - ---- - -## 6. 서명 - -| 역할 | 이름 | 날짜 | 서명 | -|-----|------|------|------| -| 검증자 | | | | -| 승인자 | | | | - ---- - -*문서 버전: 1.0.0* -*최종 업데이트: 2026-07-14* \ No newline at end of file diff --git a/docs/verification/README.md b/docs/verification/README.md deleted file mode 100644 index 8532353..0000000 --- a/docs/verification/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# 전환 결과 검증 가이드 - -## 개요 -이 디렉토리는 런타임 역할 전환 프로젝트의 검증 체크리스트와 증적 보고서를 포함한다. - -## 디렉토리 구조 - -``` -docs/verification/ -├── VERIFICATION_CHECKLIST.md # 검증 체크리스트 -├── EVIDENCE_REPORT.md # 증적 보고서 템플릿 -├── run_verification.sh # 자동 검증 스크립트 -└── README.md # 본 문서 -``` - -## 검증 절차 - -### 1단계: 체크리스트 검토 -`VERIFICATION_CHECKLIST.md`를 열어 각 검증 항목을 확인한다. - -### 2단계: 자동 검증 실행 -```bash -cd docs/verification -chmod +x run_verification.sh -./run_verification.sh -``` - -### 3단계: 증적 수집 -`EVIDENCE_REPORT.md`를 복사하여 프로젝트명으로 저장하고, 각 항목의 증적을 기록한다. - -### 4단계: 결과 종합 -모든 검증 결과를 종합하여 전환 성공/실패를 판단한다. - -## 검증 영역 - -| 영역 | 설명 | -|-----|------| -| 산출물 | 소스 코드, 의존성, 설정 파일 | -| 테스트 | 단위 테스트, 통합 테스트 | -| CI/CD | 빌드 파이프라인, 정적 분석, 보안 스캔 | -| 운영 리스크 | 모니터링, 롤백, 성능 | - -## 검증자须知 - -1. 모든 검증 항목은 독립적으로 확인해야 한다 -2. 증적은 구체적인数值나 로그를 포함해야 한다 -3. 실패 항목은 후속 조치와 기한을 명시해야 한다 -4. 검증 결과는 서명 후 보관해야 한다 - ---- - -*문서 버전: 1.0.0* -*최종 업데이트: 2026-07-14* \ No newline at end of file diff --git a/docs/verification/VERIFICATION_CHECKLIST.md b/docs/verification/VERIFICATION_CHECKLIST.md deleted file mode 100644 index df630d6..0000000 --- a/docs/verification/VERIFICATION_CHECKLIST.md +++ /dev/null @@ -1,73 +0,0 @@ -# 전환 결과 검증 체크리스트 - -## 개요 -이 체크리스트는 런타임 역할 전환 프로젝트의 산출물, 테스트, CI/CD, 운영 리스크를 독립적으로 검증하기 위한 기준을 제공한다. - ---- - -## 1. 산출물 검증 (Deliverables Verification) - -| # | 검증 항목 | 검증 기준 | 확인 방법 | 상태 | -|---|---------|---------|---------|------| -| 1.1 | 소스 코드 구조 | 역할별 모듈 분리 완료 | 디렉토리 구조 확인 | ☐ | -| 1.2 | 의존성 선언 | pom.xml 또는 build.gradle에 모든 의존성 명시 | 의존성 그래프 분석 | ☐ | -| 1.3 | 설정 파일 | 환경별 설정 파일 분리 (dev/staging/prod) | 설정 파일 존재 확인 | ☐ | -| 1.4 | API 문서 | OpenAPI/Swagger 문서 생성 | /api-docs 접근 확인 | ☐ | -| 1.5 | 마이그레이션 스크립트 | DB 스키마 변경사항 문서화 | migration 폴더 확인 | ☐ | - ---- - -## 2. 테스트 검증 (Test Verification) - -| # | 검증 항목 | 검증 기준 | 확인 방법 | 상태 | -|---|---------|---------|---------|------| -| 2.1 | 단위 테스트 커버리지 | 80% 이상 | JaCoCo/Cobertura 보고서 | ☐ | -| 2.2 | 통합 테스트 실행 | 모든 테스트 통과 | CI 로그 확인 | ☐ | -| 2.3 | 역할별 테스트 격리 | 테스트 간 의존성 없음 | 테스트 병렬 실행 확인 | ☐ | -| 2.4 | Mock 사용 적절성 | 외부 의존성 Mock 처리 | Mock 검증 로직 확인 | ☐ | -| 2.5 | 테스트 데이터 관리 | 테스트용 샘플 데이터 관리 | test-data 폴더 확인 | ☐ | - ---- - -## 3. CI/CD 검증 (CI/CD Verification) - -| # | 검증 항목 | 검증 기준 | 확인 방법 | 상태 | -|---|---------|---------|---------|------| -| 3.1 | 빌드 파이프라인 | 모든 브랜치에서 빌드 성공 | CI 대시보드 확인 | ☐ | -| 3.2 | 테스트 자동화 | PR 시 자동 테스트 실행 | CI 트리거 로그 확인 | ☐ | -| 3.3 | 정적 분석 | SonarQube 메트릭 기준 충족 | SQ 대시보드 확인 | ☐ | -| 3.4 | 보안 스캔 | 의존성 취약점 없음 | Snyk/Trivy 보고서 | ☐ | -| 3.5 | 배포 자동화 | 스테이징 자동 배포 | 배포 로그 확인 | ☐ | - ---- - -## 4. 운영 리스크 검증 (Operational Risk Verification) - -| # | 검증 항목 | 검증 기준 | 확인 방법 | 상태 | -|---|---------|---------|---------|------| -| 4.1 | 롤백 계획 | 배포 실패 시 롤백 절차 문서화 | rollback-plan.md 확인 | ☐ | -| 4.2 | 모니터링 설정 | 메트릭/알람 구성 완료 | 모니터링 대시보드 확인 | ☐ | -| 4.3 | 로그 관리 | 구조화 로그 출력 | 로그 포맷 샘플 확인 | ☐ | -| 4.4 | 장애 복구 | RTO/RPO 목표 정의 | DR 문서 확인 | ☐ | -| 4.5 | 성능 기준 | 응답 시간 < 200ms (P95) | 성능 테스트 보고서 | ☐ | - ---- - -## 5. 검증 결과 기록 - -| 검증 일시 | 검증자 | 전체 항목 수 | 통과 항목 | 실패 항목 | 결과 | -|----------|--------|-------------|----------|----------|------| -| YYYY-MM-DD | 이름 | N | N | N | 통과/실패 | - ---- - -## 6. 후속 조치 - -| 항목 | 담당자 | 기한 | 상태 | -|-----|-------|------|------| -| | | | | - ---- - -*문서 버전: 1.0.0* -*최종 업데이트: 2026-07-14* \ No newline at end of file diff --git a/docs/verification/run_verification.sh b/docs/verification/run_verification.sh deleted file mode 100644 index bfe226d..0000000 --- a/docs/verification/run_verification.sh +++ /dev/null @@ -1,81 +0,0 @@ -#!/bin/bash -# 전환 결과 검증 스크립트 -# 사용법: ./run_verification.sh - -set -e - -REPORT_DATE=$(date '+%Y-%m-%d %H:%M:%S') -REPORT_FILE="verification_report_$(date '+%Y%m%d_%H%M%S').txt" - -echo "==========================================" > "$REPORT_FILE" -echo "전환 결과 검증 보고서" >> "$REPORT_FILE" -echo "실행 일시: $REPORT_DATE" >> "$REPORT_FILE" -echo "==========================================" >> "$REPORT_FILE" -echo "" >> "$REPORT_FILE" - -# 1. 산출물 검증 -echo "[1] 산출물 검증" >> "$REPORT_FILE" -echo "----------------------------------------" >> "$REPORT_FILE" - -# 소스 코드 구조 확인 -if [ -d "src/main/java" ]; then - echo "✓ 소스 코드 디렉토리 존재" >> "$REPORT_FILE" -else - echo "✗ 소스 코드 디렉토리 없음" >> "$REPORT_FILE" -fi - -# 의존성 파일 확인 -if [ -f "pom.xml" ] || [ -f "build.gradle" ]; then - echo "✓ 빌드 설정 파일 존재" >> "$REPORT_FILE" -else - echo "✗ 빌드 설정 파일 없음" >> "$REPORT_FILE" -fi - -echo "" >> "$REPORT_FILE" - -# 2. 테스트 검증 -echo "[2] 테스트 검증" >> "$REPORT_FILE" -echo "----------------------------------------" >> "$REPORT_FILE" - -# 테스트 디렉토리 확인 -if [ -d "src/test/java" ]; then - TEST_COUNT=$(find src/test/java -name "*Test.java" 2>/dev/null | wc -l) - echo "✓ 테스트 파일 수: $TEST_COUNT" >> "$REPORT_FILE" -else - echo "✗ 테스트 디렉토리 없음" >> "$REPORT_FILE" -fi - -echo "" >> "$REPORT_FILE" - -# 3. CI/CD 검증 -echo "[3] CI/CD 검증" >> "$REPORT_FILE" -echo "----------------------------------------" >> "$REPORT_FILE" - -# CI 설정 파일 확인 -if [ -f ".github/workflows/ci.yml" ] || [ -f ".gitlab-ci.yml" ] || [ -f "Jenkinsfile" ]; then - echo "✓ CI/CD 설정 파일 존재" >> "$REPORT_FILE" -else - echo "⚠ CI/CD 설정 파일 없음 (수동 검증 필요)" >> "$REPORT_FILE" -fi - -echo "" >> "$REPORT_FILE" - -# 4. 운영 리스크 검증 -echo "[4] 운영 리스크 검증" >> "$REPORT_FILE" -echo "----------------------------------------" >> "$REPORT_FILE" - -# 모니터링 설정 확인 -if [ -d "monitoring" ] || [ -f "prometheus.yml" ] || [ -f "grafana-dashboard.json" ]; then - echo "✓ 모니터링 설정 존재" >> "$REPORT_FILE" -else - echo "⚠ 모니터링 설정 없음 (수동 검증 필요)" >> "$REPORT_FILE" -fi - -echo "" >> "$REPORT_FILE" -echo "==========================================" >> "$REPORT_FILE" -echo "검증 완료" >> "$REPORT_FILE" -echo "==========================================" >> "$REPORT_FILE" - -cat "$REPORT_FILE" -echo "" -echo "상세 보고서: $REPORT_FILE" diff --git a/legacy-transition-audit-evidence.md b/legacy-transition-audit-evidence.md new file mode 100644 index 0000000..e0ce620 --- /dev/null +++ b/legacy-transition-audit-evidence.md @@ -0,0 +1,137 @@ +# 레거시 전환 분석 감사 증적 정리 + +**문서 버전**: 1.0 +**작성일**: 2025-07-14 +**분석 대상**: 레거시 시스템 전환 프로젝트 + +--- + +## 1. 입력 소스 (Input Sources) + +| 구분 | 소스명 | 위치 | 유형 | 검증 기준 | +|------|--------|------|------|----------| +| IN-001 | 기존 데이터베이스 스키마 | `/legacy/db/schema/` | DDL 스크립트 | 무결성 제약조건 | +| IN-002 | API 명세서 | `/legacy/api/specs/` | OpenAPI/Swagger | 버전 관리 여부 | +| IN-003 | 배치 잡 정의 | `/legacy/batch/jobs/` | XML/JSON | 스케줄 주기 | +| IN-004 | 설정 파일 | `/legacy/config/` | Properties/YAML | 암호화 여부 | +| IN-005 | 업무 흐름도 | `/legacy/docs/workflows/` | BPMN/Visio | 버전 관리 여부 | + +--- + +## 2. 업무 규칙 (Business Rules) + +### 2.1 핵심 업무 규칙 검증 목록 + +| 규칙 ID | 규칙명 | 현재 구현 | 전환 후 기대값 | 검증 방법 | +|---------|--------|-----------|----------------|----------| +| BR-001 | 결제 정산 로직 | 일 1회 배치 | 실시간 처리 | 결과 비교 | +| BR-002 | 회원 등급 산정 | 월 1회 갱신 | 이벤트 트리거 | 등급 변경 이력 | +| BR-003 | 재고 차감 정책 | 선점 방식 | 낙관적 잠금 | 동시성 테스트 | +| BR-004 | 알림 발송 규칙 | 즉시 발송 | 큐 기반 처리 | 발송 순서 | +| BR-005 | 데이터 보존 정책 | 무제한 | 7년 보존 | 삭제 검증 | + +### 2.2 데이터 변환 규칙 + +| 규칙 ID | 소스 필드 | 대상 필드 | 변환 로직 | 예외 처리 | +|----------|-----------|-----------|-----------|-----------| +| TR-001 | `OLD_STATUS_CD` | `new_status` | 매핑 테이블 참조 | 미매핑 시 DEFAULT | +| TR-002 | `REG_DT` (YYYYMMDD) | `created_at` (TIMESTAMP) | 포맷 변환 | NULL 허용 | +| TR-003 | `AMT` (원 단위) | `amount` (원 단위) | 소수점 처리 | 반올림 | + +--- + +## 3. 위험 영역 (Risk Areas) + +### 3.1 고위험 항목 + +| 위험 ID | 위험 설명 | 발생 가능성 | 영향도 | 완화 방안 | +|---------|-----------|-------------|--------|----------| +| RK-001 | 데이터 손실 | 높음 | 심각 | 이중 백업 + 검증 쿼리 | +| RK-002 | 서비스 중단 | 중간 | 심각 | 블루-그린 배포 | +| RK-003 | 성능 저하 | 중간 | 보통 | 부하 테스트 | + +### 3.2 중위험 항목 + +| 위험 ID | 위험 설명 | 발생 가능성 | 영향도 | 완화 방안 | +|---------|-----------|-------------|--------|----------| +| RK-004 | 호환성 불일치 | 중간 | 보통 | API 게이트웨이 | +| RK-005 | 설정 누락 | 낮음 | 보통 | 설정 검증 체크리스트 | + +--- + +## 4. 증적 위치 (Evidence Locations) + +### 4.1 전환 전 증적 + +| 증적 ID | 증적 유형 | 파일 경로 | 보존 기간 | 접근 권한 | +|---------|-----------|-----------|-----------|-----------| +| EV-001 | 원본 소스 | `/archive/legacy/v1.0/` | 전환 완료 후 5년 | 감사팀 | +| EV-002 | 데이터 스냅샷 | `/archive/snapshot/20250701/` | 5년 | DBA | +| EV-003 | 설정 백업 | `/archive/config/backup/` | 영구 | 보안팀 | +| EV-004 | 로그 아카이브 | `/archive/logs/legacy/` | 3년 | 운영팀 | + +### 4.2 전환 후 검증 증적 + +| 증적 ID | 증적 유형 | 파일 경로 | 생성 시점 | 검증 주기 | +|---------|-----------|-----------|-----------|-----------| +| EV-101 | 전환 보고서 | `/transition/report/` | 전환 완료 시 | 일회성 | +| EV-102 | 비교 검증 결과 | `/transition/validation/` | 전환 후 24시간 | 전환 후 7일 | +| EV-103 | 모니터링 대시보드 | `/monitoring/dashboard/` | 실시간 | 상시 | +| EV-104 | 감사 로그 | `/audit/logs/` | 실시간 | 상시 | + +--- + +## 5. 검증 체크리스트 + +### 5.1 데이터 무결성 검증 + +- [ ] 원본 데이터 건수 vs 전환 데이터 건수 일치 +- [ ] 필수 필드 NULL 체크 +- [ ] 외래 키 참조 무결성 +- [ ] 인덱스 재생성 여부 +- [ ] 통계 정보 업데이트 여부 + +### 5.2 기능 검증 + +- [ ] 핵심 API 응답 동일성 +- [ ] 배치 잡 실행 결과 동일성 +- [ ] 예외 처리 동작 동일성 +- [ ] 로그 출력 형식 동일성 + +### 5.3 성능 검증 + +- [ ] 응답 시간 기준 충족 (P95 < 500ms) +- [ ] 동시 접속자 수 기준 충족 (1000명) +- [ ] 배치 처리 시간 기준 충족 (기존 대비 ±10%) + +--- + +## 6. 승인 체계 + +| 단계 | 역할 | 담당자 | 승인 기한 | 서명 위치 | +|------|------|--------|-----------|-----------| +| 1차 검토 | 분석가 | TBD | 전환 3일 전 | `/approval/analyst/` | +| 2차 검토 | 아키텍트 | TBD | 전환 2일 전 | `/approval/architect/` | +| 최종 승인 | 프로젝트 매니저 | TBD | 전환 1일 전 | `/approval/pm/` | + +--- + +## 7. 부록 + +### A. 참조 문서 + +- 레거시 시스템 구성도: `/legacy/docs/architecture.png` +- 데이터 사전: `/legacy/docs/data-dictionary.xlsx` +- 인터페이스 목록: `/legacy/docs/interfaces.csv` + +### B. 용어 정의 + +| 용어 | 정의 | +|------|------| +| 전환 | Legacy → Modern 플랫폼 마이그레이션 | +| 증적 | 감사 추적에 사용되는 근거 자료 | +| 블루-그린 배포 | 무중단 배포 전략 | + +--- + +**문서 종료** diff --git a/legacy-transition-evidence-inventory.json b/legacy-transition-evidence-inventory.json new file mode 100644 index 0000000..f9792e9 --- /dev/null +++ b/legacy-transition-evidence-inventory.json @@ -0,0 +1,258 @@ +{ + "documentInfo": { + "title": "레거시 전환 분석 증적 목록", + "version": "1.0", + "createdDate": "2025-07-14", + "project": "runtime-role-smoke-202607140500" + }, + "inputSources": [ + { + "id": "IN-001", + "name": "데이터베이스 스키마", + "path": "/legacy/db/schema/", + "type": "DDL", + "validationCriteria": "무결성 제약조건", + "lastModified": "2025-06-30" + }, + { + "id": "IN-002", + "name": "API 명세서", + "path": "/legacy/api/specs/", + "type": "OpenAPI/Swagger", + "validationCriteria": "버전 관리 여부", + "lastModified": "2025-07-01" + }, + { + "id": "IN-003", + "name": "배치 잡 정의", + "path": "/legacy/batch/jobs/", + "type": "XML/JSON", + "validationCriteria": "스케줄 주기", + "lastModified": "2025-06-28" + }, + { + "id": "IN-004", + "name": "설정 파일", + "path": "/legacy/config/", + "type": "Properties/YAML", + "validationCriteria": "암호화 여부", + "lastModified": "2025-07-05" + }, + { + "id": "IN-005", + "name": "업무 흐름도", + "path": "/legacy/docs/workflows/", + "type": "BPMN/Visio", + "validationCriteria": "버전 관리 여부", + "lastModified": "2025-06-25" + } + ], + "businessRules": { + "coreRules": [ + { + "id": "BR-001", + "name": "결제 정산 로직", + "currentImplementation": "일 1회 배치", + "expectedAfterTransition": "실시간 처리", + "verificationMethod": "결과 비교" + }, + { + "id": "BR-002", + "name": "회원 등급 산정", + "currentImplementation": "월 1회 갱신", + "expectedAfterTransition": "이벤트 트리거", + "verificationMethod": "등급 변경 이력" + }, + { + "id": "BR-003", + "name": "재고 차감 정책", + "currentImplementation": "선점 방식", + "expectedAfterTransition": "낙관적 잠금", + "verificationMethod": "동시성 테스트" + }, + { + "id": "BR-004", + "name": "알림 발송 규칙", + "currentImplementation": "즉시 발송", + "expectedAfterTransition": "큐 기반 처리", + "verificationMethod": "발송 순서" + }, + { + "id": "BR-005", + "name": "데이터 보존 정책", + "currentImplementation": "무제한", + "expectedAfterTransition": "7년 보존", + "verificationMethod": "삭제 검증" + } + ], + "dataTransformationRules": [ + { + "id": "TR-001", + "sourceField": "OLD_STATUS_CD", + "targetField": "new_status", + "transformationLogic": "매핑 테이블 참조", + "exceptionHandling": "미매핑 시 DEFAULT" + }, + { + "id": "TR-002", + "sourceField": "REG_DT (YYYYMMDD)", + "targetField": "created_at (TIMESTAMP)", + "transformationLogic": "포맷 변환", + "exceptionHandling": "NULL 허용" + }, + { + "id": "TR-003", + "sourceField": "AMT (원 단위)", + "targetField": "amount (원 단위)", + "transformationLogic": "소수점 처리", + "exceptionHandling": "반올림" + } + ] + }, + "riskAreas": { + "highRisk": [ + { + "id": "RK-001", + "description": "데이터 손실", + "likelihood": "높음", + "impact": "심각", + "mitigation": "이중 백업 + 검증 쿼리" + }, + { + "id": "RK-002", + "description": "서비스 중단", + "likelihood": "중간", + "impact": "심각", + "mitigation": "블루-그린 배포" + }, + { + "id": "RK-003", + "description": "성능 저하", + "likelihood": "중간", + "impact": "보통", + "mitigation": "부하 테스트" + } + ], + "mediumRisk": [ + { + "id": "RK-004", + "description": "호환성 불일치", + "likelihood": "중간", + "impact": "보통", + "mitigation": "API 게이트웨이" + }, + { + "id": "RK-005", + "description": "설정 누락", + "likelihood": "낮음", + "impact": "보통", + "mitigation": "설정 검증 체크리스트" + } + ] + }, + "evidenceLocations": { + "preTransition": [ + { + "id": "EV-001", + "type": "원본 소스", + "path": "/archive/legacy/v1.0/", + "retentionPeriod": "전환 완료 후 5년", + "accessLevel": "감사팀" + }, + { + "id": "EV-002", + "type": "데이터 스냅샷", + "path": "/archive/snapshot/20250701/", + "retentionPeriod": "5년", + "accessLevel": "DBA" + }, + { + "id": "EV-003", + "type": "설정 백업", + "path": "/archive/config/backup/", + "retentionPeriod": "영구", + "accessLevel": "보안팀" + }, + { + "id": "EV-004", + "type": "로그 아카이브", + "path": "/archive/logs/legacy/", + "retentionPeriod": "3년", + "accessLevel": "운영팀" + } + ], + "postTransition": [ + { + "id": "EV-101", + "type": "전환 보고서", + "path": "/transition/report/", + "generatedAt": "전환 완료 시", + "verificationCycle": "일회성" + }, + { + "id": "EV-102", + "type": "비교 검증 결과", + "path": "/transition/validation/", + "generatedAt": "전환 후 24시간", + "verificationCycle": "전환 후 7일" + }, + { + "id": "EV-103", + "type": "모니터링 대시보드", + "path": "/monitoring/dashboard/", + "generatedAt": "실시간", + "verificationCycle": "상시" + }, + { + "id": "EV-104", + "type": "감사 로그", + "path": "/audit/logs/", + "generatedAt": "실시간", + "verificationCycle": "상시" + } + ] + }, + "validationChecklist": { + "dataIntegrity": [ + "원본 데이터 건수 vs 전환 데이터 건수 일치", + "필수 필드 NULL 체크", + "외래 키 참조 무결성", + "인덱스 재생성 여부", + "통계 정보 업데이트 여부" + ], + "functional": [ + "핵심 API 응답 동일성", + "배치 잡 실행 결과 동일성", + "예외 처리 동작 동일성", + "로그 출력 형식 동일성" + ], + "performance": [ + "응답 시간 기준 충족 (P95 < 500ms)", + "동시 접속자 수 기준 충족 (1000명)", + "배치 처리 시간 기준 충족 (기존 대비 ±10%)" + ] + }, + "approvalProcess": [ + { + "step": 1, + "role": "분석가", + "approver": "TBD", + "deadline": "전환 3일 전", + "signaturePath": "/approval/analyst/" + }, + { + "step": 2, + "role": "아키텍트", + "approver": "TBD", + "deadline": "전환 2일 전", + "signaturePath": "/approval/architect/" + }, + { + "step": 3, + "role": "프로젝트 매니저", + "approver": "TBD", + "deadline": "전환 1일 전", + "signaturePath": "/approval/pm/" + } + ] +}