fix: gate research pool trial creation

This commit is contained in:
codyhhchen
2026-05-05 23:17:32 +08:00
committed by codychen123
parent 7c8761a049
commit 4057b3f611
8 changed files with 76 additions and 23 deletions
@@ -6,6 +6,7 @@ import com.wrbug.polymarketbot.service.copytrading.leaderpool.LeaderPoolAlreadyE
import com.wrbug.polymarketbot.service.copytrading.leaderpool.LeaderPoolConfirmRequiredException
import com.wrbug.polymarketbot.service.copytrading.leaderpool.LeaderPoolDuplicateTrialConfigException
import com.wrbug.polymarketbot.service.copytrading.leaderpool.LeaderPoolNotFoundException
import com.wrbug.polymarketbot.service.copytrading.leaderpool.LeaderPoolResearchCandidateNotReadyException
import com.wrbug.polymarketbot.service.copytrading.leaderpool.LeaderPoolService
import org.slf4j.LoggerFactory
import org.springframework.context.MessageSource
@@ -146,6 +147,7 @@ class LeaderPoolController(
is LeaderPoolAlreadyExistsException -> ErrorCode.LEADER_POOL_ALREADY_EXISTS
is LeaderPoolDuplicateTrialConfigException -> ErrorCode.LEADER_POOL_DUPLICATE_TRIAL_CONFIG
is LeaderPoolConfirmRequiredException -> ErrorCode.LEADER_POOL_CONFIRM_REQUIRED
is LeaderPoolResearchCandidateNotReadyException -> ErrorCode.LEADER_RESEARCH_CANDIDATE_NOT_READY
is IllegalArgumentException -> when (e.message) {
"账户不存在" -> ErrorCode.ACCOUNT_NOT_FOUND
"Leader 不存在" -> ErrorCode.LEADER_NOT_FOUND
@@ -166,6 +168,7 @@ class LeaderPoolController(
errorCode == ErrorCode.LEADER_POOL_ALREADY_EXISTS ||
errorCode == ErrorCode.LEADER_POOL_DUPLICATE_TRIAL_CONFIG ||
errorCode == ErrorCode.LEADER_POOL_CONFIRM_REQUIRED ||
errorCode == ErrorCode.LEADER_RESEARCH_CANDIDATE_NOT_READY ||
errorCode == ErrorCode.ACCOUNT_NOT_FOUND ||
errorCode == ErrorCode.LEADER_NOT_FOUND
}
@@ -7,3 +7,7 @@ class LeaderPoolAlreadyExistsException(message: String = "Leader 已在池子中
class LeaderPoolDuplicateTrialConfigException(message: String = "该账户已存在此 Leader 的跟单配置") : RuntimeException(message)
class LeaderPoolConfirmRequiredException(message: String = "立即启用试跟配置需要显式确认") : RuntimeException(message)
class LeaderPoolResearchCandidateNotReadyException(
message: String = "研究候选尚未进入试跟建议状态"
) : RuntimeException(message)
@@ -5,6 +5,7 @@ import com.wrbug.polymarketbot.entity.CopyTrading
import com.wrbug.polymarketbot.entity.Leader
import com.wrbug.polymarketbot.entity.LeaderPool
import com.wrbug.polymarketbot.enums.LeaderPoolStatus
import com.wrbug.polymarketbot.enums.LeaderResearchState
import com.wrbug.polymarketbot.repository.AccountRepository
import com.wrbug.polymarketbot.repository.CopyTradingRepository
import com.wrbug.polymarketbot.repository.LeaderPoolRepository
@@ -207,6 +208,15 @@ class LeaderPoolService(
}
return try {
if (pool.researchCandidateId != null && pool.researchState != LeaderResearchState.TRIAL_READY) {
logger.warn(
"拒绝从未试跟建议的研究候选创建 Leader 池试跟配置: poolId={}, leaderId={}, researchState={}",
pool.id,
pool.leaderId,
pool.researchState
)
return Result.failure(LeaderPoolResearchCandidateNotReadyException())
}
if (request.enableImmediately && !request.confirm) {
logger.warn("拒绝未确认的立即启用试跟配置: poolId={}, leaderId={}", pool.id, pool.leaderId)
return Result.failure(LeaderPoolConfirmRequiredException())
@@ -12,6 +12,7 @@ import com.wrbug.polymarketbot.entity.CopyTrading
import com.wrbug.polymarketbot.entity.Leader
import com.wrbug.polymarketbot.entity.LeaderPool
import com.wrbug.polymarketbot.enums.LeaderPoolStatus
import com.wrbug.polymarketbot.enums.LeaderResearchState
import com.wrbug.polymarketbot.repository.AccountRepository
import com.wrbug.polymarketbot.repository.CopyTradingRepository
import com.wrbug.polymarketbot.repository.LeaderPoolRepository
@@ -180,6 +181,20 @@ class LeaderPoolServiceTest {
assertEquals(LeaderPoolStatus.TRIAL, poolCaptor.value.status)
}
@Test
fun `research pool item must be trial ready before creating trial config`() {
Mockito.`when`(leaderPoolRepository.findById(10L)).thenReturn(
Optional.of(pool(researchCandidateId = 99, researchState = LeaderResearchState.PAPER))
)
val result = service.createTrialConfig(LeaderPoolCreateTrialConfigRequest(poolId = 10, accountId = 2))
assertTrue(result.isFailure)
assertTrue(result.exceptionOrNull() is LeaderPoolResearchCandidateNotReadyException)
Mockito.verify(accountRepository, Mockito.never()).findById(2L)
Mockito.verify(copyTradingService, Mockito.never()).createCopyTrading(anyCreateRequest())
}
@Test
fun `create trial failure leaves pool status unchanged`() {
Mockito.`when`(leaderPoolRepository.findById(10L)).thenReturn(Optional.of(pool()))
@@ -261,11 +276,15 @@ class LeaderPoolServiceTest {
private fun pool(
id: Long = 10,
leaderId: Long = 1,
status: LeaderPoolStatus = LeaderPoolStatus.CANDIDATE
status: LeaderPoolStatus = LeaderPoolStatus.CANDIDATE,
researchCandidateId: Long? = null,
researchState: LeaderResearchState? = null
) = LeaderPool(
id = id,
leaderId = leaderId,
status = status,
researchCandidateId = researchCandidateId,
researchState = researchState,
suggestedFixedAmount = BigDecimal("1"),
suggestedMaxDailyOrders = 10,
suggestedMaxDailyLoss = BigDecimal("5"),