01. Đăng ký tài khoản

flowchart LR
  A["Người dùng mở trang đăng ký"] --> B["Frontend validate username, email, password"]
  B --> C["POST /api/auth/register"]
  C --> D["C# AuthController.Register"]
  D --> E["JavaApiService.RegisterAsync"]
  E --> F["Java AuthController.register"]
  F --> G["AuthService kiểm tra username/email"]
  G --> H{"Hợp lệ?"}
  H -- Không --> I["409/400 trả lỗi về frontend"]
  H -- Có --> J["Hash password, tạo USERS"]
  J --> K["Tạo USER_PROFILES mặc định"]
  K --> L["Tạo USER_PROFILE_INFO_VISIBILITY"]
  L --> M["201 Created RegisterResponse"]
  M --> N["Frontend chuyển sang bước OTP/hoàn thiện hồ sơ"]
  

02. Đăng nhập bằng tài khoản thường

flowchart LR
  A["Người dùng nhập username/password"] --> B["Frontend gửi POST /api/auth/login"]
  B --> C["C# AuthController.Login"]
  C --> D["JavaApiService.LoginAsync"]
  D --> E["Java AuthController.login"]
  E --> F["AuthService xác thực mật khẩu và trạng thái user"]
  F --> G{"Đăng nhập hợp lệ?"}
  G -- Không --> H["401/403 trả lỗi"]
  G -- Có --> I["Sinh access token JWT"]
  I --> J["Sinh refresh token và lưu REFRESH_TOKENS"]
  J --> K["Set cookie refresh_token"]
  K --> L["C# normalize token, set login cookies"]
  L --> M["Frontend lưu trạng thái đăng nhập"]
  M --> N["Tải trang chủ / bảng tin"]
  

03. Đăng nhập bằng Google

flowchart LR
  A["Frontend nhận Google ID token"] --> B["POST /api/auth/google"]
  B --> C["C# AuthController.AuthWithGoogle"]
  C --> D["JavaApiService.AuthWithGoogleAsync"]
  D --> E["Java AuthController.authWithGoogle"]
  E --> F["GoogleTokenVerifier kiểm tra token"]
  F --> G{"Email đã có user?"}
  G -- Chưa có --> H["Tạo USERS, USER_PROFILES, USER_AUTH_PROVIDERS"]
  G -- Đã có --> I["Liên kết/đọc user hiện có"]
  H --> J["Sinh JWT và refresh token"]
  I --> J
  J --> K["Set refresh_token cookie"]
  K --> L["Frontend nhận profileCompleted"]
  L --> M{"Đã hoàn thiện hồ sơ?"}
  M -- Chưa --> N["Đi tới complete profile"]
  M -- Rồi --> O["Vào trang chủ"]
  

04. Làm mới access token

flowchart LR
  A["Access token hết hạn"] --> B["Frontend gọi POST /api/auth/refresh-token"]
  B --> C["C# đọc refresh token từ body/cookie"]
  C --> D{"Có refresh token?"}
  D -- Không --> E["401 Unauthorized"]
  D -- Có --> F["JavaApiService.RefreshTokenAsync"]
  F --> G["Java AuthService kiểm tra token hash/family/revoked/expires"]
  G --> H{"Refresh token hợp lệ?"}
  H -- Không --> I["401 INVALID_REFRESH_TOKEN"]
  H -- Có --> J["Rotate refresh token"]
  J --> K["Sinh access token mới"]
  K --> L["Set cookie refresh_token mới"]
  L --> M["Frontend retry request trước đó"]
  

05. Đăng xuất

flowchart LR
  A["Người dùng bấm đăng xuất"] --> B["POST /api/auth/logout"]
  B --> C["C# AuthController.Logout"]
  C --> D["Đọc refresh token từ body/cookie"]
  D --> E{"Có refresh token?"}
  E -- Có --> F["JavaApiService.LogoutAsync"]
  F --> G["Java AuthService revoke refresh token"]
  E -- Không --> H["Bỏ qua revoke server"]
  G --> I["C# ClearLoginCookies"]
  H --> I
  I --> J["204 No Content"]
  J --> K["Frontend xóa session và về login"]
  

