feat(tournament): wire official bots into tournaments via JWT and Redis
- Add token field to OfficialBotAccount and generate a non-expiring bot JWT on creation so official bots can authenticate - Expose token in POST /api/account/official-bots response and open the endpoint to any authenticated user - Bridge TournamentService to Redis: publish gameStart events to nowchess:bot:<name>:events after each pairing so OfficialBotService picks up games automatically Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -75,4 +75,7 @@ class OfficialBotAccount extends PanacheEntityBase:
|
||||
var rating: Int = 1500
|
||||
|
||||
var createdAt: Instant = uninitialized
|
||||
|
||||
@Column(length = 1024)
|
||||
var token: String = uninitialized
|
||||
// scalafix:on
|
||||
|
||||
@@ -46,7 +46,7 @@ case class BotAccountWithTokenDto(id: String, name: String, rating: Int, token:
|
||||
|
||||
case class RotatedTokenDto(token: String)
|
||||
|
||||
case class OfficialBotAccountDto(id: String, name: String, rating: Int, createdAt: String)
|
||||
case class OfficialBotAccountDto(id: String, name: String, rating: Int, createdAt: String, token: Option[String] = None)
|
||||
|
||||
case class OfficialChallengeResponse(gameId: String, botName: String, difficulty: Int)
|
||||
|
||||
|
||||
@@ -195,11 +195,11 @@ class AccountResource:
|
||||
|
||||
@POST
|
||||
@Path("/official-bots")
|
||||
@RolesAllowed(Array("Admin"))
|
||||
@RolesAllowed(Array("**"))
|
||||
def createOfficialBot(req: CreateBotAccountRequest): Response =
|
||||
accountService.createOfficialBotAccount(req.name) match
|
||||
case Right(bot) =>
|
||||
Response.status(Response.Status.CREATED).entity(toOfficialBotDto(bot)).build()
|
||||
Response.status(Response.Status.CREATED).entity(toOfficialBotDtoWithToken(bot)).build()
|
||||
case Left(error) =>
|
||||
Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(ErrorDto(error.message)).build()
|
||||
|
||||
@@ -219,3 +219,12 @@ class AccountResource:
|
||||
rating = bot.rating,
|
||||
createdAt = bot.createdAt.toString,
|
||||
)
|
||||
|
||||
private def toOfficialBotDtoWithToken(bot: OfficialBotAccount): OfficialBotAccountDto =
|
||||
OfficialBotAccountDto(
|
||||
id = bot.id.toString,
|
||||
name = bot.name,
|
||||
rating = bot.rating,
|
||||
createdAt = bot.createdAt.toString,
|
||||
token = Some(bot.token),
|
||||
)
|
||||
|
||||
@@ -205,6 +205,8 @@ class AccountService:
|
||||
bot.name = botName
|
||||
bot.createdAt = Instant.now()
|
||||
officialBotAccountRepository.persist(bot)
|
||||
bot.token = generateBotToken(bot.id, bot.name)
|
||||
officialBotAccountRepository.persist(bot)
|
||||
Right(bot)
|
||||
|
||||
@Transactional
|
||||
|
||||
Reference in New Issue
Block a user