mirror of
https://github.com/ktds-dg0501/kt-event-marketing.git
synced 2025-12-06 21:26:24 +00:00
✨ 주요 기능 - 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>
189 lines
7.2 KiB
Plaintext
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 |