06. Gửi và xác thực OTP email

flowchart LR
  A["Người dùng yêu cầu xác thực email"] --> B["POST /api/auth/otp/send/verify-email hoặc /me/otp/send/verify-email"]
  B --> C["C# chuyển tiếp sang Java"]
  C --> D["Java AuthService tạo OTP"]
  D --> E["Lưu OTPS với type EMAIL_VERIFY và expired_at"]
  E --> F["Email provider SMTP/Resend gửi mã"]
  F --> G["Người dùng nhập OTP"]
  G --> H["POST /api/auth/otp/verify/email hoặc /me/otp/verify/email"]
  H --> I["Java kiểm tra mã, hạn dùng, used_at"]
  I --> J{"OTP hợp lệ?"}
  J -- Không --> K["400/404 lỗi OTP"]
  J -- Có --> L["Đánh dấu used_at, cập nhật email verified"]
  L --> M["Trả OtpVerifyResponse"]
  

07. Quên mật khẩu và đặt lại mật khẩu

flowchart LR
  A["Người dùng nhập email/username"] --> B["POST /api/auth/otp/send/reset-password"]
  B --> C["Java tạo OTP PASSWORD_RESET"]
  C --> D["Gửi OTP qua email"]
  D --> E["Người dùng nhập OTP"]
  E --> F["POST /api/auth/otp/verify/password"]
  F --> G{"OTP hợp lệ?"}
  G -- Không --> H["Trả lỗi xác thực OTP"]
  G -- Có --> I["Sinh reset token"]
  I --> J["Frontend gửi mật khẩu mới"]
  J --> K["POST /api/auth/reset-password kèm X-Reset-Token"]
  K --> L["Java xác thực reset token"]
  L --> M["Hash password mới, cập nhật USERS"]
  M --> N["Thu hồi token cũ nếu cần"]
  N --> O["Trả MessageResponse thành công"]
  

08. Hoàn thiện hồ sơ sau đăng ký

flowchart LR
  A["User đăng ký/Google login nhưng profileCompleted=false"] --> B["Frontend mở complete profile"]
  B --> C["POST /api/profiles/me/complete-profile"]
  C --> D["Java UserProfileController.completeProfile"]
  D --> E["Lấy userId từ JWT"]
  E --> F["Validate displayName, phoneNumber, avatar, birthDate"]
  F --> G{"Dữ liệu hợp lệ?"}
  G -- Không --> H["400 validation error"]
  G -- Có --> I["Cập nhật USER_PROFILES"]
  I --> J["Đánh dấu profileCompleted"]
  J --> K["Trả profile response"]
  K --> L["Frontend vào trang chủ"]
  

09. Xem hồ sơ cá nhân và hồ sơ công khai

flowchart LR
  A["Frontend mở trang profile"] --> B{"Xem của mình hay người khác?"}
  B -- Của mình --> C["GET /api/profiles/me hoặc /api/profiles/me/overview"]
  B -- Người khác --> D["GET /api/profiles/{userId} hoặc /api/profiles/public?userId="]
  C --> E["C# ProfilesController hoặc Java UserProfileController"]
  D --> E
  E --> F["Lấy user profile từ Java API/database"]
  F --> G["Áp dụng visibility + friendship status"]
  G --> H["Ghép số bạn bè, avatar, displayName, bài viết"]
  H --> I["Trả dữ liệu hồ sơ"]
  I --> J["Frontend render trang cá nhân"]
  

10. Cập nhật hồ sơ và quyền riêng tư

flowchart LR
  A["Người dùng chỉnh sửa thông tin"] --> B{"Loại thông tin"}
  B -- Hồ sơ cơ bản --> C["PATCH /api/profiles/me"]
  B -- Visibility --> D["PATCH /api/profiles/me/profile-info-settings/visibility"]
  B -- Security private --> E["PATCH /api/profiles/me/security-private"]
  B -- Security account --> F["PATCH /api/users/me/security-account"]
  C --> G["Controller lấy userId từ JWT"]
  D --> G
  E --> G
  F --> G
  G --> H["Service validate dữ liệu và quyền sở hữu"]
  H --> I["Cập nhật USERS/USER_PROFILES/USER_PROFILE_INFO_VISIBILITY"]
  I --> J["Trả dữ liệu mới"]
  J --> K["Frontend cập nhật setting/profile UI"]
  

