From e414a834ad38cb50ac8b6f854fb16b046e02d8a9 Mon Sep 17 00:00:00 2001 From: forge-bot Date: Tue, 14 Jul 2026 06:25:58 +0000 Subject: [PATCH] =?UTF-8?q?TA=20=EC=97=AD=ED=95=A0=20Spring=20=EA=B2=BD?= =?UTF-8?q?=EA=B3=84=20smoke=20(role-ta-live-1522-001)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ADR-001-spring-architecture-boundaries.md | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 docs/adr/ADR-001-spring-architecture-boundaries.md diff --git a/docs/adr/ADR-001-spring-architecture-boundaries.md b/docs/adr/ADR-001-spring-architecture-boundaries.md new file mode 100644 index 0000000..031a181 --- /dev/null +++ b/docs/adr/ADR-001-spring-architecture-boundaries.md @@ -0,0 +1,84 @@ +# ADR-001: Spring MVC 아키텍처 경계 및 계약 정의 + +## Context + +runtime-role-matrix-live 프로젝트는 Spring Boot 기반 REST API 서버로 역할 기반 접근 제어(RBAC)를 구현한다. 레이어 간 책임 분담, 오류 처리 계약, 트랜잭션 범위가 명시적으로 정의되어 있지 않아 일관성 없는 구현이 발생할 위험이 있다. + +## Decision + +### 1. 레이어 경계 정의 + +| 레이어 | 책임 | +|-------|------| +| **Controller** | HTTP 요청/응답, 입력 검증, DTO 변환, HTTP 상태 코드 결정. 트랜잭션 경계 없음 | +| **Service** | 비즈니스 로직, 도메인 객체 조작, @Transactional 선언적 트랜잭션, BusinessException 발생 | +| **Repository** | 데이터 접근(JPA), 쿼리 실행, Entity 변환. 순수 데이터 조작만 수행 | + +### 2. 오류 계약 (RFC 7807 Problem Details) + +```json +{ + "type": "https://api.runtimematrix.com/errors/role-not-found", + "title": "역할을 찾을 수 없습니다", + "status": 404, + "detail": "ID가 'admin'인 역할이 존재하지 않습니다.", + "instance": "/api/v1/roles/admin", + "timestamp": "2026-07-14T15:22:00Z", + "traceId": "abc123def456" +} +``` + +**예외 계층**: `RuntimeException → BusinessException(추상) → RoleNotFoundException, RoleAlreadyExistsException` + +**HTTP 상태 매핑**: + +| 예외 | 상태 | +|-----|------| +| ValidationException | 400 | +| BusinessException | 400/409 | +| RoleNotFoundException | 404 | +| PermissionDeniedException | 403 | +| InternalServerException | 500 | + +### 3. 트랜잭션 경계 + +| 규칙 | 설명 | +|-----|------| +| 시작점 | Service Layer public 메서드 | +| 전파 | REQUIRED (기본값) | +| 읽기 전용 | SELECT-only 메서드에 `readOnly=true` | +| 격리 수준 | READ_COMMITTED | +| 롤백 | RuntimeException, BusinessException → Yes | + +### 4. 의존성 규칙 + +| From → To | 허용 | +|-----------|------| +| Controller → Service | ✅ | +| Controller → Repository | ❌ | +| Service → Repository | ✅ | +| Service → Domain | ✅ | +| Repository → Service | ❌ | + +### 5. 패키지 구조 + +``` +com.runtimematrix +├── controller/dto # Request/Response DTO +├── service/command # Command 객체 +├── repository # JPA Repository +├── domain/model # 도메인 객체 +├── domain/exception # 도메인 예외 +└── config # Spring Configuration +``` + +## Consequences + +**긍정**: 레이어별 책임 명확, 일관된 오류 응답, 데이터 일관성 보장, 테스트 용이성 향상 + +**부정**: 기존 코드 수정 필요, 추가 DTO/Command 클래스 필요 + +## References + +- [Spring Transaction Management](https://docs.spring.io/spring-framework/docs/current/reference/html/data-access.html#transaction) +- [RFC 7807 Problem Details](https://tools.ietf.org/html/rfc7807)