mirror of
https://github.com/cna-bootcamp/lifesub.git
synced 2025-12-06 16:16:22 +00:00
260 lines
8.2 KiB
Plaintext
260 lines
8.2 KiB
Plaintext
!theme mono
|
|
title MySubscription Service - Clean Architecture Class Diagram
|
|
|
|
' BIZ Layer
|
|
package "com.unicorn.lifesub.mysub.biz" {
|
|
package "usecase" {
|
|
package "in" {
|
|
interface TotalFeeUseCase {
|
|
+getTotalFee(userId: String): TotalFeeResponse
|
|
}
|
|
|
|
interface MySubscriptionsUseCase {
|
|
+getMySubscriptions(userId: String): List<MySubResponse>
|
|
}
|
|
|
|
interface SubscriptionDetailUseCase {
|
|
+getSubscriptionDetail(subscriptionId: Long): SubDetailResponse
|
|
}
|
|
|
|
interface SubscribeUseCase {
|
|
+subscribe(subscriptionId: Long, userId: String): void
|
|
}
|
|
|
|
interface CancelSubscriptionUseCase {
|
|
+cancel(subscriptionId: Long): void
|
|
}
|
|
|
|
interface CategoryUseCase {
|
|
+getAllCategories(): List<CategoryResponse>
|
|
+getServicesByCategory(categoryId: String): List<ServiceListResponse>
|
|
}
|
|
}
|
|
|
|
package "out" {
|
|
interface MySubscriptionReader {
|
|
+findByUserId(userId: String): List<MySubscription>
|
|
+findById(id: Long): Optional<MySubscription>
|
|
}
|
|
|
|
interface MySubscriptionWriter {
|
|
+save(userId: String, subscriptionId: Long): MySubscription
|
|
+delete(id: Long): void
|
|
}
|
|
|
|
interface SubscriptionReader {
|
|
+findById(id: Long): Optional<Subscription>
|
|
+findByCategory(category: String): List<Subscription>
|
|
+findAllCategories(): List<Category>
|
|
}
|
|
}
|
|
}
|
|
|
|
package "domain" {
|
|
class MySubscription {
|
|
-id: Long
|
|
-userId: String
|
|
-subscription: Subscription
|
|
+getPrice(): int
|
|
}
|
|
|
|
class Subscription {
|
|
-id: Long
|
|
-name: String
|
|
-description: String
|
|
-category: String
|
|
-price: int
|
|
-maxSharedUsers: int
|
|
-logoUrl: String
|
|
}
|
|
|
|
class Category {
|
|
-categoryId: String
|
|
-name: String
|
|
}
|
|
}
|
|
|
|
package "service" {
|
|
class MySubscriptionService {
|
|
-mySubscriptionReader: MySubscriptionReader
|
|
-mySubscriptionWriter: MySubscriptionWriter
|
|
-subscriptionReader: SubscriptionReader
|
|
-collectorThreshold: long
|
|
-addictThreshold: long
|
|
+getTotalFee(userId: String): TotalFeeResponse
|
|
+getMySubscriptions(userId: String): List<MySubResponse>
|
|
+getSubscriptionDetail(subscriptionId: Long): SubDetailResponse
|
|
+subscribe(subscriptionId: Long, userId: String): void
|
|
+cancel(subscriptionId: Long): void
|
|
+getAllCategories(): List<CategoryResponse>
|
|
+getServicesByCategory(categoryId: String): List<ServiceListResponse>
|
|
-calculateFeeLevel(totalFee: long): String
|
|
}
|
|
|
|
enum FeeLevel {
|
|
LIKFER
|
|
COLLECTOR
|
|
ADDICT
|
|
}
|
|
}
|
|
|
|
package "dto" {
|
|
class TotalFeeResponse {
|
|
-totalFee: Long
|
|
-feeLevel: String
|
|
}
|
|
|
|
class MySubResponse {
|
|
-id: Long
|
|
-serviceName: String
|
|
-logoUrl: String
|
|
}
|
|
|
|
class SubDetailResponse {
|
|
-serviceName: String
|
|
-logoUrl: String
|
|
-category: String
|
|
-description: String
|
|
-price: int
|
|
-maxSharedUsers: int
|
|
}
|
|
|
|
class CategoryResponse {
|
|
-categoryId: String
|
|
-categoryName: String
|
|
}
|
|
|
|
class ServiceListResponse {
|
|
-serviceId: String
|
|
-serviceName: String
|
|
-description: String
|
|
-price: int
|
|
-logoUrl: String
|
|
}
|
|
}
|
|
}
|
|
|
|
' INFRA Layer
|
|
package "com.unicorn.lifesub.mysub.infra" {
|
|
package "controller" {
|
|
class MySubController {
|
|
-totalFeeUseCase: TotalFeeUseCase
|
|
-mySubscriptionsUseCase: MySubscriptionsUseCase
|
|
+getTotalFee(userId: String): ResponseEntity<ApiResponse<TotalFeeResponse>>
|
|
+getMySubscriptions(userId: String): ResponseEntity<ApiResponse<List<MySubResponse>>>
|
|
}
|
|
|
|
class ServiceController {
|
|
-subscriptionDetailUseCase: SubscriptionDetailUseCase
|
|
-subscribeUseCase: SubscribeUseCase
|
|
-cancelSubscriptionUseCase: CancelSubscriptionUseCase
|
|
+getSubscriptionDetail(subscriptionId: Long): ResponseEntity<ApiResponse<SubDetailResponse>>
|
|
+subscribe(subscriptionId: Long, userId: String): ResponseEntity<ApiResponse<Void>>
|
|
+cancel(subscriptionId: Long): ResponseEntity<ApiResponse<Void>>
|
|
}
|
|
|
|
class CategoryController {
|
|
-categoryUseCase: CategoryUseCase
|
|
+getAllCategories(): ResponseEntity<ApiResponse<List<CategoryResponse>>>
|
|
+getServicesByCategory(categoryId: String): ResponseEntity<ApiResponse<List<ServiceListResponse>>>
|
|
}
|
|
}
|
|
|
|
package "gateway" {
|
|
class MySubscriptionGateway implements MySubscriptionReader, MySubscriptionWriter {
|
|
-mySubscriptionRepository: MySubscriptionJpaRepository
|
|
-subscriptionRepository: SubscriptionJpaRepository
|
|
}
|
|
|
|
class SubscriptionGateway implements SubscriptionReader {
|
|
-subscriptionRepository: SubscriptionJpaRepository
|
|
-categoryRepository: CategoryJpaRepository
|
|
}
|
|
|
|
package "repository" {
|
|
interface MySubscriptionJpaRepository {
|
|
+findByUserId(userId: String): List<MySubscriptionEntity>
|
|
+findBySubscription_Id(subscriptionId: Long): Optional<MySubscriptionEntity>
|
|
}
|
|
|
|
interface SubscriptionJpaRepository {
|
|
+findById(id: Long): Optional<SubscriptionEntity>
|
|
+findByCategory(category: String): List<SubscriptionEntity>
|
|
}
|
|
|
|
interface CategoryJpaRepository {
|
|
+findAll(): List<CategoryEntity>
|
|
}
|
|
}
|
|
|
|
package "entity" {
|
|
class MySubscriptionEntity {
|
|
-id: Long
|
|
-userId: String
|
|
-subscription: SubscriptionEntity
|
|
+toDomain(): MySubscription
|
|
}
|
|
|
|
class SubscriptionEntity {
|
|
-id: Long
|
|
-name: String
|
|
-description: String
|
|
-category: String
|
|
-price: int
|
|
-maxSharedUsers: int
|
|
-logoUrl: String
|
|
+toDomain(): Subscription
|
|
}
|
|
|
|
class CategoryEntity {
|
|
-categoryId: String
|
|
-name: String
|
|
+toDomain(): Category
|
|
}
|
|
}
|
|
}
|
|
|
|
package "config" {
|
|
class SecurityConfig {
|
|
-jwtTokenProvider: JwtTokenProvider
|
|
+securityFilterChain(http: HttpSecurity): SecurityFilterChain
|
|
+corsConfigurationSource(): CorsConfigurationSource
|
|
}
|
|
|
|
class SwaggerConfig {
|
|
+openAPI(): OpenAPI
|
|
}
|
|
|
|
class DataLoader {
|
|
-categoryRepository: CategoryJpaRepository
|
|
-subscriptionRepository: SubscriptionJpaRepository
|
|
+run(): void
|
|
}
|
|
}
|
|
}
|
|
|
|
' Relationships
|
|
MySubscriptionService ..|> TotalFeeUseCase
|
|
MySubscriptionService ..|> MySubscriptionsUseCase
|
|
MySubscriptionService ..|> SubscriptionDetailUseCase
|
|
MySubscriptionService ..|> SubscribeUseCase
|
|
MySubscriptionService ..|> CancelSubscriptionUseCase
|
|
MySubscriptionService ..|> CategoryUseCase
|
|
|
|
MySubController --> TotalFeeUseCase
|
|
MySubController --> MySubscriptionsUseCase
|
|
ServiceController --> SubscriptionDetailUseCase
|
|
ServiceController --> SubscribeUseCase
|
|
ServiceController --> CancelSubscriptionUseCase
|
|
CategoryController --> CategoryUseCase
|
|
|
|
MySubscriptionGateway --> MySubscriptionJpaRepository
|
|
MySubscriptionGateway --> SubscriptionJpaRepository
|
|
SubscriptionGateway --> SubscriptionJpaRepository
|
|
SubscriptionGateway --> CategoryJpaRepository
|
|
|
|
MySubscriptionEntity ..> MySubscription : converts to
|
|
SubscriptionEntity ..> Subscription : converts to
|
|
CategoryEntity ..> Category : converts to
|
|
|
|
MySubscription --> Subscription |