11. Tải bảng tin

flowchart LR
  A["Frontend mở Home"] --> B["GET /api/posts?page=&pageSize="]
  B --> C["C# PostsController.GetPosts"]
  C --> D["PostService.GetPagedAsync"]
  D --> E["Query POST chưa deleted"]
  E --> F["Join media, hashtag, like/reaction, comment count"]
  F --> G["Nếu có token: tính myReaction/isLiked"]
  G --> H["Lấy user summary/profile từ read model hoặc Java API"]
  H --> I["Trả PagedResult"]
  I --> J["Frontend render news feed"]
  

12. Tạo bài viết mới

flowchart LR
  A["Người dùng nhập nội dung/chọn ảnh"] --> B{"Có media?"}
  B -- Có --> C["GET /api/media/cloudinary-signature"]
  C --> D["Upload file lên Cloudinary"]
  D --> E["Nhận media_url/media_type"]
  B -- Không --> F["Dùng nội dung text"]
  E --> G["POST /api/posts"]
  F --> G
  G --> H["C# PostsController.CreatePost"]
  H --> I["PostService validate user, content, media"]
  I --> J["Lưu POST và POST_MEDIA"]
  J --> K["Tách hashtag, lưu HASHTAG/POST_HASHTAG"]
  K --> L["Trả 201 Created + PostResponseDto"]
  L --> M["Frontend thêm bài viết vào feed"]
  

13. Chỉnh sửa hoặc xóa bài viết

flowchart LR
  A["Người dùng chọn sửa/xóa bài viết"] --> B{"Thao tác"}
  B -- Sửa --> C["PUT /api/posts/{postId}"]
  B -- Xóa --> D["DELETE /api/posts/{postId}"]
  C --> E["C# kiểm tra JWT"]
  D --> E
  E --> F["PostService kiểm tra bài viết tồn tại"]
  F --> G{"Là chủ bài hoặc admin?"}
  G -- Không --> H["403 Forbidden"]
  G -- Có và sửa --> I["Cập nhật content/media/hashtag"]
  G -- Có và xóa --> J["Soft delete post"]
  I --> K["Trả PostResponseDto mới"]
  J --> L["Trả message Post deleted"]
  K --> M["Frontend cập nhật feed"]
  L --> M
  

14. Thả cảm xúc hoặc bỏ cảm xúc bài viết

flowchart LR
  A["Người dùng bấm reaction"] --> B{"Có reaction mới?"}
  B -- Có --> C["PUT /api/posts/{postId}/reactions"]
  B -- Bỏ --> D["DELETE /api/posts/{postId}/reactions"]
  C --> E["C# LikeService kiểm tra post tồn tại"]
  D --> E
  E --> F["Upsert hoặc xóa LIKE"]
  F --> G["Tính lại counters theo type"]
  G --> H["Tạo notification cho chủ bài nếu phù hợp"]
  H --> I["SignalR /hubs/notifications gửi realtime"]
  I --> J["Trả PostReactionStateResponseDto"]
  J --> K["Frontend cập nhật icon/counter"]
  

15. Xem, tạo, sửa, xóa bình luận

flowchart LR
  A["Frontend mở comment panel"] --> B["GET /api/comments/post/{postId}"]
  B --> C["C# CommentService lấy danh sách theo post"]
  C --> D["Trả PagedResult"]
  D --> E["Người dùng gửi bình luận/reply"]
  E --> F["POST /api/comments"]
  F --> G["Validate postId, parentCommentId, content"]
  G --> H["Lưu COMMENT"]
  H --> I["Tạo notification cho chủ bài/cha comment"]
  I --> J["Trả 201 Created"]
  J --> K{"Sửa hoặc xóa?"}
  K -- Sửa --> L["PUT /api/comments/{commentId}"]
  K -- Xóa --> M["DELETE /api/comments/{commentId}"]
  L --> N["Kiểm tra owner/admin, cập nhật content"]
  M --> O["Kiểm tra owner/admin, soft delete"]
  N --> P["Frontend cập nhật danh sách"]
  O --> P
  

