Final-08-Evan-Jap-Bambang-W.../ooad-docs/07_ChainOfResponsibility_Pattern.puml

138 lines
4.4 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

' ============================================================
' WALKGUIDE — DESIGN PATTERNS (GoF)
' Flutter × Spring Boot × In-Device AI
' Pattern 7 of 7: CHAIN OF RESPONSIBILITY (Behavioral)
' ============================================================
@startuml WalkGuide_07_ChainOfResponsibility
skinparam monochrome false
skinparam shadowing false
skinparam defaultFontName Arial
skinparam defaultFontSize 12
skinparam roundCorner 10
skinparam ArrowColor #555555
skinparam ArrowThickness 1.2
skinparam class {
BackgroundColor #FAFAFA
BorderColor #AAAAAA
HeaderBackgroundColor #E8E8E8
FontColor #222222
StereotypeFontColor #666666
AttributeFontColor #333333
}
skinparam package {
BackgroundColor #F5F5F5
BorderColor #888888
FontColor #333333
FontStyle bold
}
skinparam note {
BackgroundColor #FFFDE7
BorderColor #F9A825
FontColor #444444
FontSize 11
}
' ============================================================
' PATTERN 7 — CHAIN OF RESPONSIBILITY (Behavioral)
' ============================================================
package "⑦ Chain of Responsibility [Behavioral]" #FCE4EC {
' --- Flutter: Dio Interceptor Chain ---
abstract class "Interceptor\n<<Handler>>" as DioInterceptor {
+ onRequest(options, handler)
+ onResponse(response, handler)
+ onError(error, handler)
}
class "AuthInterceptor\n<<ConcreteHandler>>" as AuthInterceptor {
- _secureStorage : FlutterSecureStorage
+ onRequest(options, handler)
' Attach Bearer token ke setiap request
+ onError(error, handler)
' Jika 401: refresh token → retry request
}
class "ErrorInterceptor\n<<ConcreteHandler>>" as ErrorInterceptor {
+ onError(error, handler)
' Map HTTP error codes → Failure domain objects
' 401 → UnauthorizedFailure
' 404 → NotFoundFailure
' 500 → ServerFailure
}
class "LogInterceptor\n<<ConcreteHandler>>" as LogInterceptorFlutter {
+ onRequest(options, handler)
+ onResponse(response, handler)
+ onError(error, handler)
' Print request/response untuk debugging
}
class "ApiClient\n<<Dio>>" as ApiClient {
- _dio : Dio
+ get(url) : Response
+ post(url, data) : Response
+ put(url, data) : Response
' Interceptors dieksekusi berurutan
}
' --- Backend: Spring Security Filter Chain ---
abstract class "OncePerRequestFilter\n<<Handler>>" as SpringFilter {
+ {abstract} doFilterInternal(req, res, chain)
+ doFilter(req, res, chain)
}
class "JwtAuthFilter\n<<ConcreteHandler>>" as JwtAuthFilter {
- _jwtUtil : JwtUtil
- _userDetailsService : UserDetailsService
+ doFilterInternal(req, res, chain)
' Extract JWT → validate → set SecurityContext
' Jika invalid: 401 Unauthorized langsung
}
class "SecurityConfig\n<<Config/Handler>>" as SecurityConfigChain {
+ securityFilterChain(http) : SecurityFilterChain
' /auth/** → permitAll
' /api/v1/** → authenticated
' ROLE_GUARDIAN vs ROLE_USER routing
}
class "Controller\n<<Endpoint>>" as ControllerChain {
+ handleRequest(request) : ResponseEntity
' Request tiba hanya jika lolos semua filter
}
DioInterceptor <|-- AuthInterceptor : extends
DioInterceptor <|-- ErrorInterceptor : extends
DioInterceptor <|-- LogInterceptorFlutter : extends
ApiClient --> AuthInterceptor : chain[0]
AuthInterceptor --> ErrorInterceptor : passes to\nchain[1]
ErrorInterceptor --> LogInterceptorFlutter : passes to\nchain[2]
SpringFilter <|-- JwtAuthFilter : extends
JwtAuthFilter --> SecurityConfigChain : passes to
SecurityConfigChain --> ControllerChain : passes to\n(if authorized)
}
note bottom of ApiClient
Flutter — Dio interceptor chain:
HTTP Request → AuthInterceptor → ErrorInterceptor → LogInterceptor → Response
Setiap handler bisa: proses, modifikasi, atau blok request.
AuthInterceptor otomatis refresh JWT jika expired (401).
end note
note bottom of JwtAuthFilter
Backend — Spring Security filter chain:
HTTP Request → JwtAuthFilter → SecurityConfig → Controller
JwtAuthFilter extract & validasi Bearer token setiap request.
Jika invalid → langsung 401 tanpa lanjut ke controller.
end note
@enduml