Compare commits
16 commits
forge/runt
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 9ad341ae12 | |||
| e7766c6ba5 | |||
| 376786dd55 | |||
| 5a42946820 | |||
| 0469100bfe | |||
| 506761b978 | |||
| 89d0288b3d | |||
| cd04f9101b | |||
| c985f6e7bf | |||
| bd8b77feac | |||
| 3ef86bf9bf | |||
| db7ead282c | |||
| bf7772d6df | |||
| d927492ef4 | |||
| 3c1983a8d0 | |||
| 0d99314574 |
13 changed files with 340 additions and 100 deletions
|
|
@ -0,0 +1,3 @@
|
|||
# runtime-role-matrix-live-20260714101723-v7-aa-001-attempt-2-run-b63a6a7e452e
|
||||
|
||||
Forge 이슈 작업 브랜치 `forge/runtime-role-matrix-live-20260714101723-v7-aa-001-attempt-2-run-b63a6a7e452e`.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# runtime-role-matrix-live-20260714101723-v7-developer-001-attempt-1-run-e27e8d6f28aa
|
||||
|
||||
Forge 이슈 작업 브랜치 `forge/runtime-role-matrix-live-20260714101723-v7-developer-001-attempt-1-run-e27e8d6f28aa`.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# runtime-role-matrix-live-20260714101723-v7-pm-001-attempt-1-run-507b47dae85f
|
||||
|
||||
Forge 이슈 작업 브랜치 `forge/runtime-role-matrix-live-20260714101723-v7-pm-001-attempt-1-run-507b47dae85f`.
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
# runtime-role-matrix-live-20260714101723-v7-ta-001-attempt-1-run-140dc870c325
|
||||
|
||||
Forge 이슈 작업 브랜치 `forge/runtime-role-matrix-live-20260714101723-v7-ta-001-attempt-1-run-140dc870c325`.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# runtime-role-matrix-live-20260714101723-v7-ta-001-attempt-2-run-8f9fb566223b
|
||||
|
||||
Forge 이슈 작업 브랜치 `forge/runtime-role-matrix-live-20260714101723-v7-ta-001-attempt-2-run-8f9fb566223b`.
|
||||
71
audit/AA_ROLE_EVIDENCE_INVENTORY.json
Normal file
71
audit/AA_ROLE_EVIDENCE_INVENTORY.json
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
{
|
||||
"inventoryId": "AA_ROLE_EVIDENCE_INVENTORY",
|
||||
"role": "AA",
|
||||
"version": "v7",
|
||||
"generatedDate": "2026-07-14",
|
||||
"inputSources": [
|
||||
{
|
||||
"sourceId": "IS-001",
|
||||
"sourceName": "AA_ROLE_SPEC",
|
||||
"description": "AA 역할 정의 명세서",
|
||||
"location": "role-aa/specs/aa_role_spec.yaml",
|
||||
"type": "SPECIFICATION",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
{
|
||||
"sourceId": "IS-002",
|
||||
"sourceName": "PERMISSION_MATRIX",
|
||||
"description": "권한 매트릭스 문서",
|
||||
"location": "role-aa/specs/permission_matrix.json",
|
||||
"type": "MATRIX",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
{
|
||||
"sourceId": "IS-003",
|
||||
"sourceName": "WORKFLOW_DEF",
|
||||
"description": "워크플로우 정의",
|
||||
"location": "role-aa/workflows/aa_workflow.yaml",
|
||||
"type": "WORKFLOW",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
{
|
||||
"sourceId": "IS-004",
|
||||
"sourceName": "API_CONTRACT",
|
||||
"description": "API 계약 정의",
|
||||
"location": "role-aa/contracts/aa_api_contract.yaml",
|
||||
"type": "CONTRACT",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
],
|
||||
"evidenceLocations": [
|
||||
{
|
||||
"evidenceId": "EV-001",
|
||||
"sourceId": "IS-001",
|
||||
"type": "ROLE_DEFINITION",
|
||||
"verificationMethod": "스키마 검증"
|
||||
},
|
||||
{
|
||||
"evidenceId": "EV-002",
|
||||
"sourceId": "IS-002",
|
||||
"type": "PERMISSION_MATRIX",
|
||||
"verificationMethod": "매트릭스 교차 검증"
|
||||
},
|
||||
{
|
||||
"evidenceId": "EV-003",
|
||||
"sourceId": "IS-003",
|
||||
"type": "WORKFLOW_LOG",
|
||||
"verificationMethod": "실행 추적 검증"
|
||||
},
|
||||
{
|
||||
"evidenceId": "EV-004",
|
||||
"sourceId": "IS-004",
|
||||
"type": "API_CALL_LOG",
|
||||
"verificationMethod": "요청/응답 검증"
|
||||
}
|
||||
],
|
||||
"auditRequirements": {
|
||||
"versionControl": true,
|
||||
"changeTracking": true,
|
||||
"retentionPeriod": "7years"
|
||||
}
|
||||
}
|
||||
57
audit/AA_ROLE_LEGACY_ANALYSIS.md
Normal file
57
audit/AA_ROLE_LEGACY_ANALYSIS.md
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
# AA 역할 레거시 분석 문서
|
||||
|
||||
## 개요
|
||||
- **역할**: AA
|
||||
- **분석 일자**: 2026-07-14
|
||||
- **버전**: v7
|
||||
- **분석 목적**: 레거시 전환 분석을 위한 입력 소스, 업무 규칙, 위험 영역, 증적 위치 정리
|
||||
|
||||
---
|
||||
|
||||
## 1. 입력 소스 정의
|
||||
|
||||
| ID | 소스명 | 설명 | 위치 |
|
||||
|-----|--------|------|------|
|
||||
| IS-001 | AA_ROLE_SPEC | AA 역할 정의 명세서 | role-aa/specs/aa_role_spec.yaml |
|
||||
| IS-002 | PERMISSION_MATRIX | 권한 매트릭스 문서 | role-aa/specs/permission_matrix.json |
|
||||
| IS-003 | WORKFLOW_DEF | 워크플로우 정의 | role-aa/workflows/aa_workflow.yaml |
|
||||
| IS-004 | API_CONTRACT | API 계약 정의 | role-aa/contracts/aa_api_contract.yaml |
|
||||
|
||||
---
|
||||
|
||||
## 2. 업무 규칙
|
||||
|
||||
| 규칙 ID | 규칙 내용 | 입력 소스 |
|
||||
|---------|----------|----------|
|
||||
| BR-001 | AA 역할은 관리자 권한을 포함한다 | IS-001, IS-002 |
|
||||
| BR-002 | AA 역할은 승인 워크플로우를 통과해야 한다 | IS-003 |
|
||||
| BR-003 | AA 역할의 API 호출은 인증 토큰을 필요로 한다 | IS-004 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 위험 영역
|
||||
|
||||
| 위험 ID | 위험 설명 | 영향도 | 입력 소스 |
|
||||
|---------|----------|--------|----------|
|
||||
| RI-001 | 권한 상승 위험 | 높음 | IS-001, IS-002 |
|
||||
| RI-002 | 워크플로우 우회 위험 | 중간 | IS-003 |
|
||||
| RI-003 | API 인증 우회 위험 | 높음 | IS-004 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 증적 위치
|
||||
|
||||
| 증적 ID | 증적 유형 | 위치 | 검증 방법 |
|
||||
|---------|----------|------|----------|
|
||||
| EV-001 | 역할 정의 | IS-001 | 스키마 검증 |
|
||||
| EV-002 | 권한 매트릭스 | IS-002 | 매트릭스 교차 검증 |
|
||||
| EV-003 | 워크플로우 로그 | IS-003 | 실행 추적 검증 |
|
||||
| EV-004 | API 호출 로그 | IS-004 | 요청/응답 검증 |
|
||||
|
||||
---
|
||||
|
||||
## 5. 감사 추적 요구사항
|
||||
|
||||
- 모든 입력 소스는 버전 관리되어야 함
|
||||
- 변경 이력은 추적 가능해야 함
|
||||
- 증적은 보존 기간 동안 유지되어야 함
|
||||
|
|
@ -1,113 +1,49 @@
|
|||
# ADR-001: Spring 경계 아키텍처 정의
|
||||
# ADR-001: Spring Layer Boundary Architecture
|
||||
|
||||
**날짜**: 2026-07-14
|
||||
**상태**: 수락됨
|
||||
**결정자**: TA 아키텍트
|
||||
## Context
|
||||
|
||||
---
|
||||
TA 역할의 Spring 기반 마이크로서비스는 역할 매트릭스 관리 기능을 제공한다. Controller-Service-Repository 패턴을 적용하되, 각 계층의 책임과 경계를 명확히 정의하여 응집도를 높이고 결합도를 낮추어야 한다. 또한 오류 처리와 트랜잭션 관리의 일관된 전략이 필요하다.
|
||||
|
||||
## Context (배경)
|
||||
## Decision
|
||||
|
||||
TA 역할 프로젝트는 역할(Role) 기반 접근 제어 시스템을 구현한다. 다중 계층 구조에서 Controller, Service, Repository 각 계층의 책임 범위, 오류 계약, 트랜잭션 경계를 명확히 정의하지 않으면 다음과 같은 문제가 발생한다.
|
||||
### 1. Controller-Service-Repository 경계
|
||||
|
||||
- **책임 혼재**: 비즈니스 로직이 Controller에 유출되거나, DB 접근 로직이 Service에 직접 작성
|
||||
- **일관성 없는 오류 처리**: 각 계층마다 다른 예외 타입과 HTTP 상태 코드를 반환
|
||||
- **트랜잭션 누락/과다**: 읽기 전용 쿼리에 불필요한 트랜잭션이 걸리거나, 다중 쓰기 작업이 원자성 없이 실행
|
||||
- **테스트 어려움**: 계층 간 결합으로 인해 단위 테스트가 불가능
|
||||
|
||||
---
|
||||
|
||||
## Decision (결정)
|
||||
|
||||
### 1. 계층 책임 경계
|
||||
|
||||
| 계층 | 책임 | 포함 사항 | 금지 사항 |
|
||||
|------|------|-----------|-----------|
|
||||
| **Controller** | HTTP 요청/응답 변환, 입력 검증, 라우팅 | `@RequestMapping`, `@Valid`, `@RequestBody` 파싱, 응답 DTO 변환 | 비즈니스 로직 직접 실행, DB 접근, Service 메서드 직접 호출 없이 로직 처리 |
|
||||
| **Service** | 비즈니스 로직, 트랜잭션 관리, 도메인 조율 | `@Transactional`, 도메인 객체 조작, 다중 Repository 호출, 정책 enforcement | HTTP 요청/응답 직접 처리, SQL 직접 작성, `@Entity` 직접 매핑 반환 |
|
||||
| **Repository** | 데이터 접근 추상화, 쿼리 실행 | `JpaRepository` 확장, `@Query`, `EntityManager` 직접 사용, Specification 패턴 | 비즈니스 로직, 트랜잭션 경계 설정, 응답 형식 결정 |
|
||||
| Layer | Responsibility | Forbidden Dependencies |
|
||||
|-------|---------------|------------------------|
|
||||
| Controller | HTTP 요청/응답 변환, 입력 검증, HTTP 상태 코드 관리 | 직접 Repository 접근 금지 |
|
||||
| Service | 비즈니스 로직, 도메인 규칙, 트랜잭션 경계 | HTTP Servlet API 직접 사용 금지 |
|
||||
| Repository | 데이터 접근, JPA 쿼리, 엔티티 매핑 | 비즈니스 로직 포함 금지 |
|
||||
|
||||
### 2. 오류 계약 (Error Contract)
|
||||
|
||||
모든 계층에서 발생하는 예외는 **단일 예외 계층 구조**로 변환되어 Controller에서 일관된 HTTP 응답을 생성한다.
|
||||
|
||||
```
|
||||
BaseException (추상)
|
||||
├── BusinessException → HTTP 400 (잘못된 요청)
|
||||
│ ├── RoleNotFoundException
|
||||
│ ├── DuplicateRoleException
|
||||
│ └── InvalidRoleStateException
|
||||
├── AuthorizationException → HTTP 403 (권한 없음)
|
||||
└── SystemException → HTTP 500 (서버 오류)
|
||||
├── DataAccessException
|
||||
└── ExternalServiceException
|
||||
```
|
||||
|
||||
**오류 응답 형식 (RFC 7807 Problem Details)**:
|
||||
```json
|
||||
{
|
||||
"type": "https://api.example.com/errors/role-not-found",
|
||||
"title": "Role Not Found",
|
||||
"status": 404,
|
||||
"detail": "Role with id '123' does not exist",
|
||||
"instance": "/api/v1/roles/123",
|
||||
"timestamp": "2026-07-14T10:17:23Z"
|
||||
}
|
||||
```
|
||||
|
||||
**계약 규칙**:
|
||||
- Service 계층은 `BusinessException` 하위 타입만 던진다
|
||||
- Repository 계층 예외는 Service 계층에서 `SystemException`으로 래핑한다
|
||||
- Controller는 `@ControllerAdvice`에서 전역 예외를 처리한다
|
||||
- 예외 메시지는 외부 노출용으로 **사용자 친화적**이어야 한다
|
||||
| Scenario | HTTP Status | Response Body |
|
||||
|----------|-------------|---------------|
|
||||
| Validation Error | 400 | `{ "code": "VALIDATION_ERROR", "message": "...", "field": "..." }` |
|
||||
| Resource Not Found | 404 | `{ "code": "NOT_FOUND", "message": "...", "resourceId": "..." }` |
|
||||
| Business Rule Violation | 409 | `{ "code": "BUSINESS_ERROR", "message": "..." }` |
|
||||
| Internal Error | 500 | `{ "code": "INTERNAL_ERROR", "message": "..." }` |
|
||||
|
||||
### 3. 트랜잭션 경계
|
||||
|
||||
| 시나리오 | 전파 방식 | 격리 수준 | 읽기 전용 |
|
||||
|----------|-----------|-----------|-----------|
|
||||
| 단일 조회 (findById) | REQUIRED | DEFAULT | true |
|
||||
| 목록 조회 (findAll) | REQUIRED | DEFAULT | true |
|
||||
| 단일 생성 (save) | REQUIRED | DEFAULT | false |
|
||||
| 벌크 업데이트 (bulk update) | REQUIRED | READ_COMMITTED | false |
|
||||
| 다중 리포지토리 쓰기 | REQUIRED | READ_COMMITTED | false |
|
||||
| 읽기 전용 조회 (통계/리포트) | REQUIRED_READ_ONLY | DEFAULT | true |
|
||||
- **시작점**: Service Layer (public method 진입점)
|
||||
- **종료점**: Service Layer (public method 종료점)
|
||||
- **전파**: `@Transactional(propagation = REQUIRED)` 기본값 사용
|
||||
- **읽기 전용**: 조회 전용 Service Method에 `@Transactional(readOnly = true)` 적용
|
||||
|
||||
**트랜잭션 롤백 규칙**:
|
||||
- `RuntimeException`, `DataAccessException`은 자동 롤백
|
||||
- 검사 예외(`Checked Exception`)는 명시적 `rollbackFor` 지정 필요
|
||||
- 읽기 전용 트랜잭션에서 쓰기 시도 시 예외 발생
|
||||
## Alternatives
|
||||
|
||||
---
|
||||
1. **TransactionTemplate 사용**: 프로그래밍 방식 트랜잭션 관리로 더 세밀한 제어 가능하나, 선언적 방식 대비 복잡성 증가
|
||||
2. **Controller에서 트랜잭션 관리**: 테스트 용이성 감소, 단일 책임 원칙 위반
|
||||
3. **Repository에서 비즈니스 로직 포함**: 데이터 접근 계층의 재사용성 저하
|
||||
|
||||
## Alternatives (대안)
|
||||
## Consequences
|
||||
|
||||
### 대안 1: Service에서 직접 예외 던지기 (현재 미선택)
|
||||
- 각 Service 메서드가 다양한 예외 타입을 직접 던짐
|
||||
- **단점**: Controller에서 예외 타입별 분기 처리 필요, 일관성 유지 어려움
|
||||
### Positive
|
||||
- 계층별 단일 책임 원칙 준수
|
||||
- 일관된 오류 처리로 API consumers 보호
|
||||
- 트랜잭션 경계 명확화로 데이터 무결성 보장
|
||||
- 테스트 용이성 향상 (Mock 주입 용이)
|
||||
|
||||
### 대안 2: 트랜잭션 없음 (수동 커밋)
|
||||
- `TransactionTemplate`을 수동으로 사용
|
||||
- **단점**: 코드 복잡성 증가, 실수 가능성 높음
|
||||
|
||||
### 대안 3: Repository에서 비즈니스 로직 포함
|
||||
- **단점**: 데이터 접근과 비즈니스 로직 결합, 테스트 어려움, 재사용성 저하
|
||||
|
||||
---
|
||||
|
||||
## Consequences (결과)
|
||||
|
||||
### 긍정적 결과
|
||||
- **단위 테스트 용이**: 각 계층이 명확히 분리되어 Mock 기반 테스트 가능
|
||||
- **유지보수성**: 오류 처리와 트랜잭션 정책이 한 곳에 집중
|
||||
- **일관성**: 모든 API가 동일한 오류 응답 형식 제공
|
||||
- **확장성**: 새 예외 타입 추가 시 `BaseException` 하위 클래스만 생성
|
||||
|
||||
### 부정적 결과
|
||||
- **초기 개발 시간**: 예외 계층 구조와 `@ControllerAdvice` 설정 필요
|
||||
- **학습 곡선**: 개발자가 계층 책임 경계와 트랜잭션 전파 규칙을 숙지해야 함
|
||||
- **오버엔지니어링 위험**: 소규모 프로젝트에서는 과한 추상화 가능성
|
||||
|
||||
### 모니터링 지표
|
||||
- 예외 발생 시 `type` 필드로 문제 유형 추적
|
||||
- 트랜잭션 경과 시간 로깅으로 성능 병목 탐지
|
||||
- 계층 간 호출 횟수 카운터로 불필요한 조회 감지
|
||||
### Negative
|
||||
- 간단한 CRUD 연산에도 Service Layer 필요로 인한 코드 증가
|
||||
- 트랜잭션 경계 설정 오류 시 롤백 누락 위험
|
||||
|
|
|
|||
39
pom.xml
Normal file
39
pom.xml
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.2.5</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
<groupId>com.example</groupId>
|
||||
<artifactId>developer-role-smoke</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<name>Developer Role Smoke Test</name>
|
||||
<description>Spring Boot smoke application for Developer role</description>
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
69
role-pm/HANDOVER.md
Normal file
69
role-pm/HANDOVER.md
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
# PM 역할 인수인계 문서
|
||||
|
||||
**프로젝트**: runtime-role-matrix-live-20260714101723-v7
|
||||
**작성일**: 2025-07-14
|
||||
**버전**: v7
|
||||
|
||||
---
|
||||
|
||||
## 1. 프로젝트 목표
|
||||
|
||||
| 목표 | 설명 |
|
||||
|------|------|
|
||||
| 핵심 | 런타임 역할 매트릭스 라이브 데모 시스템 구축 및 운영 |
|
||||
| 세부 | 역할 기반 접근 제어(RBAC) 매트릭스를 런타임에 동적 렌더링하는 시스템 |
|
||||
| 기대산출물 | 설정 파일 기반 역할-권한 매핑, 실시간 UI 갱신, smoke 테스트 통과 |
|
||||
|
||||
---
|
||||
|
||||
## 2. 완료 기준
|
||||
|
||||
- [ ] 역할 매트릭스 설정 파일(JSON/YAML) 파싱 정상 동작
|
||||
- [ ] 런타임 시 역할-권한 매핑 동적 로딩
|
||||
- [ ] UI 컴포넌트에서 매트릭스 렌더링 확인
|
||||
- [ ] smoke 테스트 100% 통과
|
||||
- [ ] 빌드 산출물 생성 및 배포 가능 상태
|
||||
|
||||
---
|
||||
|
||||
## 3. 위험 (Risks)
|
||||
|
||||
| ID | 위험 항목 | 영향 | 완화 방안 |
|
||||
|----|-----------|------|----------|
|
||||
| R-01 | 역할 매트릭스 설정 변경 시 런타임 반영 지연 | 중간 | 설정 변경 감시(watch) 모드 구현 |
|
||||
| R-02 | 권한 검증 로직 누락 가능성 | 높음 | 단위 테스트 커버리지 80% 이상 확보 |
|
||||
| R-03 | 동시 접근 시 데이터 정합성 | 중간 | 락(lock) 또는 트랜잭션 처리 검토 |
|
||||
| R-04 | 의존성 버전 충돌 | 낮음 | BOM 기반 명시적 버전 관리 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 다음 액션 (Next Actions)
|
||||
|
||||
| 순서 | 액션 | 담당 | 기한 |
|
||||
|------|------|------|------|
|
||||
| 1 | smoke 테스트 실행 및 결과 공유 | PM | D+1 |
|
||||
| 2 | 역할 매트릭스 설정 파일 스키마 확정 | PM | D+2 |
|
||||
| 3 | 런타임 갱신 메커니즘 설계안 검토 | PM | D+3 |
|
||||
| 4 | 위험 R-02 관련 테스트 커버리지 보고서 확인 | PM | D+5 |
|
||||
| 5 | 인수인계 완료 보고서 제출 | PM | D+7 |
|
||||
|
||||
---
|
||||
|
||||
## 5. 주요 의사결정 로그
|
||||
|
||||
| 일자 | 결정 | 사유 |
|
||||
|------|------|------|
|
||||
| 2025-07-14 | BOM 기반 의존성 관리 채택 | 일관된 버전 관리 및 충돌 방지 |
|
||||
| 2025-07-14 | smoke 테스트 우선 통과 전략 | 빠른 피드백 루프 확보 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 연락처 및 참고자료
|
||||
|
||||
- **이전 PM**: role-pm 컨텍스트 참조
|
||||
- **문서 위치**: `role-pm/HANDOVER.md`
|
||||
- **테스트 명령**: `mvn test` (Maven 기준)
|
||||
|
||||
---
|
||||
|
||||
*본 문서는 프로젝트 인수인계 시 작성되며, 후임 PM이 참조해야 할 핵심 정보를 포함함.*
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.example.developer;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class DeveloperApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(DeveloperApplication.class, args);
|
||||
}
|
||||
}
|
||||
15
src/main/java/com/example/developer/DeveloperService.java
Normal file
15
src/main/java/com/example/developer/DeveloperService.java
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
package com.example.developer;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class DeveloperService {
|
||||
|
||||
public String getRole() {
|
||||
return "Developer";
|
||||
}
|
||||
|
||||
public boolean isValidRole(String role) {
|
||||
return "Developer".equals(role);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package com.example.developer;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@SpringBootTest
|
||||
class DeveloperServiceTest {
|
||||
|
||||
@Autowired
|
||||
private DeveloperService developerService;
|
||||
|
||||
@Test
|
||||
void getRole_returnsDeveloper() {
|
||||
String role = developerService.getRole();
|
||||
assertTrue("Developer".equals(role), "Role should be Developer");
|
||||
}
|
||||
|
||||
@Test
|
||||
void isValidRole_withDeveloper_returnsTrue() {
|
||||
boolean valid = developerService.isValidRole("Developer");
|
||||
assertTrue(valid, "Developer role should be valid");
|
||||
}
|
||||
|
||||
@Test
|
||||
void isValidRole_withOtherRole_returnsFalse() {
|
||||
boolean valid = developerService.isValidRole("Admin");
|
||||
assertTrue(!valid, "Admin role should not be valid for DeveloperService");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue