Commit Graph

238 Commits

Author SHA1 Message Date
Janis db9d153391 feat(official-bots): consume GameOver stream for bot cleanup (#67)
Build & Test (NowChessSystems) TeamCity build finished
Add consumer group official-bots-game-over on {prefix}:game-over stream.
Track pub/sub subscribers per gameId in gameWatches map. On GameOver event,
unsubscribe from the game s2c channel and remove from watch map.
XACK after cleanup; DLQ after maxRetries failures.

Closes NCS-103
https://knockoutwhist.youtrack.cloud/issue/NCS-103

Reviewed-on: #67
2026-06-09 21:49:42 +02:00
Janis 55f102cbaa feat(ws): migrate challenge notifications to Redis Streams (#66)
Replace pub/sub publish in EventPublisher with XADD to user event stream.
UserWebSocketResource subscribes via XREADGROUP consumer group (per-connection
group, '$' offset). DLQ after maxRetries=3 on delivery failure. Poll loop
uses connection identity to prevent thread leak on reconnect.

Closes NCS-104
https://knockoutwhist.youtrack.cloud/issue/NCS-104

Reviewed-on: #66
2026-06-09 21:49:21 +02:00
Janis d66b6fa471 chore(account): remove dead CoreGameClient REST trait (#65)
Move CoreCreateGameRequest, CorePlayerInfo, CoreTimeControl to CoreGameDtos.
Delete CoreGameClient trait (replaced by GameCreationStreamClient) and
CoreGameResponse (unused after stream migration). Remove from reflection config.

Closes NCS-105
https://knockoutwhist.youtrack.cloud/issue/NCS-105

Reviewed-on: #65
2026-06-09 21:49:05 +02:00
Janis 676e4110c0 feat(core): publish GameOver event to Redis Streams (#64)
Add GameOver to EventType enum and GameOverPayload DTO.
GameRedisPublisher publishes to {prefix}:game-over stream (MAXLEN ~1000)
on game completion. NativeReflectionConfig updated for core module.

Closes NCS-102
https://knockoutwhist.youtrack.cloud/issue/NCS-102

Reviewed-on: #64
2026-06-09 21:48:41 +02:00
Janis 0ad2e10999 feat(bot-platform): migrate BotRegistry to Redis Streams consumer group (#63)
Replace pub/sub subscribe with XREADGROUP on bot game-start stream.
Remove dual-write from EventPublisher.publishGameStart.
Consumer group: bot-platform-consumer, XACK after forwarding.
Poll loop uses emitter identity to prevent thread leak on re-registration.
Group created with '$' offset — no historical replay on first connect.

Closes NCS-101
https://knockoutwhist.youtrack.cloud/issue/NCS-101

Reviewed-on: #63
2026-06-09 21:48:21 +02:00
TeamCity 225c2285b7 ci: bump version with Build-116 2026-06-09 13:28:34 +00:00
lq64 c5661de4a0 feat: NCS-82 add Swiss-system tournament module (#55)
Build & Test (NowChessSystems) TeamCity build finished
## Summary

  - Implements the full tournament lifecycle (create, join, withdraw, start,
    round progression, finish) as a standalone Quarkus module
  - All 11 endpoints from the OpenAPI spec (`docs/tournament-openapi.yaml`) are covered
  - Swiss pairing algorithm with Buchholz tiebreak and bye support
  - Per-bot NDJSON event stream with targeted `gameStart` events carrying
    the correct `color` field
  - Game results ingested via Redis writeback stream (`GameResultStreamListener`)

  ## Known gaps (deferred)

  - `GET /results` `nb` param defaults to 100 instead of all
  - `PairingDto` exposes an internal `id` field not in the spec
  - `GameExport.moves` emits PGN instead of UCI (upstream `GameWritebackEventDto`
    does not carry UCI moves)
  - `Pairing.white` can be `null` for bye rounds (spec has no bye concept)

  ## Test plan

  - [x] 23 `TournamentResourceTest` integration tests (H2, mocked core client) — all pass
  - [x] 5 `SwissPairingServiceTest` unit tests — all pass
  - [x] Redis listener excluded in test/dev profiles; no Docker required to run tests

---------

Co-authored-by: LQ63 <lkhermann@web.de>
Co-authored-by: Lala, Shahd <Shahd.Lala@sybit.de>
Reviewed-on: #55
2026-06-09 15:09:53 +02:00
TeamCity 3b6c5297f6 ci: bump version with Build-115 2026-06-09 08:54:49 +00:00
Janis a24924c230 feat(events): migrate game-creation and bot flows to Redis Streams NCS-89 (#62)
Build & Test (NowChessSystems) TeamCity build finished
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>

---------

Co-authored-by: Janis Eccarius <eccariusjanis@gmail.com>
Reviewed-on: #62
2026-06-09 10:31:32 +02:00
TeamCity e18b1df744 ci: bump version with Build-114
Build & Test (NowChessSystems) TeamCity build failed
2026-06-05 10:28:26 +00:00
Janis 595c172900 feat(api): define shared EventEnvelope and EventType for Redis EventBus (#61)
Build & Test (NowChessSystems) TeamCity build finished
- Add EventEnvelope case class (eventId, type, payload, timestamp, correlationId)
- Add EventType enum with all known event types
- Update account EventPublisher to use EventEnvelope instead of raw string interpolation
- Add EventEnvelope/EventType to account NativeReflectionConfig
- Add Jackson Scala and JSR310 modules to api dependencies
- Add api module dependency to account module
- Add NativeReflectionConfig rule to CLAUDE.md

Closes NCS-90
https://knockoutwhist.youtrack.cloud/issue/NCS-90

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Reviewed-on: #61
2026-06-05 12:11:14 +02:00
TeamCity 4762f6c0c3 ci: bump version with Build-111 2026-06-03 11:50:50 +00:00
shosho996 7117a93376 fix(official-bots): NCS-70-auto-register official bots with account service (#59)
Build & Test (NowChessSystems) TeamCity build finished
Co-authored-by: Janis <janis-e@gmx.de>
Reviewed-on: #59
2026-06-03 13:27:03 +02:00
TeamCity 085e34f062 ci: bump version with Build-110 2026-06-03 06:04:13 +00:00
Janis 32c388760b fix(store): cap game-writeback stream with MAXLEN trimming (#58)
Build & Test (NowChessSystems) TeamCity build finished
Add approximate MAXLEN ~1000 to all xadd calls in
GameWritebackStreamListener. Without trimming, ACKed messages
accumulate in the stream indefinitely, wasting Redis memory.

Closes NCS-88
https://knockoutwhist.youtrack.cloud/issue/NCS-88

---------

Co-authored-by: Janis Eccarius <eccariusjanis@gmail.com>
Reviewed-on: #58
2026-06-03 07:44:13 +02:00
TeamCity 9836e87392 ci: bump version with Build-108 2026-06-02 09:49:42 +00:00
Janis 2579539084 fix(pgn): add SAN disambiguation and check/checkmate suffixes [NCS-42] (#56)
Build & Test (NowChessSystems) TeamCity build finished
Two bugs in move notation causing PGN import failures in LiChess:

1. Disambiguation: when two pieces of same type can reach same square,
   SAN requires file/rank/full-square prefix (e.g. "Ndf3" not "Nf3").
   Added disambiguate() in PgnExporter and disambiguatePiece() in
   GameEngine, both querying allLegalMoves to find competing pieces.

2. Check/checkmate suffix: "+" and "#" were never appended.
   PgnExporter now threads ctxAfter through moveToAlgebraic and
   calls DefaultRules.isCheck/isCheckmate. GameEngine passes
   PostMoveStatus to translateMoveToNotation for the same result.

Also removes dead notation code in executeMoveBody (result was never
used — not passed to MoveExecutedEvent).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Janis Eccarius <eccariusjanis@gmail.com>
Reviewed-on: #56
2026-06-02 11:24:27 +02:00
TeamCity bc500e3e94 ci: bump version with Build-107 2026-05-31 15:31:55 +00:00
Janis Eccarius 2dbb1d0b67 refactor: improve code formatting and readability
Build & Test (NowChessSystems) TeamCity build finished
2026-05-31 17:04:00 +02:00
Janis Eccarius 252851de1c fix(store): replace null check with Option for stream messages
Build & Test (NowChessSystems) TeamCity build failed
2026-05-31 16:27:22 +02:00
Janis ae3ef766e8 feat(redis): implement game writeback stream processing with error handling and retries
Build & Test (NowChessSystems) TeamCity build failed
2026-05-22 12:37:39 +02:00
TeamCity 487711628f ci: bump version with Build-106 2026-05-22 10:00:20 +00:00
Janis 008d72d826 fix(dependencies): correct Jackson databind dependency group ID
Build & Test (NowChessSystems) TeamCity build finished
2026-05-22 11:38:34 +02:00
Janis 576e3fea9b feat(dto): update GameWritebackEventDto for JSON deserialization and remove unused mixin
Build & Test (NowChessSystems) TeamCity build failed
2026-05-22 11:35:55 +02:00
TeamCity 1f66b7bde7 ci: bump version with Build-105 2026-05-22 08:50:38 +00:00
Janis 381161f003 feat(config): add GameWritebackEventDtoMixin for JSON deserialization
Build & Test (NowChessSystems) TeamCity build finished
2026-05-22 10:23:30 +02:00
TeamCity d0150fdfa4 ci: bump version with Build-104 2026-05-21 09:33:30 +00:00
Janis 29072efbfb fix(account): configure JDBC connection pool size to prevent exhaustion under load
Build & Test (NowChessSystems) TeamCity build finished
Default Agroal pool (max-size=20) exhausted under concurrent logins due to
bcrypt latency per request. Fixes NCS-87.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 11:06:33 +02:00
TeamCity dcc5ce1195 ci: bump version with Build-103 2026-05-19 13:52:19 +00:00
Janis 354db11972 fix(tests): update token path to accessToken in ChallengeResourceTest
Build & Test (NowChessSystems) TeamCity build finished
2026-05-19 15:27:53 +02:00
Janis 9296db88b7 feat(account): implement token pair handling for login and refresh endpoints
Build & Test (NowChessSystems) TeamCity build failed
2026-05-19 14:41:21 +02:00
Janis ec22a9585e refactor(account): update time control structure and remove deprecated fields 2026-05-19 14:41:20 +02:00
TeamCity 411eed2453 ci: bump version with Build-102 2026-05-19 11:40:58 +00:00
Janis af6b0ed8b7 feat(redis): use ManagedExecutor for asynchronous writeback processing
Build & Test (NowChessSystems) TeamCity build finished
2026-05-19 13:16:07 +02:00
TeamCity bcd8257db2 ci: bump version with Build-101 2026-05-19 09:06:09 +00:00
Janis d61fe97b4c feat(redis): add @Startup annotation to GameWritebackStreamListener
Build & Test (NowChessSystems) TeamCity build finished
2026-05-19 10:44:51 +02:00
TeamCity 959bb53335 ci: bump version with Build-100 2026-05-19 08:13:51 +00:00
Janis b610678005 fix(redis): add log message for starting Writeback listener
Build & Test (NowChessSystems) TeamCity build finished
2026-05-19 09:48:21 +02:00
TeamCity d0552b08b5 ci: bump version with Build-99 2026-05-19 07:15:31 +00:00
Janis 87f29a7204 feat(config): add GameWritebackEventDto to reflection targets
Build & Test (NowChessSystems) TeamCity build finished
2026-05-19 08:49:48 +02:00
TeamCity cb44f491bd ci: bump version with Build-98 2026-05-18 21:25:03 +00:00
Janis f5614c3582 fix(core): add logs to trace subscribeGame call in createGame
Build & Test (NowChessSystems) TeamCity build finished
Track whether subscribeGame is being called and completing successfully
to diagnose empty game-writeback messages.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-05-18 22:55:33 +02:00
TeamCity 9d960d3ee5 ci: bump version with Build-97 2026-05-18 18:58:53 +00:00
Janis a9f4606b40 feat: force delete pod immediately on heartbeat loss
Build & Test (NowChessSystems) TeamCity build finished
When instance stream drops, immediately force delete the K8s pod (grace period 0). No waiting for health check or pod watch events.

Reduces failover latency and ensures stale pods don't linger.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-05-18 20:36:26 +02:00
Janis 32a12737e3 refactor: resource-based scaling only, remove health-check triggered scaling
Scale up: only if resource constrained (CPU/memory)
Scale down: only if NOT resource constrained AND game load low
Remove: triggering scale-up on unexpected instance failures
Keep: health monitoring (mark dead, delete pod, failover games) but no scaling

Prevents cascade scaling from transient health check failures.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-05-18 20:36:23 +02:00
TeamCity b4c75e2a0f ci: bump version with Build-96 2026-05-17 20:01:45 +00:00
Janis 9bf995f47d fix: revert pod matching to original logic instanceId.contains(podName)
Build & Test (NowChessSystems) TeamCity build finished
Accidentally flipped pod matching direction in previous commits. Changed from correct instanceId.contains(podName) to incorrect podName.contains(instanceId), causing all health checks to fail.

Reverted all 3 locations to original working logic.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-05-17 21:35:16 +02:00
TeamCity 8df418627c ci: bump version with Build-95 2026-05-17 18:53:07 +00:00
Janis 6dbe1e62ac fix: correct pod matching logic from endsWith to contains
Build & Test (NowChessSystems) TeamCity build finished
Pod matching used endsWith(instanceId) which failed to match any pods because instanceId is randomly generated 8-char string, not pod name suffix. All instances marked dead causing cascading health check failures.

Changed to podName.contains(instanceId) to match instanceId embedded anywhere in pod name. Reverting incomplete fix from previous commit.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-05-17 20:26:08 +02:00
TeamCity 6311d8fd00 ci: bump version with Build-94 2026-05-17 17:07:55 +00:00