From 00b48bab506cca3e1939daba9bacfe6af99a46f0 Mon Sep 17 00:00:00 2001 From: hailin Date: Sat, 6 Dec 2025 01:09:49 -0800 Subject: [PATCH] fix(coordinator): handle all participant states in ReportCompletion with proper state transitions - Add switch-case to handle Invited, Joined, and Ready states - Auto-transition Invited -> Joined -> Ready -> Completed - Auto-transition Joined -> Ready -> Completed - Auto-transition Ready -> Completed - Return error for invalid states (Failed, Completed, etc.) - Fixes 'cannot transition to completed status' error - Applies to all parties including server-party-api --- .../use_cases/report_completion.go | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/backend/mpc-system/services/session-coordinator/application/use_cases/report_completion.go b/backend/mpc-system/services/session-coordinator/application/use_cases/report_completion.go index abcb87e8..193ae5b3 100644 --- a/backend/mpc-system/services/session-coordinator/application/use_cases/report_completion.go +++ b/backend/mpc-system/services/session-coordinator/application/use_cases/report_completion.go @@ -2,6 +2,7 @@ package use_cases import ( "context" + "fmt" "time" "github.com/rwadurian/mpc-system/pkg/logger" @@ -60,15 +61,37 @@ func (uc *ReportCompletionUseCase) Execute( } // 3.1 Ensure participant is in Ready state before marking as Completed - // The status flow is: Joined -> Ready -> Completed - if participant.Status == value_objects.ParticipantStatusJoined { - // Auto-transition to Ready if currently Joined + // The status flow is: Invited -> Joined -> Ready -> Completed + // Handle all possible states to reach Ready + switch participant.Status { + case value_objects.ParticipantStatusInvited: + // Invited -> Joined + if err := session.UpdateParticipantStatus(partyID, value_objects.ParticipantStatusJoined); err != nil { + return nil, err + } + logger.Debug("auto-transitioned participant from invited to joined", + zap.String("session_id", session.ID.String()), + zap.String("party_id", inputData.PartyID)) + // Joined -> Ready if err := session.UpdateParticipantStatus(partyID, value_objects.ParticipantStatusReady); err != nil { return nil, err } - logger.Debug("auto-transitioned participant to ready", + logger.Debug("auto-transitioned participant from joined to ready", zap.String("session_id", session.ID.String()), zap.String("party_id", inputData.PartyID)) + case value_objects.ParticipantStatusJoined: + // Joined -> Ready + if err := session.UpdateParticipantStatus(partyID, value_objects.ParticipantStatusReady); err != nil { + return nil, err + } + logger.Debug("auto-transitioned participant from joined to ready", + zap.String("session_id", session.ID.String()), + zap.String("party_id", inputData.PartyID)) + case value_objects.ParticipantStatusReady: + // Already ready, no transition needed + default: + // Invalid state for completion (Failed, Completed, etc.) + return nil, fmt.Errorf("participant in invalid state for completion: %s", participant.Status) } // 3.2 Update participant status to completed