fix(official-bots): sync bots before token fetch on first startup after DB wipe
Build & Test (NowChessSystems) TeamCity build finished

OfficialBotService.onStart fires on StartupEvent (after all @PostConstruct),
so official bot accounts do not exist in the account service DB yet when
TournamentBotGamePlayer.initialize() runs on a fresh DB. This caused
getBotToken to 404, falling back to the stale TOURNAMENT_BOT_TOKEN env
var which uses the old signing key and is rejected with 401.

fetchTokenFromAccountService now retries after syncing all official bot
accounts (creating them if missing), ensuring a fresh token with the
current signing key is always available on startup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Janis Eccarius
2026-06-22 20:21:35 +02:00
parent fd23c6e514
commit b0ddb274d2
@@ -62,9 +62,7 @@ class TournamentBotGamePlayer:
private def resolveToken(difficulty: String): Option[String] =
val name = botName(difficulty)
val redisKey = s"${redisConfig.prefix}:tournament-bot:token:$name"
Try(accountServiceClient.getBotToken(name).token)
.toOption
.filter(_.nonEmpty)
fetchTokenFromAccountService(name)
.map { token =>
redis.value(classOf[String]).set(redisKey, token)
log.infof("Fetched fresh bot token for %s from account service", name)
@@ -83,6 +81,16 @@ class TournamentBotGamePlayer:
}
}
private def fetchTokenFromAccountService(name: String): Option[String] =
Try(accountServiceClient.getBotToken(name).token).toOption.filter(_.nonEmpty)
.orElse {
Try {
val allNames = BotController.listBots.map(botName)
accountServiceClient.syncBots(de.nowchess.bot.client.SyncOfficialBotsRequest(allNames))
accountServiceClient.getBotToken(name).token
}.toOption.filter(_.nonEmpty)
}
private def parkOnStartup(token: Option[String]): Unit =
token match
case None => log.warn("No bot token resolved — skipping park")