Skip to content

Task 1-1: Chuẩn hóa Error Events cho Matching

Phase: 1 Priority: Medium Module: websocket Depends on: Không có Blocks: task-3-1, task-3-2, task-3-3 Reference: docs/BountyHunter-Backend/details/feature-matching-matchmaking/SPEC.md

Background

Error events từ matching/pool/invitation dùng VALIDATE_GAME chung với reason strings không chuẩn hóa. Cần tạo constants và đảm bảo leave graceful.

Tasks

1. Tạo MatchingReasonCode constants

DI Note: MatchingReasonCode là utility class với constants — không cần inject, không cần @Component. Các consumer handlers (MatchMatchingCmdConsumer, OpponentPoolCmdHandler, InvitationCmdConsumer) đã inject BroadcastService (hoặc tương đương) để gửi events — chỉ cần replace hardcoded string bằng constant, không cần thêm injection mới.

File mới: common/src/main/java/com/figpop/common/constants/MatchingReasonCode.java

public final class MatchingReasonCode {
    private MatchingReasonCode() {}  // Prevent instantiation

    public static final String INVALID_PRIZE_IDS = "INVALID_PRIZE_IDS";
    public static final String INVALID_PRIZE_ALLOCATION_TYPE = "INVALID_PRIZE_ALLOCATION_TYPE";
    public static final String INVITATION_EXPIRED = "INVITATION_EXPIRED";
    public static final String INVITATION_NOT_FOUND = "INVITATION_NOT_FOUND";
    public static final String TARGET_USER_BUSY = "TARGET_USER_BUSY";
    // ... thêm sau khi audit tất cả VALIDATE_GAME usages
}

2. Audit và replace hardcoded strings

  • [ ] Grep tất cả VALIDATE_GAME broadcasts trong source code:
    grep -rn "VALIDATE_GAME" websocket/ application-core/
    
  • [ ] Replace với MatchingReasonCode.* trong:
  • MatchMatchingCmdConsumer.java
  • OpponentPoolCmdHandler.java
  • InvitationCmdConsumer.java
  • CreateRoomService.java (matching paths)
  • [ ] Thêm tất cả reason codes tìm được vào MatchingReasonCode.java

3. Đảm bảo leave graceful

DI Note: MatchMatchingCmdConsumer inject CreateRoomService để gọi leaveAutoMatchMatching(). Exception type cần xác nhận (có thể là MatchingRecordNotFoundException, NotFoundException, hoặc custom exception từ application-core). Kiểm tra package com.figpop.common.exception để tìm đúng class name.

File: websocket/handler/consumer_handler/MatchMatchingCmdConsumer.java

@OnCmd("LEAVE_QUEUE_MATCH_MATCHING")
public void onLeaveAutoMatching(JSONObject objectMessage, String userId) {
    try {
        String settingId = objectMessage.getString("playable_game_booth_setting_id");
        String prizeId = objectMessage.optString("prize_id", null);
        createRoomService.leaveAutoMatchMatching(userId, settingId, prizeId);
        // Optional: broadcast success
    } catch (MatchingRecordNotFoundException e) {
        // Graceful: log warning, không broadcast error về client
        LOGGER.warn("[MATCHING] No matching record found for user {} - ignoring leave", userId);
    }
}

Verification / Acceptance Criteria

  • [ ] MatchingReasonCode.java tồn tại tại path common/constants/ và compile thành công
  • [ ] Grep VALIDATE_GAME trong các consumer handlers → tất cả hardcoded strings đã được thay bằng MatchingReasonCode.*
  • [ ] Khi LEAVE_QUEUE_MATCH_MATCHING gửi mà user không trong queue → server log WARN, không broadcast error tới client
  • [ ] Unit test: MatchingReasonCode.INVALID_PRIZE_IDS.equals("INVALID_PRIZE_IDS") = true

Files to Modify

  • common/constants/MatchingReasonCode.java (new)
  • websocket/handler/consumer_handler/MatchMatchingCmdConsumer.java
  • websocket/handler/consumer_handler/OpponentPoolCmdHandler.java
  • websocket/handler/consumer_handler/InvitationCmdConsumer.java