16. Thả cảm xúc bình luận

flowchart LR
  A["Người dùng bấm reaction bình luận"] --> B{"Set hay remove?"}
  B -- Set --> C["PUT /api/comments/{commentId}/reactions"]
  B -- Remove --> D["DELETE /api/comments/{commentId}/reactions"]
  C --> E["CommentReactionService kiểm tra comment"]
  D --> E
  E --> F["Upsert/xóa COMMENT_REACTION"]
  F --> G["Tính lại reaction state"]
  G --> H["Tạo notification cho chủ comment nếu phù hợp"]
  H --> I["Trả CommentReactionStateResponseDto"]
  I --> J["Frontend cập nhật reaction UI"]
  

17. Story: tải, tạo, xem, reaction, xóa

flowchart LR
  A["Frontend tải story"] --> B["GET /api/stories"]
  B --> C["C# StoryService lấy story chưa hết hạn/chưa xóa"]
  C --> D["Trả danh sách story"]
  D --> E["Người dùng tạo story"]
  E --> F["Upload media nếu cần"]
  F --> G["POST /api/stories"]
  G --> H["Lưu STORY với expired_at"]
  H --> I["Người khác xem story"]
  I --> J["POST /api/stories/{storyId}/view"]
  J --> K["Lưu STORY_VIEW nếu lần đầu"]
  K --> L["PUT/DELETE /api/stories/{storyId}/reactions"]
  L --> M["Lưu/xóa STORY_REACTION"]
  M --> N["DELETE /api/stories/{storyId} nếu chủ story xóa"]
  

18. Lưu và bỏ lưu bài viết

flowchart LR
  A["Người dùng bấm lưu bài viết"] --> B["POST /api/saved-posts"]
  B --> C["C# SavedPostService kiểm tra post tồn tại"]
  C --> D["Upsert SAVED_POST theo userId/postId"]
  D --> E["Trả trạng thái đã lưu"]
  E --> F["Người dùng mở mục bài đã lưu"]
  F --> G["GET /api/saved-posts/my"]
  G --> H["Trả danh sách post đã lưu"]
  H --> I["Người dùng bỏ lưu"]
  I --> J["DELETE /api/saved-posts/{postId}"]
  J --> K["Xóa SAVED_POST"]
  K --> L["Frontend cập nhật icon lưu"]
  

19. Hashtag: tách từ bài viết và tìm kiếm

flowchart LR
  A["Người dùng tạo/sửa bài có #hashtag"] --> B["PostService parse hashtag từ content"]
  B --> C["Normalize tên hashtag"]
  C --> D{"Hashtag đã tồn tại?"}
  D -- Chưa --> E["Tạo HASHTAG"]
  D -- Rồi --> F["Dùng hashtag hiện có"]
  E --> G["Lưu POST_HASHTAG"]
  F --> G
  G --> H["Người dùng tìm hashtag"]
  H --> I["GET /api/hashtags/search"]
  I --> J["HashtagService query normalized_name"]
  J --> K["Trả danh sách hashtag/post liên quan"]
  

20. Gửi lời mời kết bạn

flowchart LR
  A["Người dùng bấm kết bạn"] --> B["POST /api/friendships/request hoặc /api/messenger/friendships"]
  B --> C["Controller lấy requesterId từ JWT"]
  C --> D["FriendshipService kiểm tra targetUserId"]
  D --> E{"Đã block/đã là bạn/đã có request?"}
  E -- Có --> F["Trả lỗi nghiệp vụ"]
  E -- Không --> G["Tạo FRIENDSHIPS status PENDING"]
  G --> H["Tạo notification cho addressee"]
  H --> I["SignalR/WebSocket cập nhật realtime"]
  I --> J["Frontend chuyển nút sang Đã gửi"]
  

21. Chấp nhận hoặc từ chối lời mời kết bạn

