game-service Architecture

duobao backend — lottery rounds, ticket buying, draw engine (3 modes), physical prize state machine

game-service (schema: one_u_game, port 6672) gateway-service JWT verify, header inject upstream AUTHENTICATED (JWT) /api/v1/game/* /api/v1/prize/* POST /api/v1/game/buy GET /api/v1/game/{id} GET /api/v1/game/list GET /api/v1/prize/my POST /api/v1/prize/{id}/confirm-addr v1.0 done INTERNAL FEIGN /internal/v1/game/* GET /{gameId} POST / POST /{gameId}/pause POST /{gameId}/resume POST /{gameId}/force-draw GET /order/{orderNo} GET /{gameId}/winner guard: ServiceTokenAuthFilter UserHeaderVerifyFilter v1.0 done ADMIN /admin/v1/* (via admin-service) POST /admin/v1/lottery/create POST /{gameId}/pause POST /{gameId}/force-draw GET /admin/v1/lottery/list guard: AdminAuthFilter (in admin-svc) v1.0 done SERVLET FILTERS ServiceTokenAuthFilter internal Feign auth UserHeaderVerifyFilter HMAC X-User-Id from gateway CONTROLLERS GameController /api/v1/game/* PrizeController /api/v1/prize/* GameInternalCtl /internal/v1/game/* AdminGameSvc /admin/v1/* SERVICES (business logic) RoundCreateSvc create round, lock draw_mode at create OrderBuyTxSvc Feign debit wallet + alloc tickets (lock) TicketAssignSvc RANDOM/MANUAL GRID/RANGE modes GameQuerySvc detail / list / winner cached reads OrderRecovery Svc SUBMITTED timeout DRAW ENGINE (DrawEngine interface, DrawEngineRouter) FullChainDraw Engine FULL_CHAIN mode VrfOnlyDraw Engine VRF_ONLY mode BackendDraw Engine BACKEND mode DrawOrchestration Svc routes by round.draw_mode DeadlinePoller @Scheduled DEADLINE mode PrizeDist Svc USDT/BTC/PHYSICAL PhysicalPrize Svc state machine + forfeit UnsoldStrategy Svc PLATFORM_COVER FEIGN CALLEE CLIENTS (game-service calls outbound) IWalletService debit / credit IChainService requestVrf / call ISignService signCommit (BACKEND) IUserService getUser / notify IAdminService enqueuePhysical EVENT PRODUCERS KafkaGameEventProducer game.round.created / sold_out / draw.requested / draw.completed / draw.timeout / round.canceled + prize.physical.* delivered / forfeited EVENT CONSUMER VrfFulfilledConsumer @KafkaListener("chain.vrf.fulfilled") — triggers draw settlement, writes oneu_draw_result MYBATIS MAPPERS OneuLottery Mapper OneuOrder Mapper OneuTicket Mapper OneuDrawResult Mapper BackendDraw CommitMapper OneuLottery PrizeMapper OneuUserPrize Mapper OneuPrizeTpl Mapper v1.0 done — 8 mappers + flyway_schema_history MySQL 8 schema: one_u_game • oneu_lottery (round master) • oneu_prize_template • oneu_lottery_prize • oneu_order • oneu_ticket • oneu_draw_result • oneu_user_prize (physical SM) • backend_draw_commit migrations V1 — 8 tables v1.0 done opt-lock via oneu_lottery.version Kafka broker kafka:29092 (compose) • produces 8 topics (see panel) • consumes chain.vrf.fulfilled Kafka Events — game-service game.round.created partition keygameId triggerRoundCreateSvc on new round consumed bychain-service · admin-service game.round.sold_out triggerOrderBuyTxSvc last ticket consumed bygame-service (self) · wallet-service game.draw.requested triggerDrawOrchestrationSvc pre-VRF consumed bychain-service (VRF request) game.draw.completed triggerVrfFulfilledConsumer settlement consumed bywallet · user · agent(v1.1+) game.draw.timeout triggerDeadlinePoller VRF >30 min consumed byadmin-service game.round.canceled wallet(refund) · user prize.physical.delivered user (push) prize.physical.forfeited wallet (70% USDT) · user CONSUMES: chain.vrf.fulfilled via VrfFulfilledConsumer game.round.sold_out (self) draws self-trigger scheduling v1.0 — 8 produced, 2 consumed LEGEND Controllers Services / sibling svc Auth filters DB / Mappers Events / channels External services Helpers / lanes Service boundary Cache / limiter line Kafka publish v1.1 deferred path v1.0 done v1.1 deferred conditional bean

What game-service owns

  • • Lottery round lifecycle: create, pause, resume, cancel, settle
  • • Ticket purchase (Feign-sync wallet.debit then ticket alloc)
  • • DrawEngine: 3 implementations (FULL_CHAIN / VRF_ONLY / BACKEND), mode locked at round creation
  • • Physical prize state machine (WAITING_ADDRESS → WAITING_AUDIT → SHIPPED → DELIVERED / FORFEITED)
  • • VRF timeout detection (DeadlinePoller @Scheduled) — no auto-fallback, escalates to admin
  • • 8 Kafka topics produced, 2 consumed

Kafka events produced + consumed

  • Produces: game.round.created / game.round.sold_out / game.draw.requested
  • Produces: game.draw.completed / game.draw.timeout / game.round.canceled
  • Produces: prize.physical.delivered / prize.physical.forfeited
  • Consumes: chain.vrf.fulfilled — settles draw, writes oneu_draw_result
  • Consumes: game.round.sold_out (self) — triggers DrawEngineRouter

External dependencies

  • • MySQL one_u_game — 8 tables, V1 migration
  • • Kafka kafka:29092 — 8 topics produced, 2 consumed
  • • Feign: IWalletService (debit/credit), IChainService (VRF/contract), ISignService (BACKEND commit)
  • • Feign: IUserService (getUser), IAdminService (enqueuePhysicalPrize)
  • • No direct Redis (rate-limit delegated to gateway)