Compare commits
No commits in common. "main" and "forge/role-aa-001-attempt-1-run-f88341c79b7c" have entirely different histories.
main
...
forge/role
7 changed files with 0 additions and 538 deletions
|
|
@ -1,3 +0,0 @@
|
|||
# role-pm-001-attempt-1-run-0d2fe2a0ad41
|
||||
|
||||
Forge 이슈 작업 브랜치 `forge/role-pm-001-attempt-1-run-0d2fe2a0ad41`.
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
# role-ta-001-attempt-1-run-9fa6a6b8d5c6
|
||||
|
||||
Forge 이슈 작업 브랜치 `forge/role-ta-001-attempt-1-run-9fa6a6b8d5c6`.
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
# 런타임 역할 검증 프로젝트 - 운영 인수인계 문서
|
||||
|
||||
**프로젝트**: 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. **운영 전환**: 공식 운영 시작일 공지
|
||||
|
||||
---
|
||||
|
||||
**문서 종료**
|
||||
|
|
@ -1,131 +0,0 @@
|
|||
# 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<RoleResponse> 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<Role, Long> {
|
||||
Optional<Role> 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 활용으로 보일러플레이트 감소
|
||||
- 공통 응답/예외 처리基础设施建设
|
||||
|
|
@ -1,132 +0,0 @@
|
|||
# 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<FieldError> details
|
||||
) {
|
||||
public record FieldError(String field, Object rejectedValue, String message) {}
|
||||
}
|
||||
|
||||
// GlobalExceptionHandler.java
|
||||
@RestControllerAdvice
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
@ExceptionHandler(BusinessException.class)
|
||||
public ResponseEntity<ErrorResponse> handleBusinessException(BusinessException ex, HttpServletRequest request) {
|
||||
ErrorResponse response = ErrorResponse.of(ex, request.getRequestURI());
|
||||
return ResponseEntity.status(ex.getHttpStatus()).body(response);
|
||||
}
|
||||
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public ResponseEntity<ErrorResponse> 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:**
|
||||
- 오류 응답 클래스 추가 작성 필요
|
||||
- 기존 예외 처리 코드 마이그레이션 필요
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
# 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<Role> 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에서 트랜잭션 동작 검증
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
# 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 검토 및 업데이트
|
||||
Loading…
Add table
Add a link
Reference in a new issue