@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