GameCreationServiceTest called createGame which routes through
RedisGameRegistry.store → IoGrpcClientWrapper.exportCombined, hitting a
real gRPC stub that fails with UNIMPLEMENTED in tests.
MockRedisDataSourceProducer's RETURNS_DEEP_STUBS mock caused a classloader
mismatch when GameCreationStreamListener called .stream() on it
(PubSubCommands mock returned instead of StreamCommands).
- Add @InjectMock IoGrpcClientWrapper + @BeforeEach stub in GameCreationServiceTest
- Add nowchess.game-creation-stream.enabled: false to core test application.yml
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CDI fires StartupEvent to all observer beans regardless of @InjectMock
substitution, causing GameCreationStreamClient and GameCreationStreamListener
to start their poll loops during @QuarkusTest even when mocked. Without
Redis configured in account tests, this floods logs with NPE stack traces
from the unconfigured RedisDataSource synthetic bean.
- Switch @Startup/@PostConstruct to @Observes StartupEvent on both beans
- Guard startup body with nowchess.game-creation-stream.enabled (default true)
- Disable the flag in modules/account/src/test/resources/application.yml
Mirrors the nowchess.coordinator.enabled pattern in InstanceHeartbeatService.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace synchronous account→core game-creation HTTP call and plain
pub/sub bot game-start events with Redis Streams using consumer groups,
XACK, retry, and a Dead Letter Queue for at-least-once delivery and
observability.
- account: GameCreationStreamClient publishes game-creation requests and
correlates responses via a per-instance consumer group (NCS-91)
- core: GameCreationStreamListener consumes requests, calls
GameCreationService, publishes response events, retries, and routes
exhausted/unparseable events to the DLQ (NCS-91, NCS-93, NCS-94)
- official-bots: bot game-start events migrated from pub/sub to Streams
with consumer group, XACK, retry, and DLQ (NCS-92)
- account EventPublisher dual-writes to the stream and legacy pub/sub
channel for backward compatibility
- all flows use the typed EventEnvelope (eventId/type/payload/timestamp/
correlationId) with DLQ error context (eventType, error, attempt)
- register new DTOs and EventEnvelope/EventType for native reflection
Closes NCS-91, NCS-92, NCS-93, NCS-94
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>