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 60c77cfd..abcb87e8 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 @@ -53,7 +53,25 @@ func (uc *ReportCompletionUseCase) Execute( return nil, err } - // 3. Update participant status to completed + // 3. Get participant and check current status + participant, err := session.GetParticipant(partyID) + if err != nil { + return nil, err + } + + // 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 + if err := session.UpdateParticipantStatus(partyID, value_objects.ParticipantStatusReady); err != nil { + return nil, err + } + logger.Debug("auto-transitioned participant to ready", + zap.String("session_id", session.ID.String()), + zap.String("party_id", inputData.PartyID)) + } + + // 3.2 Update participant status to completed if err := session.UpdateParticipantStatus(partyID, value_objects.ParticipantStatusCompleted); err != nil { return nil, err } @@ -67,10 +85,6 @@ func (uc *ReportCompletionUseCase) Execute( } // 4. Update participant's public key if provided - participant, err := session.GetParticipant(partyID) - if err != nil { - return nil, err - } if len(inputData.PublicKey) > 0 { participant.SetPublicKey(inputData.PublicKey) }