flowchart LR
  A["Người dùng mở danh sách lời mời"] --> B["GET /api/friendships/pending-requesters"]
  B --> C["FriendshipService trả danh sách requester"]
  C --> D{"Người dùng chọn"}
  D -- Chấp nhận --> E["POST /api/friendships/accept"]
  D -- Từ chối --> F["POST /api/friendships/reject"]
  E --> G["Cập nhật FRIENDSHIPS status ACCEPTED"]
  G --> H["Tạo CONTACTS hai chiều nếu cần"]
  H --> I["Tạo notification accepted"]
  F --> J["Cập nhật/xóa request pending"]
  I --> K["Frontend cập nhật danh sách bạn bè"]
  J --> K
  

22. Hủy kết bạn, chặn và bỏ chặn

flowchart LR
  A["Người dùng thao tác với một user"] --> B{"Loại thao tác"}
  B -- Hủy bạn --> C["POST /api/friendships/unfriend hoặc DELETE /api/messenger/friendships"]
  B -- Chặn --> D["POST /api/friendships/block hoặc /api/messenger/friendships/block/{targetUserId}"]
  B -- Bỏ chặn --> E["DELETE /api/friendships/block/{targetUserId}"]
  C --> F["Xóa/cập nhật FRIENDSHIPS"]
  F --> G["Cập nhật CONTACTS"]
  D --> H["Đánh dấu blocked hoặc tạo block record"]
  H --> I["Ẩn quan hệ, conversation/contact tương ứng"]
  E --> J["Gỡ trạng thái blocked"]
  G --> K["Frontend cập nhật trạng thái nút"]
  I --> K
  J --> K
  

23. Gợi ý bạn bè, danh bạ và trạng thái online

flowchart LR
  A["Frontend mở danh bạ/bạn bè"] --> B{"Dữ liệu cần tải"}
  B -- Gợi ý --> C["GET /api/friendships/suggestions hoặc /api/users/suggestions"]
  B -- Danh bạ --> D["GET /api/friendships/contacts hoặc /api/messenger/contacts/getByUser"]
  B -- Online --> E["GET /api/friendships/presence hoặc /api/profiles/me/friends/presence"]
  C --> F["Service lọc user chưa kết bạn/chưa block"]
  D --> G["Service lấy CONTACTS/FRIENDSHIPS ACCEPTED"]
  E --> H["Service ghép presence/lastSeen"]
  F --> I["Trả danh sách user summary"]
  G --> I
  H --> I
  I --> J["Frontend render sidebar/danh bạ"]
  

24. Tạo cuộc trò chuyện cá nhân hoặc nhóm

flowchart LR
  A["Người dùng chọn người để nhắn tin"] --> B["POST /api/messenger/conversations/create"]
  B --> C["Java ConversationController.create"]
  C --> D["ConversationService kiểm tra thành viên"]
  D --> E{"Direct đã tồn tại?"}
  E -- Có --> F["Trả conversation hiện có"]
  E -- Không --> G["Tạo CONVERSATIONS"]
  G --> H["Tạo CONVERSATION_MEMBERS"]
  H --> I["Set role admin/member cho nhóm"]
  I --> J["Trả ConversationResponse"]
  F --> J
  J --> K["Frontend mở khung chat"]
  

25. Tải danh sách cuộc trò chuyện

flowchart LR
  A["Frontend mở messenger"] --> B["GET /api/messenger/conversations/getByUser"]
  B --> C["Java ConversationController.getByUser"]
  C --> D["Service lấy CONVERSATION_MEMBERS theo userId"]
  D --> E["Join CONVERSATIONS + last_message_id"]
  E --> F["Lấy last sender, unread count, member count"]
  F --> G["Sắp xếp theo last_message_at"]
  G --> H["Trả danh sách conversation"]
  H --> I["Frontend render sidebar chat"]
  

26. Gửi tin nhắn văn bản hoặc tệp đính kèm

