Fix: 보상 이중 지급 방지, 에러 응답 개선, Rate Limit 조정
Some checks failed
Server CI/CD / lint-and-build (push) Failing after 32s
Server CI/CD / deploy (push) Has been skipped

- reward_worker에 txCheck 기반 이중 지급 방지 추가 (LastTxID 저장 후 재시도 전 확인)
- RewardFailure 모델에 LastTxID 필드 추가
- grantWithRetry가 txID를 반환하도록 변경
- 10회 재시도 초과 시 CRITICAL 로그에 상세 정보 포함
- 경험치 실패도 hasRewardFailure에 반영하여 reward_failed 상태 전이
- 에러 응답에 requestId 필드 포함 (관측성 개선)
- /api/auth/refresh를 authLimiter에서 분리 (NAT 환경 한도 초과 방지)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-19 21:01:45 +09:00
parent dc2bcb1c5d
commit 9883985968
7 changed files with 110 additions and 34 deletions

25
main.go
View File

@@ -106,9 +106,12 @@ func main() {
brRepo := bossraid.NewRepository(db)
brSvc := bossraid.NewService(brRepo, rdb)
brSvc.SetRewardGranter(func(username string, tokenAmount uint64, assets []core.MintAssetPayload) error {
_, err := chainSvc.GrantRewardByUsername(username, tokenAmount, assets)
return err
brSvc.SetRewardGranter(func(username string, tokenAmount uint64, assets []core.MintAssetPayload) (string, error) {
result, err := chainSvc.GrantRewardByUsername(username, tokenAmount, assets)
if result != nil {
return result.TxID, err
}
return "", err
})
brSvc.SetExpGranter(func(username string, exp int) error {
return playerSvc.GrantExperienceByUsername(username, exp)
@@ -151,13 +154,23 @@ func main() {
rewardWorker := bossraid.NewRewardWorker(
brRepo,
func(username string, tokenAmount uint64, assets []core.MintAssetPayload) error {
_, err := chainSvc.GrantRewardByUsername(username, tokenAmount, assets)
return err
func(username string, tokenAmount uint64, assets []core.MintAssetPayload) (string, error) {
result, err := chainSvc.GrantRewardByUsername(username, tokenAmount, assets)
if result != nil {
return result.TxID, err
}
return "", err
},
func(username string, exp int) error {
return playerSvc.GrantExperienceByUsername(username, exp)
},
func(txID string) (bool, error) {
result, err := chainClient.GetTxStatus(txID)
if err != nil {
return false, err
}
return result != nil && result.Success, nil
},
)
rewardWorker.Start()