543 lines
19 KiB
Plaintext
543 lines
19 KiB
Plaintext
@startuml WalkGuide_Component_Diagram
|
||
title Component Diagram — WalkGuide System (v2.0)
|
||
|
||
skinparam componentStyle rectangle
|
||
skinparam backgroundColor #FAFAFA
|
||
skinparam component {
|
||
BackgroundColor #EEF2FF
|
||
BorderColor #6366F1
|
||
FontColor #1E1B4B
|
||
FontSize 11
|
||
}
|
||
skinparam package {
|
||
BackgroundColor #F0F4FF
|
||
BorderColor #818CF8
|
||
FontColor #1E1B4B
|
||
FontSize 12
|
||
FontStyle bold
|
||
}
|
||
skinparam interface {
|
||
BackgroundColor #DBEAFE
|
||
BorderColor #3B82F6
|
||
}
|
||
skinparam database {
|
||
BackgroundColor #FEF3C7
|
||
BorderColor #D97706
|
||
}
|
||
skinparam cloud {
|
||
BackgroundColor #F0FDF4
|
||
BorderColor #16A34A
|
||
}
|
||
skinparam arrow {
|
||
Color #4B5563
|
||
FontSize 9
|
||
FontColor #374151
|
||
}
|
||
skinparam note {
|
||
BackgroundColor #FFFBEB
|
||
BorderColor #F59E0B
|
||
FontSize 9
|
||
}
|
||
|
||
' ─────────────────────────────────────────────
|
||
' MOBILE DEVICE — Flutter App
|
||
' ─────────────────────────────────────────────
|
||
package "Mobile Device (Flutter App)" as FLUTTER #E8EAF6 {
|
||
|
||
package "Presentation Layer" as PRESENTATION {
|
||
[ServerConnectScreen] as SCS
|
||
[SplashScreen] as SS
|
||
[LoginScreen] as LS
|
||
[RegisterScreen] as RS
|
||
|
||
package "User Screens" as US_SCREENS {
|
||
[WalkGuideScreen] as WGS
|
||
[SosScreen] as SOSS
|
||
[ActivityLogScreen] as ALS
|
||
[NotificationScreen] as NS
|
||
[NavigationModeScreen] as NMS
|
||
[UserSettingsScreen] as USS
|
||
[CallScreen] as CS
|
||
[ManualScreen] as MS
|
||
[UserPairingScreen] as UPS
|
||
}
|
||
|
||
package "Guardian Screens" as GS_SCREENS {
|
||
[GuardianDashboardScreen] as GDS
|
||
[GuardianMapScreen] as GMS
|
||
[GuardianActivityLogScreen] as GALS
|
||
[GuardianSendNotifScreen] as GSNS
|
||
[GuardianAiConfigScreen] as GACS
|
||
[GuardianVoiceCmdScreen] as GVCS
|
||
[GuardianShortcutScreen] as GSHS
|
||
[GuardianGeofenceScreen] as GGFS
|
||
[GuardianPairingScreen] as GPS
|
||
[IncomingCallScreen] as ICS
|
||
}
|
||
}
|
||
|
||
package "Application Layer (BLoC / Cubit)" as BLOC_LAYER {
|
||
[AuthBloc] as AuthBloc
|
||
[PairingBloc] as PairingBloc
|
||
[WalkGuideBloc] as WGBloc
|
||
[SosBloc] as SosBloc
|
||
[LocationBloc] as LocBloc
|
||
[NotificationBloc] as NotifBloc
|
||
[ActivityLogBloc] as ActLogBloc
|
||
[VoiceCommandBloc] as VCBloc
|
||
[ServerConnectBloc] as SCBloc
|
||
[CallBloc] as CallBloc
|
||
[GuardianDashboardBloc] as GDBloc
|
||
}
|
||
|
||
package "Domain Layer" as DOMAIN {
|
||
package "Use Cases" as USECASES {
|
||
[LoginUseCase] as LoginUC
|
||
[RegisterUseCase] as RegUC
|
||
[LogoutUseCase] as LogoutUC
|
||
[InviteUserUseCase] as InviteUC
|
||
[RespondPairingUseCase] as RespUC
|
||
[UnpairUseCase] as UnpairUC
|
||
[StartSessionUseCase] as StartUC
|
||
[StopSessionUseCase] as StopUC
|
||
[LogObstacleUseCase] as LogObsUC
|
||
[TriggerSosUseCase] as TrigSosUC
|
||
[UpdateLocationUseCase] as UpdLocUC
|
||
}
|
||
package "Repository Interfaces" as REPO_INTF {
|
||
interface "IAuthRepository" as IAuthRepo
|
||
interface "IPairingRepository" as IPairRepo
|
||
interface "IWalkGuideRepository" as IWGRepo
|
||
interface "IActivityLogRepository" as IActRepo
|
||
interface "ISosRepository" as ISosRepo
|
||
interface "ILocationRepository" as ILocRepo
|
||
interface "INotificationRepository" as INotifRepo
|
||
interface "IAiConfigRepository" as IAIRepo
|
||
}
|
||
}
|
||
|
||
package "Data Layer" as DATA {
|
||
package "Repository Implementations" as REPO_IMPL {
|
||
[AuthRepositoryImpl] as AuthRepoImpl
|
||
[PairingRepositoryImpl] as PairRepoImpl
|
||
[WalkGuideRepositoryImpl] as WGRepoImpl
|
||
[ActivityLogRepositoryImpl] as ActRepoImpl
|
||
[SosRepositoryImpl] as SosRepoImpl
|
||
[LocationRepositoryImpl] as LocRepoImpl
|
||
[NotificationRepositoryImpl] as NotifRepoImpl
|
||
[AiConfigRepositoryImpl] as AIRepoImpl
|
||
}
|
||
|
||
package "Remote Data Sources" as REMOTE_DS {
|
||
[AuthRemoteDataSource] as AuthDS
|
||
[WalkGuideRemoteDataSource] as WGDS
|
||
[ActivityLogRemoteDataSource] as ActDS
|
||
[SosRemoteDataSource] as SosDS
|
||
[LocationRemoteDataSource] as LocDS
|
||
[NotificationRemoteDataSource] as NotifDS
|
||
[GuardianRemoteDataSource] as GrdDS
|
||
}
|
||
|
||
package "Local Data Sources (Drift/SQLite)" as LOCAL_DS {
|
||
[SecureStorageService] as SecStore
|
||
[LocalDatabase (Drift)] as DriftDB
|
||
[SharedPreferencesService] as SharedPref
|
||
}
|
||
|
||
package "Core Services (Singletons)" as CORE_SVC {
|
||
[TtsService\n(flutter_tts)] as TTS
|
||
[SttService\n(speech_to_text)] as STT
|
||
[VoiceCommandHandler] as VCH
|
||
[HapticService\n(vibration)] as HAP
|
||
[HardwareShortcutListener] as HSL
|
||
[FcmService\n(firebase_messaging)] as FCMSvc
|
||
[WebSocketService\n(stomp_dart_client)] as WSSvc
|
||
[AgoraService\n(agora_rtc_engine)] as AgoraSvc
|
||
}
|
||
|
||
package "AI Engine (On-Device)" as AI_ENGINE {
|
||
[ModelLoader\n(tflite_flutter)] as ModelLoader
|
||
[YoloDetector\n(YOLOv8n)] as YOLO
|
||
[ObstacleAnalyzer] as ObsAnalyzer
|
||
}
|
||
|
||
[ApiClient\n(Dio + Interceptors)] as DioClient
|
||
}
|
||
}
|
||
|
||
' ─────────────────────────────────────────────
|
||
' BACKEND SERVER — Spring Boot
|
||
' ─────────────────────────────────────────────
|
||
package "Backend Server (Spring Boot @ 202.46.28.160:8080)" as BACKEND #E8F5E9 {
|
||
|
||
package "Security & Config" as SEC_CFG {
|
||
[SecurityConfig\n(CORS, CSRF, RBAC)] as SecConfig
|
||
[JwtAuthFilter\n(OncePerRequestFilter)] as JWTFilter
|
||
[JwtUtil\n(JJWT)] as JWTUtil
|
||
[CustomUserDetailsService] as CUDS
|
||
[WebSocketConfig\n(STOMP)] as WSConfig
|
||
[GlobalExceptionHandler\n(@ControllerAdvice)] as GEH
|
||
[SwaggerConfig\n(Springdoc OpenAPI)] as SwagConfig
|
||
}
|
||
|
||
package "Controller Layer" as CTRL {
|
||
[AuthController\n/api/v1/auth] as AuthCtrl
|
||
[PairingController\n/api/v1/shared/pairing] as PairCtrl
|
||
[GuardianController\n/api/v1/guardian] as GrdCtrl
|
||
[UserController\n/api/v1/user] as UserCtrl
|
||
[CallController\n/api/v1/shared/call] as CallCtrl
|
||
}
|
||
|
||
package "Service Layer" as SVC {
|
||
[AuthService] as AuthSvc
|
||
[PairingService] as PairSvc
|
||
[ActivityLogService] as ActLogSvc
|
||
[LocationService\n(+ Haversine)] as LocSvc
|
||
[ObstacleLogService] as ObsLogSvc
|
||
[NotificationService] as NotifSvc
|
||
[SosService] as SosSvc
|
||
[AiConfigService] as AICfgSvc
|
||
[VoiceCommandService] as VCSvc
|
||
[HardwareShortcutService] as HWSvc
|
||
[GeofenceService\n(Haversine)] as GeoSvc
|
||
[UserSettingsService] as UserSetSvc
|
||
[FcmService\n(Firebase Admin)] as FcmBackSvc
|
||
[AgoraTokenService] as AgoraSvcBE
|
||
[GuardianDashboardService] as GDSvc
|
||
}
|
||
|
||
package "WebSocket Broadcaster" as WS_BROADCAST {
|
||
[LocationBroadcaster\n(SimpMessagingTemplate)] as LocBcast
|
||
}
|
||
|
||
package "Repository Layer (Spring Data JPA)" as REPO {
|
||
[UserRepository] as UserRepo
|
||
[PairingRelationRepository] as PairRepo
|
||
[ActivityLogRepository] as ActRepo
|
||
[ObstacleLogRepository] as ObsRepo
|
||
[LocationHistoryRepository] as LocRepo
|
||
[GuardianNotificationRepository] as NotifRepo
|
||
[SosEventRepository] as SosRepo
|
||
[UserSettingsRepository] as UserSetRepo
|
||
[AiConfigRepository] as AIRepo
|
||
[VoiceCommandConfigRepository] as VCRepo
|
||
[HardwareShortcutRepository] as HWRepo
|
||
[GeofenceConfigRepository] as GeoRepo
|
||
[RefreshTokenRepository] as RTRepo
|
||
}
|
||
|
||
package "Domain / Entity" as ENTITY {
|
||
[User] as UEnt
|
||
[PairingRelation] as PRel
|
||
[ActivityLog] as ActEnt
|
||
[ObstacleLog] as ObsEnt
|
||
[LocationHistory] as LocEnt
|
||
[GuardianNotification] as NotifEnt
|
||
[SosEvent] as SosEnt
|
||
[UserSettings] as UserSetEnt
|
||
[AiConfig] as AICfgEnt
|
||
[VoiceCommandConfig] as VCEnt
|
||
[HardwareShortcut] as HWEnt
|
||
[GeofenceConfig] as GeoEnt
|
||
[RefreshToken] as RTEnt
|
||
}
|
||
}
|
||
|
||
' ─────────────────────────────────────────────
|
||
' EXTERNAL SERVICES
|
||
' ─────────────────────────────────────────────
|
||
package "External Services" as EXTERNAL #FFF8E1 {
|
||
cloud "Firebase (FCM)\nPush Notifications" as FCM
|
||
cloud "Agora RTC\nVoIP Audio Call" as AGORA
|
||
cloud "OpenStreetMap\n(flutter_map tiles)" as OSM
|
||
}
|
||
|
||
database "PostgreSQL\n202.46.28.160:2002\n(University Server)\nFlyway Migrations V1-V16" as PGDB
|
||
|
||
' ─────────────────────────────────────────────
|
||
' PRESENTATION → BLOC
|
||
' ─────────────────────────────────────────────
|
||
SCS --> SCBloc
|
||
SS --> AuthBloc
|
||
LS --> AuthBloc
|
||
RS --> AuthBloc
|
||
WGS --> WGBloc
|
||
WGS --> VCBloc
|
||
SOSS --> SosBloc
|
||
ALS --> ActLogBloc
|
||
NS --> NotifBloc
|
||
NMS --> LocBloc
|
||
USS --> AuthBloc
|
||
CS --> CallBloc
|
||
UPS --> PairingBloc
|
||
GDS --> GDBloc
|
||
GMS --> LocBloc
|
||
GALS --> ActLogBloc
|
||
GSNS --> NotifBloc
|
||
GACS --> AIRepoImpl
|
||
GVCS --> VCBloc
|
||
GSHS --> VCBloc
|
||
GGFS --> GDBloc
|
||
GPS --> PairingBloc
|
||
ICS --> CallBloc
|
||
|
||
' ─────────────────────────────────────────────
|
||
' BLOC → USE CASES
|
||
' ─────────────────────────────────────────────
|
||
AuthBloc --> LoginUC
|
||
AuthBloc --> RegUC
|
||
AuthBloc --> LogoutUC
|
||
PairingBloc --> InviteUC
|
||
PairingBloc --> RespUC
|
||
PairingBloc --> UnpairUC
|
||
WGBloc --> StartUC
|
||
WGBloc --> StopUC
|
||
WGBloc --> LogObsUC
|
||
SosBloc --> TrigSosUC
|
||
LocBloc --> UpdLocUC
|
||
CallBloc --> AgoraSvc
|
||
VCBloc --> VCH
|
||
|
||
' ─────────────────────────────────────────────
|
||
' USE CASES → REPOSITORY INTERFACES
|
||
' ─────────────────────────────────────────────
|
||
LoginUC --> IAuthRepo
|
||
RegUC --> IAuthRepo
|
||
LogoutUC --> IAuthRepo
|
||
InviteUC --> IPairRepo
|
||
RespUC --> IPairRepo
|
||
UnpairUC --> IPairRepo
|
||
StartUC --> IWGRepo
|
||
StopUC --> IWGRepo
|
||
LogObsUC --> IWGRepo
|
||
TrigSosUC --> ISosRepo
|
||
UpdLocUC --> ILocRepo
|
||
|
||
' ─────────────────────────────────────────────
|
||
' INTERFACES → IMPLEMENTATIONS
|
||
' ─────────────────────────────────────────────
|
||
IAuthRepo <|.. AuthRepoImpl
|
||
IPairRepo <|.. PairRepoImpl
|
||
IWGRepo <|.. WGRepoImpl
|
||
IActRepo <|.. ActRepoImpl
|
||
ISosRepo <|.. SosRepoImpl
|
||
ILocRepo <|.. LocRepoImpl
|
||
INotifRepo <|.. NotifRepoImpl
|
||
IAIRepo <|.. AIRepoImpl
|
||
|
||
' ─────────────────────────────────────────────
|
||
' REPO IMPL → DATA SOURCES
|
||
' ─────────────────────────────────────────────
|
||
AuthRepoImpl --> AuthDS
|
||
AuthRepoImpl --> SecStore
|
||
PairRepoImpl --> GrdDS
|
||
WGRepoImpl --> WGDS
|
||
WGRepoImpl --> DriftDB
|
||
ActRepoImpl --> ActDS
|
||
SosRepoImpl --> SosDS
|
||
LocRepoImpl --> LocDS
|
||
NotifRepoImpl --> NotifDS
|
||
NotifRepoImpl --> DriftDB
|
||
AIRepoImpl --> GrdDS
|
||
|
||
' ─────────────────────────────────────────────
|
||
' REMOTE DATA SOURCES → DioClient
|
||
' ─────────────────────────────────────────────
|
||
AuthDS --> DioClient
|
||
WGDS --> DioClient
|
||
ActDS --> DioClient
|
||
SosDS --> DioClient
|
||
LocDS --> DioClient
|
||
NotifDS --> DioClient
|
||
GrdDS --> DioClient
|
||
|
||
' ─────────────────────────────────────────────
|
||
' CORE SERVICES INTERCONNECT
|
||
' ─────────────────────────────────────────────
|
||
WGBloc --> YOLO
|
||
WGBloc --> TTS
|
||
WGBloc --> HAP
|
||
YOLO --> ModelLoader
|
||
YOLO --> ObsAnalyzer
|
||
ObsAnalyzer --> TTS
|
||
ObsAnalyzer --> HAP
|
||
VCH --> STT
|
||
VCH --> DriftDB
|
||
HSL --> DriftDB
|
||
FCMSvc --> DriftDB
|
||
|
||
SharedPref --> DioClient : baseUrl
|
||
|
||
' ─────────────────────────────────────────────
|
||
' DioClient → Backend REST API
|
||
' ─────────────────────────────────────────────
|
||
DioClient -down-> AuthCtrl : "POST /api/v1/auth/register\nPOST /api/v1/auth/login\nPOST /api/v1/auth/refresh\nPOST /api/v1/auth/logout\nPUT /api/v1/auth/fcm-token\nGET /api/v1/auth/ping"
|
||
DioClient -down-> PairCtrl : "POST /shared/pairing/invite\nPOST /shared/pairing/respond\nDELETE /shared/pairing/unpair\nGET /shared/pairing/status"
|
||
DioClient -down-> UserCtrl : "GET /user/profile\nPOST /user/location\nPOST /user/obstacle\nPOST /user/sos\nGET /user/notifications\nPOST /user/walkguide/start\nPOST /user/walkguide/stop"
|
||
DioClient -down-> GrdCtrl : "GET /guardian/dashboard\nGET /guardian/user-location\nPOST /guardian/notifications/send\nPUT /guardian/ai-config\nPUT /guardian/geofence"
|
||
DioClient -down-> CallCtrl : "POST /shared/call/token\nPOST /shared/call/notify"
|
||
|
||
' WebSocket STOMP
|
||
WSSvc -down-> WSConfig : "ws://host:8080/ws\n(STOMP)\n/topic/location/{userId}\n/queue/sos/{guardianId}\n/queue/notif/{userId}"
|
||
|
||
' ─────────────────────────────────────────────
|
||
' BACKEND SECURITY FLOW
|
||
' ─────────────────────────────────────────────
|
||
JWTFilter --> JWTUtil : validate token
|
||
JWTFilter --> CUDS : load user
|
||
JWTFilter -up-> SecConfig : filter chain
|
||
SecConfig -right-> JWTFilter
|
||
|
||
' ─────────────────────────────────────────────
|
||
' CONTROLLERS → SERVICES
|
||
' ─────────────────────────────────────────────
|
||
AuthCtrl --> AuthSvc
|
||
PairCtrl --> PairSvc
|
||
GrdCtrl --> GDSvc
|
||
GrdCtrl --> LocSvc
|
||
GrdCtrl --> ActLogSvc
|
||
GrdCtrl --> ObsLogSvc
|
||
GrdCtrl --> NotifSvc
|
||
GrdCtrl --> SosSvc
|
||
GrdCtrl --> AICfgSvc
|
||
GrdCtrl --> VCSvc
|
||
GrdCtrl --> HWSvc
|
||
GrdCtrl --> GeoSvc
|
||
UserCtrl --> AuthSvc
|
||
UserCtrl --> LocSvc
|
||
UserCtrl --> ObsLogSvc
|
||
UserCtrl --> SosSvc
|
||
UserCtrl --> ActLogSvc
|
||
UserCtrl --> NotifSvc
|
||
UserCtrl --> UserSetSvc
|
||
UserCtrl --> VCSvc
|
||
UserCtrl --> HWSvc
|
||
UserCtrl --> AICfgSvc
|
||
CallCtrl --> AgoraSvcBE
|
||
|
||
' ─────────────────────────────────────────────
|
||
' SERVICES CROSS-DEPENDENCIES
|
||
' ─────────────────────────────────────────────
|
||
AuthSvc --> PairSvc : seed defaults on register
|
||
PairSvc --> VCSvc : seedDefaults()
|
||
PairSvc --> HWSvc : seedDefaults()
|
||
PairSvc --> AICfgSvc : create config on pair
|
||
PairSvc --> FcmBackSvc : send FCM invite/response
|
||
NotifSvc --> FcmBackSvc : send FCM notification
|
||
SosSvc --> FcmBackSvc : send FCM SOS high-priority
|
||
AICfgSvc --> FcmBackSvc : notify settings updated
|
||
LocSvc --> GeoSvc : checkGeofence()
|
||
LocSvc --> LocBcast : broadcastLocation()
|
||
LocSvc --> ActLogSvc : log LOCATION_UPDATE
|
||
NotifSvc --> LocBcast : broadcastNotification()
|
||
SosSvc --> LocBcast : broadcastSos()
|
||
SosSvc --> ActLogSvc : log SOS_TRIGGERED
|
||
ActLogSvc --> LocBcast : broadcast to Guardian
|
||
GDSvc --> LocSvc
|
||
GDSvc --> ActLogSvc
|
||
GDSvc --> NotifSvc
|
||
GDSvc --> SosSvc
|
||
|
||
' ─────────────────────────────────────────────
|
||
' SERVICES → REPOSITORIES
|
||
' ─────────────────────────────────────────────
|
||
AuthSvc --> UserRepo
|
||
AuthSvc --> RTRepo
|
||
AuthSvc --> ActLogSvc
|
||
PairSvc --> PairRepo
|
||
PairSvc --> UserRepo
|
||
ActLogSvc --> ActRepo
|
||
LocSvc --> LocRepo
|
||
LocSvc --> PairRepo
|
||
ObsLogSvc --> ObsRepo
|
||
ObsLogSvc --> ActLogSvc
|
||
NotifSvc --> NotifRepo
|
||
NotifSvc --> PairRepo
|
||
SosSvc --> SosRepo
|
||
SosSvc --> PairRepo
|
||
AICfgSvc --> AIRepo
|
||
VCSvc --> VCRepo
|
||
HWSvc --> HWRepo
|
||
GeoSvc --> GeoRepo
|
||
UserSetSvc --> UserSetRepo
|
||
FcmBackSvc --> UserRepo
|
||
AgoraSvcBE --> UserRepo
|
||
|
||
' ─────────────────────────────────────────────
|
||
' REPOSITORIES → ENTITIES (JPA/Hibernate)
|
||
' ─────────────────────────────────────────────
|
||
UserRepo --> UEnt
|
||
PairRepo --> PRel
|
||
ActRepo --> ActEnt
|
||
ObsRepo --> ObsEnt
|
||
LocRepo --> LocEnt
|
||
NotifRepo --> NotifEnt
|
||
SosRepo --> SosEnt
|
||
UserSetRepo --> UserSetEnt
|
||
AIRepo --> AICfgEnt
|
||
VCRepo --> VCEnt
|
||
HWRepo --> HWEnt
|
||
GeoRepo --> GeoEnt
|
||
RTRepo --> RTEnt
|
||
|
||
' ─────────────────────────────────────────────
|
||
' ENTITIES → DATABASE
|
||
' ─────────────────────────────────────────────
|
||
UEnt --> PGDB : JPA/Hibernate
|
||
PRel --> PGDB
|
||
ActEnt --> PGDB
|
||
ObsEnt --> PGDB
|
||
LocEnt --> PGDB
|
||
NotifEnt --> PGDB
|
||
SosEnt --> PGDB
|
||
UserSetEnt --> PGDB
|
||
AICfgEnt --> PGDB
|
||
VCEnt --> PGDB
|
||
HWEnt --> PGDB
|
||
GeoEnt --> PGDB
|
||
RTEnt --> PGDB
|
||
|
||
' ─────────────────────────────────────────────
|
||
' EXTERNAL SERVICES
|
||
' ─────────────────────────────────────────────
|
||
FcmBackSvc -right-> FCM : "Firebase Admin SDK\nFirebaseMessaging.send()"
|
||
AgoraSvcBE -right-> AGORA : "Generate RTC Token\n(server-side Agora SDK)"
|
||
AgoraSvc --> AGORA : "agora_rtc_engine\nJoin Channel (audio-only)"
|
||
FCMSvc --> FCM : "firebase_messaging\nReceive push"
|
||
GMS --> OSM : "flutter_map\nOpenStreetMap tiles"
|
||
|
||
note top of PGDB
|
||
Tables (Flyway V1–V16):
|
||
users, pairing_relations,
|
||
activity_logs, obstacle_logs,
|
||
location_history, guardian_notifications,
|
||
sos_events, user_settings, ai_configs,
|
||
voice_command_configs, hardware_shortcuts,
|
||
geofence_configs, refresh_tokens
|
||
end note
|
||
|
||
note right of AI_ENGINE
|
||
On-Device AI (No server call):
|
||
YOLOv8n .tflite (640×640)
|
||
→ detect obstacles
|
||
→ direction: LEFT/CENTER/RIGHT
|
||
→ TTS + Haptic alert
|
||
NNAPI delegate (Android AI accel.)
|
||
end note
|
||
|
||
note left of SharedPref
|
||
Dynamic Server URL:
|
||
User inputs "http://202.46.28.160:8080"
|
||
Saved to SharedPreferences
|
||
No hardcoded BASE_URL in APK
|
||
end note
|
||
|
||
note bottom of WSSvc
|
||
WebSocket STOMP:
|
||
/topic/location/{userId} → Guardian map real-time
|
||
/queue/sos/{guardianId} → SOS alert instant
|
||
/queue/notif/{userId} → Notification push
|
||
end note
|
||
|
||
@enduml
|