flowchart LR
  A["Người dùng nhập tin nhắn/chọn file"] --> B{"Có file?"}
  B -- Có --> C["Upload media lên Cloudinary"]
  C --> D["Tạo attachment request"]
  B -- Không --> E["Chỉ gửi content"]
  D --> F["POST /api/messenger/messages/send"]
  E --> F
  F --> G["Java MessageController.send"]
  G --> H["MessageService kiểm tra user thuộc conversation"]
  H --> I["Lưu MESSAGES"]
  I --> J["Lưu ATTACHMENTS nếu có"]
  J --> K["Cập nhật CONVERSATIONS last_message"]
  K --> L["STOMP/WebSocket đẩy message realtime"]
  L --> M["Frontend append message"]
  

27. Tải lịch sử tin nhắn

flowchart LR
  A["Frontend mở một conversation"] --> B["GET /api/messenger/messages/conversation/{conversationId}"]
  B --> C["Java MessageController.getByConversation"]
  C --> D["MessageService kiểm tra membership"]
  D --> E["Query MESSAGES chưa deleted"]
  E --> F["Join ATTACHMENTS và sender profile"]
  F --> G["Cập nhật MESSAGE_STATUS/last read nếu có"]
  G --> H["Trả danh sách message"]
  H --> I["Frontend render thread chat"]
  

28. Quản lý nhóm chat

flowchart LR
  A["Admin nhóm thao tác"] --> B{"Thao tác nhóm"}
  B -- Đổi thông tin --> C["PATCH /api/messenger/conversations/{conversationId}"]
  B -- Thêm thành viên --> D["POST /api/messenger/conversations/{conversationId}/members/{targetUserId}"]
  B -- Xóa thành viên --> E["DELETE /api/messenger/conversations/{conversationId}/members/{targetUserId}"]
  B -- Thêm admin --> F["POST /api/messenger/conversations/{conversationId}/admins/{targetUserId}"]
  B -- Tự hạ admin --> G["POST /api/messenger/conversations/{conversationId}/admins/me/demote"]
  C --> H["ConversationService kiểm tra role"]
  D --> H
  E --> H
  F --> H
  G --> H
  H --> I["Cập nhật CONVERSATIONS/CONVERSATION_MEMBERS"]
  I --> J["Trả conversation mới"]
  J --> K["Frontend cập nhật nhóm chat"]
  

29. Thông báo và realtime notification

flowchart LR
  A["Sự kiện: like/comment/friend/report/story"] --> B["NotificationService tạo NOTIFICATION"]
  B --> C["Lưu notification theo user_id"]
  C --> D["SignalR NotificationsHub /hubs/notifications"]
  D --> E["Frontend đang online nhận realtime"]
  E --> F["Cập nhật badge/toast"]
  F --> G["Người dùng mở thông báo"]
  G --> H["GET /api/notifications"]
  H --> I["Trả danh sách notification"]
  I --> J["PATCH /api/notifications/{id}/read hoặc /read-all"]
  J --> K["Đánh dấu is_read=true"]
  

30. Báo cáo bài viết, bình luận, story, người dùng

flowchart LR
  A["Người dùng bấm báo cáo nội dung"] --> B{"Loại báo cáo"}
  B -- Post --> C["POST /api/post-reports"]
  B -- Comment --> D["POST /api/comment-reports"]
  B -- Story --> E["POST /api/story-reports"]
  B -- User --> F["POST /api/user-reports"]
  C --> G["ReportService kiểm tra target tồn tại"]
  D --> G
  E --> G
  F --> G
  G --> H["Lưu REPORT status Pending"]
  H --> I["Admin xem danh sách report"]
  I --> J["GET /api/*-reports hoặc pending-count"]
  J --> K["Admin resolve/delete report"]
  K --> L["PATCH /resolve hoặc DELETE"]
  

31. Quản trị người dùng

flowchart LR
  A["Admin đăng nhập"] --> B["POST /api/auth/admin/login"]
  B --> C["C# kiểm tra role ADMIN trong token"]
  C --> D{"Có quyền admin?"}
  D -- Không --> E["403 Forbidden"]
  D -- Có --> F["GET /api/admin/dashboard"]
  F --> G["AdminConsoleService tổng hợp thống kê"]
  G --> H["GET /api/admin/users/search"]
  H --> I["Tìm user qua Java Admin API/read model"]
  I --> J["PATCH /api/admin/users/{userId}/status"]
  J --> K["Cập nhật trạng thái user"]
  K --> L["Ghi ADMIN_AUDIT_LOG"]
  L --> M["GET /api/admin/audit-logs"]
  

