jhbkjh 3075a5d49f 물리아키텍처 설계 완료
 주요 기능
- Azure 기반 물리아키텍처 설계 (개발환경/운영환경)
- 7개 마이크로서비스 물리 구조 설계
- 네트워크 아키텍처 다이어그램 작성 (Mermaid)
- 환경별 비교 분석 및 마스터 인덱스 문서

📁 생성 파일
- design/backend/physical/physical-architecture.md (마스터)
- design/backend/physical/physical-architecture-dev.md (개발환경)
- design/backend/physical/physical-architecture-prod.md (운영환경)
- design/backend/physical/*.mmd (4개 Mermaid 다이어그램)

🎯 핵심 성과
- 비용 최적화: 개발환경 월 $143, 운영환경 월 $2,860
- 확장성: 개발환경 100명 → 운영환경 10,000명 (100배)
- 가용성: 개발환경 95% → 운영환경 99.9%
- 보안: 다층 보안 아키텍처 (L1~L4)

🛠️ 기술 스택
- Azure Kubernetes Service (AKS)
- Azure Database for PostgreSQL Flexible
- Azure Cache for Redis Premium
- Azure Service Bus Premium
- Application Gateway + WAF

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 15:13:01 +09:00

189 lines
7.2 KiB
Plaintext

@startuml
!theme mono
title 공통 컴포넌트 클래스 다이어그램
package "com.kt.event.common" {
package "entity" {
abstract class BaseTimeEntity {
- createdAt: LocalDateTime
- updatedAt: LocalDateTime
}
}
package "dto" {
class "ApiResponse<T>" {
- success: boolean
- data: T
- errorCode: String
- message: String
- timestamp: LocalDateTime
+ success(data: T): ApiResponse<T>
+ success(): ApiResponse<T>
+ error(errorCode: String, message: String): ApiResponse<T>
}
class ErrorResponse {
- success: boolean
- errorCode: String
- message: String
- timestamp: LocalDateTime
- details: Map<String, Object>
+ of(errorCode: ErrorCode): ErrorResponse
+ of(errorCode: ErrorCode, details: Map<String, Object>): ErrorResponse
}
class "PageResponse<T>" {
- content: List<T>
- totalElements: long
- totalPages: int
- number: int
- size: int
- first: boolean
- last: boolean
+ of(content: List<T>, pageable: Pageable, total: long): PageResponse<T>
}
}
package "exception" {
interface ErrorCode {
+ getCode(): String
+ getMessage(): String
}
enum CommonErrorCode implements ErrorCode {
COMMON_001
COMMON_002
COMMON_003
COMMON_004
COMMON_005
NOT_FOUND
INVALID_INPUT_VALUE
AUTH_001 ~ AUTH_005
USER_001 ~ USER_005
EVENT_001 ~ EVENT_005
JOB_001 ~ JOB_004
AI_001 ~ AI_004
CONTENT_001 ~ CONTENT_004
DIST_001 ~ DIST_004
PART_001 ~ PART_008
ANALYTICS_001 ~ ANALYTICS_003
EXTERNAL_001 ~ EXTERNAL_003
DB_001 ~ DB_004
REDIS_001 ~ REDIS_003
KAFKA_001 ~ KAFKA_003
- code: String
- message: String
+ getCode(): String
+ getMessage(): String
}
class BusinessException extends RuntimeException {
- errorCode: ErrorCode
- details: String
+ BusinessException(errorCode: ErrorCode)
+ BusinessException(errorCode: ErrorCode, message: String)
+ BusinessException(errorCode: ErrorCode, message: String, details: String)
+ BusinessException(errorCode: ErrorCode, cause: Throwable)
+ BusinessException(errorCode: ErrorCode, message: String, details: String, cause: Throwable)
+ getErrorCode(): ErrorCode
+ getDetails(): String
}
class InfraException extends RuntimeException {
- errorCode: ErrorCode
- details: String
+ InfraException(errorCode: ErrorCode)
+ InfraException(errorCode: ErrorCode, message: String)
+ InfraException(errorCode: ErrorCode, cause: Throwable)
+ getErrorCode(): ErrorCode
+ getDetails(): String
}
}
package "util" {
class ValidationUtil {
+ requireNonNull(object: Object, errorCode: ErrorCode): void
+ requireNonNull(object: Object, errorCode: ErrorCode, message: String): void
+ requireNotBlank(str: String, errorCode: ErrorCode): void
+ requireNotBlank(str: String, errorCode: ErrorCode, message: String): void
+ require(condition: boolean, errorCode: ErrorCode): void
+ require(condition: boolean, errorCode: ErrorCode, message: String): void
+ requireValidPhoneNumber(phoneNumber: String, errorCode: ErrorCode): void
+ requireValidEmail(email: String, errorCode: ErrorCode): void
+ requireValidBusinessNumber(businessNumber: String, errorCode: ErrorCode): void
+ requirePositive(value: long, errorCode: ErrorCode): void
+ requireNonNegative(value: long, errorCode: ErrorCode): void
+ requireInRange(value: long, min: long, max: long, errorCode: ErrorCode): void
}
class StringUtil {
+ isBlank(str: String): boolean
+ isNotBlank(str: String): boolean
+ hasText(str: String): boolean
+ isEmpty(str: String): boolean
+ isNotEmpty(str: String): boolean
+ isValidEmail(email: String): boolean
+ isValidPhoneNumber(phoneNumber: String): boolean
+ isValidBusinessNumber(businessNumber: String): boolean
+ maskEmail(email: String): String
+ maskPhoneNumber(phoneNumber: String): String
+ generateRandomString(length: int): String
+ removeSpecialCharacters(str: String): String
}
class DateTimeUtil {
+ now(): LocalDateTime
+ nowZoned(): ZonedDateTime
+ toEpochMilli(dateTime: LocalDateTime): long
+ fromEpochMilli(epochMilli: long): LocalDateTime
+ format(dateTime: LocalDateTime, pattern: String): String
+ parse(dateTimeString: String, pattern: String): LocalDateTime
+ isAfter(dateTime1: LocalDateTime, dateTime2: LocalDateTime): boolean
+ isBefore(dateTime1: LocalDateTime, dateTime2: LocalDateTime): boolean
+ isDateInRange(target: LocalDateTime, start: LocalDateTime, end: LocalDateTime): boolean
+ getDaysBetween(start: LocalDateTime, end: LocalDateTime): long
}
class EncryptionUtil {
+ encrypt(plainText: String): String
+ decrypt(encryptedText: String): String
+ hash(plainText: String): String
+ matches(plainText: String, hashedText: String): boolean
+ generateSalt(): String
+ encryptWithSalt(plainText: String, salt: String): String
}
}
package "security" {
class JwtAuthenticationFilter extends OncePerRequestFilter {
- jwtTokenProvider: JwtTokenProvider
- userDetailsService: UserDetailsService
+ doFilterInternal(request: HttpServletRequest, response: HttpServletResponse, filterChain: FilterChain): void
- extractTokenFromRequest(request: HttpServletRequest): String
- authenticateUser(token: String): void
}
interface JwtTokenProvider {
+ generateToken(userDetails: UserDetails): String
+ validateToken(token: String): boolean
+ getUsernameFromToken(token: String): String
+ getExpirationDateFromToken(token: String): Date
}
}
}
' 관계 정의
BusinessException --> ErrorCode : uses
InfraException --> ErrorCode : uses
ValidationUtil --> ErrorCode : uses
ValidationUtil --> StringUtil : uses
ErrorResponse --> ErrorCode : uses
note top of BaseTimeEntity : JPA Auditing을 위한 기본 엔티티\n모든 도메인 엔티티가 상속
note top of "ApiResponse<T>" : 모든 API 응답을 감싸는\n표준 응답 포맷
note top of CommonErrorCode : 시스템 전체에서 사용하는\n표준 에러 코드
note top of ValidationUtil : 비즈니스 로직에서 사용하는\n공통 유효성 검증 기능
@enduml