32. Đánh giá ứng dụng

flowchart LR
  A["Người dùng mở prompt đánh giá"] --> B["GET /api/app-reviews/me"]
  B --> C{"Đã từng đánh giá?"}
  C -- Chưa --> D["POST /api/app-reviews"]
  C -- Rồi --> E["PUT /api/app-reviews/me"]
  D --> F["AppReviewService validate rating/content"]
  E --> F
  F --> G["Lưu APP_REVIEW"]
  G --> H["GET /api/app-reviews/public hoặc /summary"]
  H --> I["Frontend hiển thị điểm trung bình/public reviews"]
  I --> J["Admin hide/unhide/delete nếu cần"]
  J --> K["PATCH /api/admin/app-reviews/{id}/hide hoặc DELETE"]
  

33. Game: tạo phòng và tham gia phòng

flowchart LR
  A["Người dùng mở trang game"] --> B["GET /api/games"]
  B --> C["C# GamesController trả danh sách game"]
  C --> D["POST /api/games/rooms"]
  D --> E["GameRoomService tạo roomCode, hostUserId"]
  E --> F["Trả roomId/roomCode"]
  F --> G["Người khác nhập code"]
  G --> H["POST /api/games/rooms/join-by-code"]
  H --> I["Kiểm tra room còn chỗ/trạng thái"]
  I --> J["Thêm player vào room"]
  J --> K["SignalR GamesHub thông báo room updated"]
  K --> L["Frontend chuyển vào màn chơi"]
  

34. Game realtime: gửi nước đi và rời phòng

flowchart LR
  A["Player thực hiện nước đi"] --> B["SignalR /hubs/games gửi event"]
  B --> C["GamesHub nhận move"]
  C --> D["Game service tương ứng: Chess/Caro/Snake/Flappy"]
  D --> E["Validate lượt chơi, trạng thái, luật game"]
  E --> F{"Move hợp lệ?"}
  F -- Không --> G["Trả lỗi cho client"]
  F -- Có --> H["Cập nhật trạng thái room/game"]
  H --> I["Broadcast state cho các player"]
  I --> J["Player rời phòng"]
  J --> K["POST /api/games/rooms/leave hoặc disconnect hub"]
  K --> L["GameRoomService xử lý leave/disconnect"]
  L --> M["Broadcast room/game ended nếu cần"]
  

35. Upload media qua Cloudinary

flowchart LR
  A["Frontend cần upload ảnh/video"] --> B["GET /api/media/cloudinary-signature"]
  B --> C["C# MediaController kiểm tra JWT"]
  C --> D["CloudinarySigningService kiểm tra cấu hình"]
  D --> E["Sinh signature, timestamp, folder, apiKey"]
  E --> F["Frontend upload trực tiếp lên Cloudinary"]
  F --> G{"Upload thành công?"}
  G -- Không --> H["Hiển thị lỗi upload"]
  G -- Có --> I["Nhận secure_url/resource_type"]
  I --> J["Gửi media_url vào post/story/message API"]
  

36. Luồng gateway giữa frontend, C# API và Java API

flowchart LR
  A["Frontend web Cloudflare Pages"] --> B{"Endpoint được gọi"}
  B -- Post/Comment/Story/Notification/Game/Report --> C["C# API Render"]
  B -- Auth/Profile/Friend/Messenger --> D["Java API Render"]
  C --> E{"C# cần dữ liệu user/profile?"}
  E -- Có --> F["JavaApiService gọi Java API"]
  E -- Không --> G["PostgreSQL/Redis/SignalR"]
  F --> H["Java API xử lý user/profile/friend"]
  H --> I["MySQL/Redis/WebSocket"]
  D --> I
  G --> J["Trả response về frontend"]
  I --> J
  J --> K["Frontend cập nhật UI"]