Compare commits

..

36 Commits

Author SHA1 Message Date
TeamCity dcebdf237e ci: bump version with Build-70 2026-05-08 12:26:57 +00:00
Janis 0f41f13ce6 fix: update HealthMonitor to evict instances without associated pods
Build & Test (NowChessSystems) TeamCity build finished
2026-05-08 14:10:53 +02:00
TeamCity ae6d235e1d ci: bump version with Build-69 2026-05-08 10:54:01 +00:00
Janis b4920d3817 fix: enhance AutoScaler and InstanceRegistry for replica management and stale instance eviction
Build & Test (NowChessSystems) TeamCity build finished
2026-05-08 12:37:23 +02:00
TeamCity 708ebaf6e5 ci: bump version with Build-68 2026-05-06 07:06:52 +00:00
Janis 0eb752d493 fix(redis): enhance GameRedisSubscriberManager to use ReactiveRedisDataSource and improve subscription handling
Build & Test (NowChessSystems) TeamCity build finished
2026-05-06 08:41:30 +02:00
Janis e279c39246 fix(auth): add InternalClientHeadersFactory for custom client headers management
Build & Test (NowChessSystems) TeamCity build failed
2026-05-06 08:07:58 +02:00
TeamCity a101866bcf ci: bump version with Build-67 2026-05-05 18:20:39 +00:00
Janis 5baf6a7cdb fix(redis): update Redis configuration with max pool size and waiting parameters
Build & Test (NowChessSystems) TeamCity build finished
2026-05-05 20:01:32 +02:00
TeamCity a10958b0d1 ci: bump version with Build-66 2026-05-05 07:07:00 +00:00
Janis dc224abe26 fix: Lints
Build & Test (NowChessSystems) TeamCity build finished
2026-05-05 08:44:25 +02:00
Janis 1813ea1d2d fix(redis): simplify refreshRedisHeartbeat logic and ensure proper error handling
Build & Test (NowChessSystems) TeamCity build failed
2026-05-05 08:24:10 +02:00
Janis 6e0fd9523e fix(auth): update InternalAuthFilter to use @ApplicationScoped and add index-dependency configuration
Build & Test (NowChessSystems) TeamCity build failed
2026-05-05 06:49:45 +02:00
Janis 847b13202c fix(redis): prevent concurrent Redis heartbeat refreshes using AtomicBoolean
Build & Test (NowChessSystems) TeamCity build failed
2026-05-04 22:45:45 +02:00
Janis c08d5303eb fix(auth): change InternalAuthFilter to use @Singleton and add HTTP tests for secret validation
Build & Test (NowChessSystems) TeamCity build failed
2026-05-03 17:27:30 +02:00
Janis 33e5017f51 fix(redis): add max pool wait time and switch to ReactiveRedisDataSource for heartbeat updates
Build & Test (NowChessSystems) TeamCity build failed
2026-05-03 16:47:54 +02:00
TeamCity de391113dc ci: bump version with Build-65 2026-05-03 11:30:40 +00:00
Janis 85b187293f fix(auth): correct internal secret validation logic in InternalAuthFilter
Build & Test (NowChessSystems) TeamCity build finished
2026-05-03 13:12:57 +02:00
TeamCity 4a145cb538 ci: bump version with Build-64 2026-05-03 10:34:44 +00:00
Janis 327c23a6aa fix(ci): update image existence check to use GitHub token for authentication
Build & Test (NowChessSystems) TeamCity build finished
2026-05-03 12:16:31 +02:00
Janis d522f7f6ed fix(coordinator): refine type casting in rolloutSpec method (#45)
Build & Test (NowChessSystems) TeamCity build failed
Reviewed-on: #45
Co-authored-by: Janis <janis.e.20@gmx.de>
Co-committed-by: Janis <janis.e.20@gmx.de>
2026-05-03 12:12:39 +02:00
Janis 82d0b754be fix(coordinator): use genericKubernetesResources API for Argo Rollout scaling (#44)
Build & Test (NowChessSystems) TeamCity build failed
Reviewed-on: #44
Co-authored-by: Janis <janis.e.20@gmx.de>
Co-committed-by: Janis <janis.e.20@gmx.de>
2026-05-02 22:27:18 +02:00
TeamCity 4694f516fa ci: bump version with Build-63 2026-05-02 19:39:06 +00:00
Janis fa3c6b2886 fix(coordinator): use genericKubernetesResources API for Argo Rollout scaling (#43)
Build & Test (NowChessSystems) TeamCity build finished
fabric8 disallows client.resources(classOf[GenericKubernetesResource]) — throws
KubernetesClientException at runtime. Switch to genericKubernetesResources(apiVersion, kind)
which is the correct API for CRDs.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

Reviewed-on: #43
Co-authored-by: Janis <janis.e.20@gmx.de>
Co-committed-by: Janis <janis.e.20@gmx.de>
2026-05-02 21:22:53 +02:00
TeamCity e472fb75ad ci: bump version with Build-62 2026-05-02 17:12:34 +00:00
Janis 5f44570b35 fix(dependencies): replace Fabric8 Kubernetes client with Quarkus Kubernetes client
Build & Test (NowChessSystems) TeamCity build finished
2026-05-02 18:52:47 +02:00
Janis c16f139c8e fix(ci): add version check and conditional steps for image existence in GHCR
Build & Test (NowChessSystems) TeamCity build failed
2026-05-02 18:39:09 +02:00
TeamCity cabf1bca73 ci: bump version with Build-61 2026-05-02 16:33:43 +00:00
Janis 0c981517da fix(heartbeat): inject ObjectMapper into InstanceHeartbeatService (#42)
Build & Test (NowChessSystems) TeamCity build finished
Reviewed-on: #42
Co-authored-by: Janis <janis.e.20@gmx.de>
Co-committed-by: Janis <janis.e.20@gmx.de>
2026-05-02 18:15:29 +02:00
TeamCity 18a4b1cc15 ci: bump version with Build-60 2026-05-02 15:53:05 +00:00
Janis 804a4bf179 feat(logging): add DEBUG/INFO/WARN logging across services (NCS-72) (#41)
Build & Test (NowChessSystems) TeamCity build finished
Reviewed-on: #41
Co-authored-by: Janis <janis.e.20@gmx.de>
Co-committed-by: Janis <janis.e.20@gmx.de>
2026-05-02 17:33:27 +02:00
TeamCity 3c47d2b8c9 ci: bump version with Build-58 2026-05-01 18:23:46 +00:00
Janis d346c41d98 refactor: improve code formatting and readability
Build & Test (NowChessSystems) TeamCity build finished
2026-05-01 20:06:10 +02:00
Janis 2dd0501687 fix(middleware): update paths for bot generation and stockfish configuration
Build & Test (NowChessSystems) TeamCity build failed
refactor(bru): standardize authentication settings across requests
chore: add coordinator base URL to configuration files
2026-05-01 19:56:34 +02:00
Janis e17e4e806a feat(api): add comprehensive API collection for NowChess microservices 2026-05-01 19:55:07 +02:00
TeamCity 9f86cc421f ci: bump version with Build-57 2026-04-30 17:14:21 +00:00
109 changed files with 2334 additions and 825 deletions
+201 -188
View File
@@ -2,7 +2,7 @@
> **Stack:** raw-http | none | unknown | scala
> 0 routes + 40 rpc | 0 models | 0 components | 146 lib files | 1 env vars | 1 middleware
> 0 routes + 40 rpc | 0 models | 0 components | 163 lib files | 1 env vars | 1 middleware
> **Token savings:** this file is ~0 tokens. Without it, AI exploration would cost ~0 tokens. **Saves ~0 tokens per conversation.**
---
@@ -75,6 +75,7 @@
- `modules/account/src/main/scala/de/nowchess/account/client/CoreGameClient.scala` — class CoreGameClient, function createGame
- `modules/account/src/main/scala/de/nowchess/account/config/JacksonConfig.scala` — class JacksonConfig, function customize
- `modules/account/src/main/scala/de/nowchess/account/config/NativeReflectionConfig.scala` — class NativeReflectionConfig
- `modules/account/src/main/scala/de/nowchess/account/config/RedisConfig.scala` — class RedisConfig
- `modules/account/src/main/scala/de/nowchess/account/domain/Challenge.scala`
- class Challenge
- function gameIdOpt
@@ -100,7 +101,7 @@
- function persist
- function findByEmail
- function findAll
- _...12 more_
- _...11 more_
- `modules/account/src/main/scala/de/nowchess/account/repository/ChallengeRepository.scala`
- class ChallengeRepository
- function findActiveByChallengerId
@@ -116,14 +117,16 @@
- function me
- function publicProfile
- function banUser
- _...10 more_
- _...9 more_
- `modules/account/src/main/scala/de/nowchess/account/resource/ChallengeResource.scala`
- class ChallengeResource
- function create
- function list
- function get
- function accept
- function decline
- function cancel
- _...1 more_
- `modules/account/src/main/scala/de/nowchess/account/resource/OfficialChallengeResource.scala` — class OfficialChallengeResource, function challengeWithDifficulty
- `modules/account/src/main/scala/de/nowchess/account/service/AccountService.scala`
- class AccountService
- function register
@@ -131,15 +134,20 @@
- function findByUsername
- function findById
- function createBotAccount
- _...11 more_
- _...10 more_
- `modules/account/src/main/scala/de/nowchess/account/service/ChallengeService.scala`
- class ChallengeService
- function create
- function accept
- function decline
- function cancel
- function listForUser
- _...1 more_
- function findById
- _...2 more_
- `modules/account/src/main/scala/de/nowchess/account/service/EventPublisher.scala`
- class EventPublisher
- function publishGameStart
- function publishChallengeCreated
- function publishChallengeAccepted
- `modules/api/src/main/scala/de/nowchess/api/board/Board.scala`
- class Board
- function apply
@@ -162,10 +170,6 @@
- class Square
- function fromAlgebraic
- function offset
- `modules/api/src/main/scala/de/nowchess/api/bot/Bot.scala`
- class Bot
- function name
- function nextMove
- `modules/api/src/main/scala/de/nowchess/api/dto/ErrorEventDto.scala` — class ErrorEventDto, function apply
- `modules/api/src/main/scala/de/nowchess/api/dto/GameFullEventDto.scala` — class GameFullEventDto, function apply
- `modules/api/src/main/scala/de/nowchess/api/dto/GameStateEventDto.scala` — class GameStateEventDto, function apply
@@ -186,6 +190,14 @@
- function withEnPassantSquare
- function withHalfMoveClock
- _...4 more_
- `modules/api/src/main/scala/de/nowchess/api/grpc/ProtoMapperBase.scala`
- class ProtoMapperBase
- function toProtoColor
- function fromProtoColor
- function toProtoPieceType
- function fromProtoPieceType
- function toProtoMoveKind
- _...17 more_
- `modules/api/src/main/scala/de/nowchess/api/io/GameContextExport.scala` — class GameContextExport, function exportGameContext
- `modules/api/src/main/scala/de/nowchess/api/io/GameContextImport.scala` — class GameContextImport, function importGameContext
- `modules/api/src/main/scala/de/nowchess/api/player/PlayerInfo.scala` — class PlayerId, function apply
@@ -201,115 +213,21 @@
- function isCheck
- function isCheckmate
- _...6 more_
- `modules/bot/python/nnue.py`
- function get_weights_dir: ()
- function get_data_dir: ()
- function list_checkpoints: ()
- function migrate_legacy_data: ()
- function show_header: ()
- function show_checkpoints_table: ()
- _...10 more_
- `modules/bot/python/src/dataset.py`
- function get_datasets_dir: () -> Path
- function next_dataset_version: () -> int
- function list_datasets: () -> List[Tuple[int, Dict]]
- function load_dataset_metadata: (version) -> Optional[Dict]
- function save_dataset_metadata: (version, metadata) -> None
- function create_dataset: (version, labeled_jsonl_path, sources, stockfish_depth) -> Path
- _...4 more_
- `modules/bot/python/src/export.py` — function export_to_nbai: (weights_file, output_file, trained_by, train_loss)
- `modules/bot/python/src/generate.py` — function play_random_game_and_collect_positions: (output_file, total_positions, samples_per_game, min_move, max_move, num_workers)
- `modules/bot/python/src/label.py` — function normalize_evaluation: (cp_value, method, scale), function label_positions_with_stockfish: (positions_file, output_file, stockfish_path, batch_size, depth, verbose, normalize, num_workers)
- `modules/bot/python/src/lichess_importer.py` — function import_lichess_evals: (input_path, output_file, max_positions, min_depth, verbose) -> int
- `modules/bot/python/src/tactical_positions_extractor.py`
- function download_and_extract_puzzle_db: (url, output_dir)
- function extract_puzzle_positions: (puzzle_csv, max_puzzles) -> Set[str]
- function load_positions_from_file: (file_path) -> Set[str]
- function merge_positions: (tactical, other, output_file)
- function extract_tactical_only: (puzzle_csv, output_file, max_puzzles) -> int
- function interactive_merge_positions: (puzzle_csv, output_file, max_puzzles)
- `modules/bot/python/src/train.py`
- function fen_to_features: (fen)
- function find_next_version: (base_name)
- function save_metadata: (weights_file, metadata)
- function train_nnue: (data_file, output_file, epochs, batch_size, lr, checkpoint, stockfish_depth, use_versioning, early_stopping_patience, weight_decay, subsample_ratio, hidden_sizes)
- function burst_train: (data_file, output_file, duration_minutes, epochs_per_season, early_stopping_patience, batch_size, lr, initial_checkpoint, stockfish_depth, use_versioning, weight_decay, subsample_ratio, hidden_sizes)
- class NNUEDataset
- _...1 more_
- `modules/bot/src/main/scala/de/nowchess/bot/BotController.scala`
- class BotController
- function getBot
- function listBots
- `modules/bot/src/main/scala/de/nowchess/bot/BotMoveRepetition.scala`
- class BotMoveRepetition
- function blockedMoves
- function repeatedMove
- function filterAllowed
- `modules/bot/src/main/scala/de/nowchess/bot/Config.scala` — class Config
- `modules/bot/src/main/scala/de/nowchess/bot/ai/Evaluation.scala`
- class Evaluation
- class CHECKMATE_SCORE
- class DRAW_SCORE
- function evaluate
- function initAccumulator
- function copyAccumulator
- _...2 more_
- `modules/bot/src/main/scala/de/nowchess/bot/bots/classic/EvaluationClassic.scala`
- class EvaluationClassic
- function evaluate
- function countRay
- `modules/bot/src/main/scala/de/nowchess/bot/bots/nnue/EvaluationNNUE.scala` — class EvaluationNNUE, function evaluate
- `modules/bot/src/main/scala/de/nowchess/bot/bots/nnue/NNUE.scala`
- class NNUE
- function initAccumulator
- function pushAccumulator
- function copyAccumulator
- function recomputeAccumulator
- function validateAccumulator
- _...4 more_
- `modules/bot/src/main/scala/de/nowchess/bot/bots/nnue/NbaiLoader.scala`
- class NbaiLoader
- function load
- function loadDefault
- `modules/bot/src/main/scala/de/nowchess/bot/bots/nnue/NbaiMigrator.scala` — class NbaiMigrator, function migrateFromBin
- `modules/bot/src/main/scala/de/nowchess/bot/bots/nnue/NbaiModel.scala`
- function toJson
- class NbaiMetadata
- function fromJson
- function str
- function num
- `modules/bot/src/main/scala/de/nowchess/bot/bots/nnue/NbaiWriter.scala` — class NbaiWriter, function write
- `modules/bot/src/main/scala/de/nowchess/bot/logic/AlphaBetaSearch.scala`
- function bestMove
- function bestMove
- function bestMoveWithTime
- function bestMoveWithTime
- function loop
- function loop
- `modules/bot/src/main/scala/de/nowchess/bot/logic/MoveOrdering.scala`
- class MoveOrdering
- class OrderingContext
- function addKillerMove
- function getKillerMoves
- function addHistory
- function getHistory
- _...3 more_
- `modules/bot/src/main/scala/de/nowchess/bot/logic/TranspositionTable.scala`
- function advance
- function probe
- function store
- function clear
- `modules/bot/src/main/scala/de/nowchess/bot/util/PolyglotBook.scala` — function probe, function select
- `modules/bot/src/main/scala/de/nowchess/bot/util/PolyglotHash.scala` — class PolyglotHash, function hash
- `modules/bot/src/main/scala/de/nowchess/bot/util/ZobristHash.scala`
- class ZobristHash
- function hash
- function nextHash
- `modules/bot-platform/src/main/scala/de/nowchess/botplatform/config/JacksonConfig.scala` — class JacksonConfig, function customize
- `modules/bot-platform/src/main/scala/de/nowchess/botplatform/config/RedisConfig.scala` — class RedisConfig
- `modules/bot-platform/src/main/scala/de/nowchess/botplatform/registry/BotRegistry.scala`
- class BotRegistry
- function register
- function unregister
- function dispatch
- function registeredBots
- `modules/bot-platform/src/main/scala/de/nowchess/botplatform/resource/BotEventResource.scala`
- class BotEventResource
- function streamEvents
- function streamGame
- function makeMove
- `modules/coordinator/src/main/scala/de/nowchess/coordinator/CoordinatorApp.scala` — class CoordinatorApp
- `modules/coordinator/src/main/scala/de/nowchess/coordinator/config/BeansProducer.scala`
- class BeansProducer
- function redissonClient
- function kubernetesClient
- `modules/coordinator/src/main/scala/de/nowchess/coordinator/config/BeansProducer.scala` — class BeansProducer, function kubernetesClient
- `modules/coordinator/src/main/scala/de/nowchess/coordinator/config/CoordinatorConfig.scala`
- class CoordinatorConfig
- function maxGamesPerCore
@@ -393,10 +311,6 @@
- `modules/core/src/main/scala/de/nowchess/chess/config/JacksonConfig.scala` — class JacksonConfig, function customize
- `modules/core/src/main/scala/de/nowchess/chess/config/NativeReflectionConfig.scala` — class NativeReflectionConfig
- `modules/core/src/main/scala/de/nowchess/chess/config/RedisConfig.scala` — class RedisConfig
- `modules/core/src/main/scala/de/nowchess/chess/config/RedissonProducer.scala`
- class RedissonProducer
- function produceRedissonClient
- function shutdown
- `modules/core/src/main/scala/de/nowchess/chess/controller/Parser.scala` — class Parser, function parseMove
- `modules/core/src/main/scala/de/nowchess/chess/engine/GameEngine.scala`
- class GameEngine
@@ -405,21 +319,14 @@
- function context
- function pendingDrawOfferBy
- function currentClockState
- _...22 more_
- _...21 more_
- `modules/core/src/main/scala/de/nowchess/chess/exception/ApiException.scala`
- class ApiException
- class GameNotFoundException
- class BadRequestException
- `modules/core/src/main/scala/de/nowchess/chess/exception/ApiExceptionMapper.scala` — class ApiExceptionMapper, function toResponse
- `modules/core/src/main/scala/de/nowchess/chess/grpc/CoordinatorServiceHandler.scala` — class CoordinatorServiceHandler
- `modules/core/src/main/scala/de/nowchess/chess/grpc/CoreProtoMapper.scala`
- class CoreProtoMapper
- function toProtoColor
- function fromProtoColor
- function toProtoPieceType
- function fromProtoPieceType
- function toProtoMoveKind
- _...9 more_
- `modules/core/src/main/scala/de/nowchess/chess/grpc/CoreProtoMapper.scala` — class CoreProtoMapper
- `modules/core/src/main/scala/de/nowchess/chess/grpc/IoGrpcClientWrapper.scala`
- class IoGrpcClientWrapper
- function exportCombined
@@ -444,15 +351,18 @@
- function unsubscribe
- _...1 more_
- `modules/core/src/main/scala/de/nowchess/chess/redis/C2sMessage.scala` — class C2sMessage
- `modules/core/src/main/scala/de/nowchess/chess/redis/GameRedisPublisher.scala` — class GameRedisPublisher, function onGameEvent
- `modules/core/src/main/scala/de/nowchess/chess/redis/GameRedisPublisher.scala`
- class GameRedisPublisher
- class GameRedisPublisher
- function onGameEvent
- `modules/core/src/main/scala/de/nowchess/chess/redis/GameRedisSubscriberManager.scala`
- class GameRedisSubscriberManager
- function subscribeGame
- function onMessage
- function unsubscribeGame
- function batchResubscribeGames
- function unsubscribeGames
- _...3 more_
- function evictGames
- _...2 more_
- `modules/core/src/main/scala/de/nowchess/chess/registry/GameRegistry.scala`
- class GameRegistry
- function store
@@ -518,14 +428,7 @@
- function importGameContext
- `modules/io/src/main/scala/de/nowchess/io/fen/FenParserSupport.scala` — function buildSquares
- `modules/io/src/main/scala/de/nowchess/io/grpc/IoGrpcService.scala` — class IoGrpcService
- `modules/io/src/main/scala/de/nowchess/io/grpc/IoProtoMapper.scala`
- class IoProtoMapper
- function toProtoColor
- function fromProtoColor
- function toProtoPieceType
- function fromProtoPieceType
- function toProtoMoveKind
- _...9 more_
- `modules/io/src/main/scala/de/nowchess/io/grpc/IoProtoMapper.scala` — class IoProtoMapper
- `modules/io/src/main/scala/de/nowchess/io/json/JsonExporter.scala` — class JsonExporter, function exportGameContext
- `modules/io/src/main/scala/de/nowchess/io/json/JsonParser.scala` — class JsonParser, function importGameContext
- `modules/io/src/main/scala/de/nowchess/io/pgn/PgnExporter.scala`
@@ -556,16 +459,124 @@
- `modules/json/src/main/scala/de/nowchess/json/SquareKeyDeserializer.scala` — class SquareKeyDeserializer
- `modules/json/src/main/scala/de/nowchess/json/SquareKeySerializer.scala` — class SquareKeySerializer
- `modules/json/src/main/scala/de/nowchess/json/SquareSerializer.scala` — class SquareSerializer
- `modules/official-bots/python/nnue.py`
- function get_weights_dir: ()
- function get_data_dir: ()
- function list_checkpoints: ()
- function migrate_legacy_data: ()
- function show_header: ()
- function show_checkpoints_table: ()
- _...10 more_
- `modules/official-bots/python/src/dataset.py`
- function get_datasets_dir: () -> Path
- function next_dataset_version: () -> int
- function list_datasets: () -> List[Tuple[int, Dict]]
- function load_dataset_metadata: (version) -> Optional[Dict]
- function save_dataset_metadata: (version, metadata) -> None
- function create_dataset: (version, labeled_jsonl_path, sources, stockfish_depth) -> Path
- _...4 more_
- `modules/official-bots/python/src/export.py` — function export_to_nbai: (weights_file, output_file, trained_by, train_loss)
- `modules/official-bots/python/src/generate.py` — function play_random_game_and_collect_positions: (output_file, total_positions, samples_per_game, min_move, max_move, num_workers)
- `modules/official-bots/python/src/label.py` — function normalize_evaluation: (cp_value, method, scale), function label_positions_with_stockfish: (positions_file, output_file, stockfish_path, batch_size, depth, verbose, normalize, num_workers)
- `modules/official-bots/python/src/lichess_importer.py` — function import_lichess_evals: (input_path, output_file, max_positions, min_depth, verbose) -> int
- `modules/official-bots/python/src/tactical_positions_extractor.py`
- function download_and_extract_puzzle_db: (url, output_dir)
- function extract_puzzle_positions: (puzzle_csv, max_puzzles) -> Set[str]
- function load_positions_from_file: (file_path) -> Set[str]
- function merge_positions: (tactical, other, output_file)
- function extract_tactical_only: (puzzle_csv, output_file, max_puzzles) -> int
- function interactive_merge_positions: (puzzle_csv, output_file, max_puzzles)
- `modules/official-bots/python/src/train.py`
- function fen_to_features: (fen)
- function find_next_version: (base_name)
- function save_metadata: (weights_file, metadata)
- function train_nnue: (data_file, output_file, epochs, batch_size, lr, checkpoint, stockfish_depth, use_versioning, early_stopping_patience, weight_decay, subsample_ratio, hidden_sizes)
- function burst_train: (data_file, output_file, duration_minutes, epochs_per_season, early_stopping_patience, batch_size, lr, initial_checkpoint, stockfish_depth, use_versioning, weight_decay, subsample_ratio, hidden_sizes)
- class NNUEDataset
- _...1 more_
- `modules/official-bots/src/main/scala/de/nowchess/bot/BotController.scala`
- class BotController
- function getBot
- function listBots
- class BotController
- function getBot
- function listBots
- `modules/official-bots/src/main/scala/de/nowchess/bot/BotMoveRepetition.scala`
- class BotMoveRepetition
- function blockedMoves
- function repeatedMove
- function filterAllowed
- `modules/official-bots/src/main/scala/de/nowchess/bot/Config.scala` — class Config
- `modules/official-bots/src/main/scala/de/nowchess/bot/ai/Evaluation.scala`
- class Evaluation
- class CHECKMATE_SCORE
- class DRAW_SCORE
- function evaluate
- function initAccumulator
- function copyAccumulator
- _...2 more_
- `modules/official-bots/src/main/scala/de/nowchess/bot/bots/ClassicalBot.scala` — class ClassicalBot, function apply
- `modules/official-bots/src/main/scala/de/nowchess/bot/bots/HybridBot.scala` — class HybridBot, function apply
- `modules/official-bots/src/main/scala/de/nowchess/bot/bots/NNUEBot.scala` — class NNUEBot, function apply
- `modules/official-bots/src/main/scala/de/nowchess/bot/bots/classic/EvaluationClassic.scala`
- class EvaluationClassic
- function evaluate
- function countRay
- `modules/official-bots/src/main/scala/de/nowchess/bot/bots/nnue/EvaluationNNUE.scala` — class EvaluationNNUE, function evaluate
- `modules/official-bots/src/main/scala/de/nowchess/bot/bots/nnue/NNUE.scala`
- class NNUE
- function initAccumulator
- function pushAccumulator
- function copyAccumulator
- function recomputeAccumulator
- function validateAccumulator
- _...4 more_
- `modules/official-bots/src/main/scala/de/nowchess/bot/bots/nnue/NbaiLoader.scala`
- class NbaiLoader
- function load
- function loadDefault
- `modules/official-bots/src/main/scala/de/nowchess/bot/bots/nnue/NbaiMigrator.scala` — class NbaiMigrator, function migrateFromBin
- `modules/official-bots/src/main/scala/de/nowchess/bot/bots/nnue/NbaiModel.scala`
- function toJson
- class NbaiMetadata
- function fromJson
- function str
- function num
- `modules/official-bots/src/main/scala/de/nowchess/bot/bots/nnue/NbaiWriter.scala` — class NbaiWriter, function write
- `modules/official-bots/src/main/scala/de/nowchess/bot/config/JacksonConfig.scala` — class JacksonConfig, function customize
- `modules/official-bots/src/main/scala/de/nowchess/bot/config/RedisConfig.scala` — class RedisConfig
- `modules/official-bots/src/main/scala/de/nowchess/bot/logic/AlphaBetaSearch.scala`
- function bestMove
- function bestMove
- function bestMoveWithTime
- function bestMoveWithTime
- function loop
- function loop
- `modules/official-bots/src/main/scala/de/nowchess/bot/logic/MoveOrdering.scala`
- class MoveOrdering
- class OrderingContext
- function addKillerMove
- function getKillerMoves
- function addHistory
- function getHistory
- _...3 more_
- `modules/official-bots/src/main/scala/de/nowchess/bot/logic/TranspositionTable.scala`
- function advance
- function probe
- function store
- function clear
- `modules/official-bots/src/main/scala/de/nowchess/bot/resource/OfficialBotChallengeResource.scala` — class OfficialBotChallengeResource, function challengeWithDifficulty
- `modules/official-bots/src/main/scala/de/nowchess/bot/service/DifficultyMapper.scala` — class DifficultyMapper, function fromElo
- `modules/official-bots/src/main/scala/de/nowchess/bot/service/OfficialBotService.scala` — class OfficialBotService, function onStart
- `modules/official-bots/src/main/scala/de/nowchess/bot/util/PolyglotBook.scala` — function probe, function select
- `modules/official-bots/src/main/scala/de/nowchess/bot/util/PolyglotHash.scala` — class PolyglotHash, function hash
- `modules/official-bots/src/main/scala/de/nowchess/bot/util/ZobristHash.scala`
- class ZobristHash
- function hash
- function nextHash
- `modules/rule/src/main/scala/de/nowchess/rules/config/JacksonConfig.scala` — class JacksonConfig, function customize
- `modules/rule/src/main/scala/de/nowchess/rules/config/NativeReflectionConfig.scala` — class NativeReflectionConfig
- `modules/rule/src/main/scala/de/nowchess/rules/grpc/ProtoMapper.scala`
- class ProtoMapper
- function toProtoColor
- function fromProtoColor
- function toProtoPieceType
- function fromProtoPieceType
- function toProtoMoveKind
- _...9 more_
- `modules/rule/src/main/scala/de/nowchess/rules/grpc/ProtoMapper.scala` — class ProtoMapper
- `modules/rule/src/main/scala/de/nowchess/rules/grpc/RuleGrpcService.scala` — class RuleGrpcService
- `modules/rule/src/main/scala/de/nowchess/rules/resource/RuleSetResource.scala`
- class RuleSetResource
@@ -576,38 +587,40 @@
- function isCheckmate
- _...6 more_
- `modules/rule/src/main/scala/de/nowchess/rules/sets/DefaultRules.scala` — class DefaultRules, function positionOf
- `modules/security/src/main/scala/de/nowchess/security/InternalAuthFilter.scala` — class InternalAuthFilter
- `modules/security/src/main/scala/de/nowchess/security/InternalGrpcAuthInterceptor.scala` — class InternalGrpcAuthInterceptor
- `modules/security/src/main/scala/de/nowchess/security/InternalGrpcSecretClientInterceptor.scala` — class InternalGrpcSecretClientInterceptor
- `modules/security/src/main/scala/de/nowchess/security/InternalSecretClientFilter.scala` — class InternalSecretClientFilter
- `modules/store/src/main/scala/de/nowchess/store/config/JacksonConfig.scala` — class JacksonConfig, function customize
- `modules/store/src/main/scala/de/nowchess/store/config/NativeReflectionConfig.scala` — class NativeReflectionConfig
- `modules/store/src/main/scala/de/nowchess/store/config/RedisConfig.scala` — class RedisConfig
- `modules/store/src/main/scala/de/nowchess/store/config/RedissonProducer.scala`
- class RedissonProducer
- function redissonClient
- function close
- `modules/store/src/main/scala/de/nowchess/store/domain/GameRecord.scala` — class GameRecord
- `modules/store/src/main/scala/de/nowchess/store/redis/GameWritebackStreamListener.scala`
- class GameWritebackStreamListener
- function startListening
- function onMessage
- `modules/store/src/main/scala/de/nowchess/store/redis/GameWritebackStreamListener.scala` — class GameWritebackStreamListener, function startListening
- `modules/store/src/main/scala/de/nowchess/store/repository/GameRecordRepository.scala`
- class GameRecordRepository
- function findByGameId
- function persist
- function merge
- `modules/store/src/main/scala/de/nowchess/store/resource/StoreGameResource.scala` — class StoreGameResource, function getGame
- function findByPlayerId
- function findByPlayerIdRunning
- `modules/store/src/main/scala/de/nowchess/store/resource/StoreGameResource.scala`
- class StoreGameResource
- function getGame
- function getRunning
- function getHistory
- `modules/store/src/main/scala/de/nowchess/store/service/GameWritebackService.scala` — class GameWritebackService, function writeBack
- `modules/ws/src/main/scala/de/nowchess/ws/config/JacksonConfig.scala` — class JacksonConfig, function customize
- `modules/ws/src/main/scala/de/nowchess/ws/config/NativeReflectionConfig.scala` — class NativeReflectionConfig
- `modules/ws/src/main/scala/de/nowchess/ws/config/RedisConfig.scala` — class RedisConfig
- `modules/ws/src/main/scala/de/nowchess/ws/config/RedissonProducer.scala`
- class RedissonProducer
- function produceRedissonClient
- function shutdown
- `modules/ws/src/main/scala/de/nowchess/ws/resource/GameWebSocketResource.scala`
- class GameWebSocketResource
- function onOpen
- function onMessage
- function onTextMessage
- function onClose
- `modules/ws/src/main/scala/de/nowchess/ws/resource/UserWebSocketResource.scala`
- class UserWebSocketResource
- function onOpen
- function onClose
---
@@ -615,14 +628,14 @@
## Environment Variables
- `STOCKFISH_PATH` **required** — modules/bot/python/nnue.py
- `STOCKFISH_PATH` **required** — modules/official-bots/python/nnue.py
---
# Middleware
## custom
- generate — `modules/bot/python/src/generate.py`
- generate — `modules/official-bots/python/src/generate.py`
---
@@ -631,38 +644,38 @@
## Most Imported Files (change these carefully)
- `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala` — imported by **76** files
- `modules/api/src/main/scala/de/nowchess/api/board/Square.scala` — imported by **57** files
- `modules/api/src/main/scala/de/nowchess/api/move/Move.scala` — imported by **55** files
- `modules/api/src/main/scala/de/nowchess/api/board/Square.scala` — imported by **56** files
- `modules/api/src/main/scala/de/nowchess/api/move/Move.scala` — imported by **54** files
- `modules/api/src/main/scala/de/nowchess/api/board/Color.scala` — imported by **47** files
- `modules/rule/src/main/scala/de/nowchess/rules/sets/DefaultRules.scala` — imported by **28** files
- `modules/api/src/main/scala/de/nowchess/api/board/Board.scala` — imported by **20** files
- `modules/rule/src/main/scala/de/nowchess/rules/sets/DefaultRules.scala` — imported by **27** files
- `modules/api/src/main/scala/de/nowchess/api/board/PieceType.scala` — imported by **20** files
- `modules/api/src/main/scala/de/nowchess/api/board/Piece.scala` — imported by **20** files
- `modules/api/src/main/scala/de/nowchess/api/game/DrawReason.scala` — imported by **18** files
- `modules/api/src/main/scala/de/nowchess/api/game/GameResult.scala` — imported by **18** files
- `modules/api/src/main/scala/de/nowchess/api/game/DrawReason.scala` — imported by **20** files
- `modules/api/src/main/scala/de/nowchess/api/game/GameResult.scala` — imported by **20** files
- `modules/api/src/main/scala/de/nowchess/api/board/Board.scala` — imported by **19** files
- `modules/api/src/main/scala/de/nowchess/api/board/Piece.scala` — imported by **19** files
- `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala` — imported by **14** files
- `modules/api/src/main/scala/de/nowchess/api/board/CastlingRights.scala` — imported by **13** files
- `modules/io/src/main/scala/de/nowchess/io/fen/FenParser.scala` — imported by **11** files
- `modules/api/src/main/scala/de/nowchess/api/player/PlayerInfo.scala` — imported by **9** files
- `modules/api/src/main/scala/de/nowchess/api/board/CastlingRights.scala` — imported by **12** files
- `modules/io/src/main/scala/de/nowchess/io/fen/FenParser.scala` — imported by **12** files
- `modules/api/src/main/scala/de/nowchess/api/error/GameError.scala` — imported by **9** files
- `modules/core/src/main/scala/de/nowchess/chess/observer/Observer.scala` — imported by **9** files
- `modules/account/src/main/scala/de/nowchess/account/config/RedisConfig.scala` — imported by **8** files
- `modules/api/src/main/scala/de/nowchess/api/io/GameContextImport.scala` — imported by **8** files
- `modules/core/src/main/scala/de/nowchess/chess/grpc/IoGrpcClientWrapper.scala` — imported by **7** files
- `modules/core/src/main/scala/de/nowchess/chess/grpc/IoGrpcClientWrapper.scala` — imported by **8** files
- `modules/api/src/main/scala/de/nowchess/api/player/PlayerInfo.scala` — imported by **6** files
- `modules/api/src/main/scala/de/nowchess/api/game/GameMode.scala` — imported by **6** files
- `modules/api/src/main/scala/de/nowchess/api/bot/Bot.scala` — imported by **6** files
## Import Map (who imports what)
- `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala``modules/api/src/main/scala/de/nowchess/api/bot/Bot.scala`, `modules/api/src/main/scala/de/nowchess/api/io/GameContextExport.scala`, `modules/api/src/main/scala/de/nowchess/api/io/GameContextImport.scala`, `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala`, `modules/bot/src/main/scala/de/nowchess/bot/BotMoveRepetition.scala` +71 more
- `modules/api/src/main/scala/de/nowchess/api/board/Square.scala``modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/api/src/main/scala/de/nowchess/api/move/Move.scala`, `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/api/src/test/scala/de/nowchess/api/move/MoveTest.scala` +52 more
- `modules/api/src/main/scala/de/nowchess/api/move/Move.scala``modules/api/src/main/scala/de/nowchess/api/bot/Bot.scala`, `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala`, `modules/api/src/test/scala/de/nowchess/api/board/BoardTest.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala` +50 more
- `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala``modules/api/src/main/scala/de/nowchess/api/grpc/ProtoMapperBase.scala`, `modules/api/src/main/scala/de/nowchess/api/io/GameContextExport.scala`, `modules/api/src/main/scala/de/nowchess/api/io/GameContextImport.scala`, `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala`, `modules/core/src/main/scala/de/nowchess/chess/adapter/RuleSetRestAdapter.scala` +71 more
- `modules/api/src/main/scala/de/nowchess/api/board/Square.scala``modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/api/src/main/scala/de/nowchess/api/move/Move.scala`, `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/api/src/test/scala/de/nowchess/api/move/MoveTest.scala` +51 more
- `modules/api/src/main/scala/de/nowchess/api/move/Move.scala``modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala`, `modules/api/src/test/scala/de/nowchess/api/board/BoardTest.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/core/src/main/scala/de/nowchess/chess/adapter/RuleSetRestAdapter.scala` +49 more
- `modules/api/src/main/scala/de/nowchess/api/board/Color.scala``modules/api/src/main/scala/de/nowchess/api/game/ClockState.scala`, `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/api/src/main/scala/de/nowchess/api/game/GameResult.scala`, `modules/api/src/test/scala/de/nowchess/api/game/ClockStateTest.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala` +42 more
- `modules/rule/src/main/scala/de/nowchess/rules/sets/DefaultRules.scala``modules/bot/src/main/scala/de/nowchess/bot/bots/ClassicalBot.scala`, `modules/bot/src/main/scala/de/nowchess/bot/bots/HybridBot.scala`, `modules/bot/src/main/scala/de/nowchess/bot/bots/NNUEBot.scala`, `modules/bot/src/main/scala/de/nowchess/bot/logic/AlphaBetaSearch.scala`, `modules/bot/src/test/scala/de/nowchess/bot/AlphaBetaSearchTest.scala` +23 more
- `modules/api/src/main/scala/de/nowchess/api/board/Board.scala``modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/bot/src/main/scala/de/nowchess/bot/bots/nnue/NNUE.scala`, `modules/bot/src/main/scala/de/nowchess/bot/logic/MoveOrdering.scala`, `modules/bot/src/test/scala/de/nowchess/bot/AlphaBetaSearchTest.scala` +15 more
- `modules/api/src/main/scala/de/nowchess/api/board/PieceType.scala``modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/bot/src/main/scala/de/nowchess/bot/bots/classic/EvaluationClassic.scala`, `modules/bot/src/main/scala/de/nowchess/bot/bots/nnue/NNUE.scala`, `modules/bot/src/main/scala/de/nowchess/bot/logic/AlphaBetaSearch.scala`, `modules/bot/src/main/scala/de/nowchess/bot/logic/MoveOrdering.scala` +15 more
- `modules/api/src/main/scala/de/nowchess/api/board/Piece.scala``modules/bot/src/main/scala/de/nowchess/bot/bots/nnue/NNUE.scala`, `modules/bot/src/main/scala/de/nowchess/bot/logic/MoveOrdering.scala`, `modules/bot/src/main/scala/de/nowchess/bot/util/PolyglotHash.scala`, `modules/bot/src/main/scala/de/nowchess/bot/util/ZobristHash.scala`, `modules/bot/src/test/scala/de/nowchess/bot/AlphaBetaSearchTest.scala` +15 more
- `modules/api/src/main/scala/de/nowchess/api/game/DrawReason.scala``modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/core/src/main/scala/de/nowchess/chess/config/NativeReflectionConfig.scala`, `modules/core/src/main/scala/de/nowchess/chess/engine/GameEngine.scala`, `modules/core/src/main/scala/de/nowchess/chess/grpc/CoreProtoMapper.scala`, `modules/core/src/main/scala/de/nowchess/chess/observer/Observer.scala` +13 more
- `modules/api/src/main/scala/de/nowchess/api/game/GameResult.scala``modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/core/src/main/scala/de/nowchess/chess/config/NativeReflectionConfig.scala`, `modules/core/src/main/scala/de/nowchess/chess/engine/GameEngine.scala`, `modules/core/src/main/scala/de/nowchess/chess/grpc/CoreProtoMapper.scala`, `modules/core/src/main/scala/de/nowchess/chess/resource/GameDtoMapper.scala` +13 more
- `modules/rule/src/main/scala/de/nowchess/rules/sets/DefaultRules.scala``modules/core/src/test/scala/de/nowchess/chess/engine/EngineTestHelpers.scala`, `modules/core/src/test/scala/de/nowchess/chess/engine/GameEngineClockTest.scala`, `modules/core/src/test/scala/de/nowchess/chess/engine/GameEngineDrawOfferTest.scala`, `modules/core/src/test/scala/de/nowchess/chess/engine/GameEngineGameEndingTest.scala`, `modules/core/src/test/scala/de/nowchess/chess/engine/GameEngineIntegrationTest.scala` +22 more
- `modules/api/src/main/scala/de/nowchess/api/board/PieceType.scala``modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/core/src/main/scala/de/nowchess/chess/config/NativeReflectionConfig.scala`, `modules/core/src/main/scala/de/nowchess/chess/engine/GameEngine.scala`, `modules/core/src/test/scala/de/nowchess/chess/engine/GameEngineIntegrationTest.scala`, `modules/core/src/test/scala/de/nowchess/chess/engine/GameEnginePromotionTest.scala` +15 more
- `modules/api/src/main/scala/de/nowchess/api/game/DrawReason.scala``modules/api/src/main/scala/de/nowchess/api/grpc/ProtoMapperBase.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/core/src/main/scala/de/nowchess/chess/config/NativeReflectionConfig.scala`, `modules/core/src/main/scala/de/nowchess/chess/engine/GameEngine.scala`, `modules/core/src/main/scala/de/nowchess/chess/grpc/CoreProtoMapper.scala` +15 more
- `modules/api/src/main/scala/de/nowchess/api/game/GameResult.scala``modules/api/src/main/scala/de/nowchess/api/grpc/ProtoMapperBase.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/core/src/main/scala/de/nowchess/chess/config/NativeReflectionConfig.scala`, `modules/core/src/main/scala/de/nowchess/chess/engine/GameEngine.scala`, `modules/core/src/main/scala/de/nowchess/chess/grpc/CoreProtoMapper.scala` +15 more
- `modules/api/src/main/scala/de/nowchess/api/board/Board.scala``modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/core/src/main/scala/de/nowchess/chess/engine/GameEngine.scala`, `modules/core/src/test/scala/de/nowchess/chess/engine/EngineTestHelpers.scala`, `modules/core/src/test/scala/de/nowchess/chess/engine/GameEngineIntegrationTest.scala` +14 more
- `modules/api/src/main/scala/de/nowchess/api/board/Piece.scala` `modules/core/src/main/scala/de/nowchess/chess/config/NativeReflectionConfig.scala`, `modules/core/src/main/scala/de/nowchess/chess/engine/GameEngine.scala`, `modules/core/src/test/scala/de/nowchess/chess/engine/GameEnginePromotionTest.scala`, `modules/core/src/test/scala/de/nowchess/chess/engine/GameEngineScenarioTest.scala`, `modules/io/src/main/scala/de/nowchess/io/service/config/NativeReflectionConfig.scala` +14 more
---
+1 -1
View File
@@ -2,4 +2,4 @@
## Environment Variables
- `STOCKFISH_PATH` **required** — modules/bot/python/nnue.py
- `STOCKFISH_PATH` **required** — modules/official-bots/python/nnue.py
+21 -21
View File
@@ -3,35 +3,35 @@
## Most Imported Files (change these carefully)
- `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala` — imported by **76** files
- `modules/api/src/main/scala/de/nowchess/api/board/Square.scala` — imported by **57** files
- `modules/api/src/main/scala/de/nowchess/api/move/Move.scala` — imported by **55** files
- `modules/api/src/main/scala/de/nowchess/api/board/Square.scala` — imported by **56** files
- `modules/api/src/main/scala/de/nowchess/api/move/Move.scala` — imported by **54** files
- `modules/api/src/main/scala/de/nowchess/api/board/Color.scala` — imported by **47** files
- `modules/rule/src/main/scala/de/nowchess/rules/sets/DefaultRules.scala` — imported by **28** files
- `modules/api/src/main/scala/de/nowchess/api/board/Board.scala` — imported by **20** files
- `modules/rule/src/main/scala/de/nowchess/rules/sets/DefaultRules.scala` — imported by **27** files
- `modules/api/src/main/scala/de/nowchess/api/board/PieceType.scala` — imported by **20** files
- `modules/api/src/main/scala/de/nowchess/api/board/Piece.scala` — imported by **20** files
- `modules/api/src/main/scala/de/nowchess/api/game/DrawReason.scala` — imported by **18** files
- `modules/api/src/main/scala/de/nowchess/api/game/GameResult.scala` — imported by **18** files
- `modules/api/src/main/scala/de/nowchess/api/game/DrawReason.scala` — imported by **20** files
- `modules/api/src/main/scala/de/nowchess/api/game/GameResult.scala` — imported by **20** files
- `modules/api/src/main/scala/de/nowchess/api/board/Board.scala` — imported by **19** files
- `modules/api/src/main/scala/de/nowchess/api/board/Piece.scala` — imported by **19** files
- `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala` — imported by **14** files
- `modules/api/src/main/scala/de/nowchess/api/board/CastlingRights.scala` — imported by **13** files
- `modules/io/src/main/scala/de/nowchess/io/fen/FenParser.scala` — imported by **11** files
- `modules/api/src/main/scala/de/nowchess/api/player/PlayerInfo.scala` — imported by **9** files
- `modules/api/src/main/scala/de/nowchess/api/board/CastlingRights.scala` — imported by **12** files
- `modules/io/src/main/scala/de/nowchess/io/fen/FenParser.scala` — imported by **12** files
- `modules/api/src/main/scala/de/nowchess/api/error/GameError.scala` — imported by **9** files
- `modules/core/src/main/scala/de/nowchess/chess/observer/Observer.scala` — imported by **9** files
- `modules/account/src/main/scala/de/nowchess/account/config/RedisConfig.scala` — imported by **8** files
- `modules/api/src/main/scala/de/nowchess/api/io/GameContextImport.scala` — imported by **8** files
- `modules/core/src/main/scala/de/nowchess/chess/grpc/IoGrpcClientWrapper.scala` — imported by **7** files
- `modules/core/src/main/scala/de/nowchess/chess/grpc/IoGrpcClientWrapper.scala` — imported by **8** files
- `modules/api/src/main/scala/de/nowchess/api/player/PlayerInfo.scala` — imported by **6** files
- `modules/api/src/main/scala/de/nowchess/api/game/GameMode.scala` — imported by **6** files
- `modules/api/src/main/scala/de/nowchess/api/bot/Bot.scala` — imported by **6** files
## Import Map (who imports what)
- `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala``modules/api/src/main/scala/de/nowchess/api/bot/Bot.scala`, `modules/api/src/main/scala/de/nowchess/api/io/GameContextExport.scala`, `modules/api/src/main/scala/de/nowchess/api/io/GameContextImport.scala`, `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala`, `modules/bot/src/main/scala/de/nowchess/bot/BotMoveRepetition.scala` +71 more
- `modules/api/src/main/scala/de/nowchess/api/board/Square.scala``modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/api/src/main/scala/de/nowchess/api/move/Move.scala`, `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/api/src/test/scala/de/nowchess/api/move/MoveTest.scala` +52 more
- `modules/api/src/main/scala/de/nowchess/api/move/Move.scala``modules/api/src/main/scala/de/nowchess/api/bot/Bot.scala`, `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala`, `modules/api/src/test/scala/de/nowchess/api/board/BoardTest.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala` +50 more
- `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala``modules/api/src/main/scala/de/nowchess/api/grpc/ProtoMapperBase.scala`, `modules/api/src/main/scala/de/nowchess/api/io/GameContextExport.scala`, `modules/api/src/main/scala/de/nowchess/api/io/GameContextImport.scala`, `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala`, `modules/core/src/main/scala/de/nowchess/chess/adapter/RuleSetRestAdapter.scala` +71 more
- `modules/api/src/main/scala/de/nowchess/api/board/Square.scala``modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/api/src/main/scala/de/nowchess/api/move/Move.scala`, `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/api/src/test/scala/de/nowchess/api/move/MoveTest.scala` +51 more
- `modules/api/src/main/scala/de/nowchess/api/move/Move.scala``modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala`, `modules/api/src/test/scala/de/nowchess/api/board/BoardTest.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/core/src/main/scala/de/nowchess/chess/adapter/RuleSetRestAdapter.scala` +49 more
- `modules/api/src/main/scala/de/nowchess/api/board/Color.scala``modules/api/src/main/scala/de/nowchess/api/game/ClockState.scala`, `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/api/src/main/scala/de/nowchess/api/game/GameResult.scala`, `modules/api/src/test/scala/de/nowchess/api/game/ClockStateTest.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala` +42 more
- `modules/rule/src/main/scala/de/nowchess/rules/sets/DefaultRules.scala``modules/bot/src/main/scala/de/nowchess/bot/bots/ClassicalBot.scala`, `modules/bot/src/main/scala/de/nowchess/bot/bots/HybridBot.scala`, `modules/bot/src/main/scala/de/nowchess/bot/bots/NNUEBot.scala`, `modules/bot/src/main/scala/de/nowchess/bot/logic/AlphaBetaSearch.scala`, `modules/bot/src/test/scala/de/nowchess/bot/AlphaBetaSearchTest.scala` +23 more
- `modules/api/src/main/scala/de/nowchess/api/board/Board.scala``modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/bot/src/main/scala/de/nowchess/bot/bots/nnue/NNUE.scala`, `modules/bot/src/main/scala/de/nowchess/bot/logic/MoveOrdering.scala`, `modules/bot/src/test/scala/de/nowchess/bot/AlphaBetaSearchTest.scala` +15 more
- `modules/api/src/main/scala/de/nowchess/api/board/PieceType.scala``modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/bot/src/main/scala/de/nowchess/bot/bots/classic/EvaluationClassic.scala`, `modules/bot/src/main/scala/de/nowchess/bot/bots/nnue/NNUE.scala`, `modules/bot/src/main/scala/de/nowchess/bot/logic/AlphaBetaSearch.scala`, `modules/bot/src/main/scala/de/nowchess/bot/logic/MoveOrdering.scala` +15 more
- `modules/api/src/main/scala/de/nowchess/api/board/Piece.scala``modules/bot/src/main/scala/de/nowchess/bot/bots/nnue/NNUE.scala`, `modules/bot/src/main/scala/de/nowchess/bot/logic/MoveOrdering.scala`, `modules/bot/src/main/scala/de/nowchess/bot/util/PolyglotHash.scala`, `modules/bot/src/main/scala/de/nowchess/bot/util/ZobristHash.scala`, `modules/bot/src/test/scala/de/nowchess/bot/AlphaBetaSearchTest.scala` +15 more
- `modules/api/src/main/scala/de/nowchess/api/game/DrawReason.scala``modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/core/src/main/scala/de/nowchess/chess/config/NativeReflectionConfig.scala`, `modules/core/src/main/scala/de/nowchess/chess/engine/GameEngine.scala`, `modules/core/src/main/scala/de/nowchess/chess/grpc/CoreProtoMapper.scala`, `modules/core/src/main/scala/de/nowchess/chess/observer/Observer.scala` +13 more
- `modules/api/src/main/scala/de/nowchess/api/game/GameResult.scala``modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/core/src/main/scala/de/nowchess/chess/config/NativeReflectionConfig.scala`, `modules/core/src/main/scala/de/nowchess/chess/engine/GameEngine.scala`, `modules/core/src/main/scala/de/nowchess/chess/grpc/CoreProtoMapper.scala`, `modules/core/src/main/scala/de/nowchess/chess/resource/GameDtoMapper.scala` +13 more
- `modules/rule/src/main/scala/de/nowchess/rules/sets/DefaultRules.scala``modules/core/src/test/scala/de/nowchess/chess/engine/EngineTestHelpers.scala`, `modules/core/src/test/scala/de/nowchess/chess/engine/GameEngineClockTest.scala`, `modules/core/src/test/scala/de/nowchess/chess/engine/GameEngineDrawOfferTest.scala`, `modules/core/src/test/scala/de/nowchess/chess/engine/GameEngineGameEndingTest.scala`, `modules/core/src/test/scala/de/nowchess/chess/engine/GameEngineIntegrationTest.scala` +22 more
- `modules/api/src/main/scala/de/nowchess/api/board/PieceType.scala``modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/core/src/main/scala/de/nowchess/chess/config/NativeReflectionConfig.scala`, `modules/core/src/main/scala/de/nowchess/chess/engine/GameEngine.scala`, `modules/core/src/test/scala/de/nowchess/chess/engine/GameEngineIntegrationTest.scala`, `modules/core/src/test/scala/de/nowchess/chess/engine/GameEnginePromotionTest.scala` +15 more
- `modules/api/src/main/scala/de/nowchess/api/game/DrawReason.scala``modules/api/src/main/scala/de/nowchess/api/grpc/ProtoMapperBase.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/core/src/main/scala/de/nowchess/chess/config/NativeReflectionConfig.scala`, `modules/core/src/main/scala/de/nowchess/chess/engine/GameEngine.scala`, `modules/core/src/main/scala/de/nowchess/chess/grpc/CoreProtoMapper.scala` +15 more
- `modules/api/src/main/scala/de/nowchess/api/game/GameResult.scala``modules/api/src/main/scala/de/nowchess/api/grpc/ProtoMapperBase.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/core/src/main/scala/de/nowchess/chess/config/NativeReflectionConfig.scala`, `modules/core/src/main/scala/de/nowchess/chess/engine/GameEngine.scala`, `modules/core/src/main/scala/de/nowchess/chess/grpc/CoreProtoMapper.scala` +15 more
- `modules/api/src/main/scala/de/nowchess/api/board/Board.scala``modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/core/src/main/scala/de/nowchess/chess/engine/GameEngine.scala`, `modules/core/src/test/scala/de/nowchess/chess/engine/EngineTestHelpers.scala`, `modules/core/src/test/scala/de/nowchess/chess/engine/GameEngineIntegrationTest.scala` +14 more
- `modules/api/src/main/scala/de/nowchess/api/board/Piece.scala` `modules/core/src/main/scala/de/nowchess/chess/config/NativeReflectionConfig.scala`, `modules/core/src/main/scala/de/nowchess/chess/engine/GameEngine.scala`, `modules/core/src/test/scala/de/nowchess/chess/engine/GameEnginePromotionTest.scala`, `modules/core/src/test/scala/de/nowchess/chess/engine/GameEngineScenarioTest.scala`, `modules/io/src/main/scala/de/nowchess/io/service/config/NativeReflectionConfig.scala` +14 more
+177 -164
View File
@@ -19,6 +19,7 @@
- `modules/account/src/main/scala/de/nowchess/account/client/CoreGameClient.scala` — class CoreGameClient, function createGame
- `modules/account/src/main/scala/de/nowchess/account/config/JacksonConfig.scala` — class JacksonConfig, function customize
- `modules/account/src/main/scala/de/nowchess/account/config/NativeReflectionConfig.scala` — class NativeReflectionConfig
- `modules/account/src/main/scala/de/nowchess/account/config/RedisConfig.scala` — class RedisConfig
- `modules/account/src/main/scala/de/nowchess/account/domain/Challenge.scala`
- class Challenge
- function gameIdOpt
@@ -44,7 +45,7 @@
- function persist
- function findByEmail
- function findAll
- _...12 more_
- _...11 more_
- `modules/account/src/main/scala/de/nowchess/account/repository/ChallengeRepository.scala`
- class ChallengeRepository
- function findActiveByChallengerId
@@ -60,14 +61,16 @@
- function me
- function publicProfile
- function banUser
- _...10 more_
- _...9 more_
- `modules/account/src/main/scala/de/nowchess/account/resource/ChallengeResource.scala`
- class ChallengeResource
- function create
- function list
- function get
- function accept
- function decline
- function cancel
- _...1 more_
- `modules/account/src/main/scala/de/nowchess/account/resource/OfficialChallengeResource.scala` — class OfficialChallengeResource, function challengeWithDifficulty
- `modules/account/src/main/scala/de/nowchess/account/service/AccountService.scala`
- class AccountService
- function register
@@ -75,15 +78,20 @@
- function findByUsername
- function findById
- function createBotAccount
- _...11 more_
- _...10 more_
- `modules/account/src/main/scala/de/nowchess/account/service/ChallengeService.scala`
- class ChallengeService
- function create
- function accept
- function decline
- function cancel
- function listForUser
- _...1 more_
- function findById
- _...2 more_
- `modules/account/src/main/scala/de/nowchess/account/service/EventPublisher.scala`
- class EventPublisher
- function publishGameStart
- function publishChallengeCreated
- function publishChallengeAccepted
- `modules/api/src/main/scala/de/nowchess/api/board/Board.scala`
- class Board
- function apply
@@ -106,10 +114,6 @@
- class Square
- function fromAlgebraic
- function offset
- `modules/api/src/main/scala/de/nowchess/api/bot/Bot.scala`
- class Bot
- function name
- function nextMove
- `modules/api/src/main/scala/de/nowchess/api/dto/ErrorEventDto.scala` — class ErrorEventDto, function apply
- `modules/api/src/main/scala/de/nowchess/api/dto/GameFullEventDto.scala` — class GameFullEventDto, function apply
- `modules/api/src/main/scala/de/nowchess/api/dto/GameStateEventDto.scala` — class GameStateEventDto, function apply
@@ -130,6 +134,14 @@
- function withEnPassantSquare
- function withHalfMoveClock
- _...4 more_
- `modules/api/src/main/scala/de/nowchess/api/grpc/ProtoMapperBase.scala`
- class ProtoMapperBase
- function toProtoColor
- function fromProtoColor
- function toProtoPieceType
- function fromProtoPieceType
- function toProtoMoveKind
- _...17 more_
- `modules/api/src/main/scala/de/nowchess/api/io/GameContextExport.scala` — class GameContextExport, function exportGameContext
- `modules/api/src/main/scala/de/nowchess/api/io/GameContextImport.scala` — class GameContextImport, function importGameContext
- `modules/api/src/main/scala/de/nowchess/api/player/PlayerInfo.scala` — class PlayerId, function apply
@@ -145,115 +157,21 @@
- function isCheck
- function isCheckmate
- _...6 more_
- `modules/bot/python/nnue.py`
- function get_weights_dir: ()
- function get_data_dir: ()
- function list_checkpoints: ()
- function migrate_legacy_data: ()
- function show_header: ()
- function show_checkpoints_table: ()
- _...10 more_
- `modules/bot/python/src/dataset.py`
- function get_datasets_dir: () -> Path
- function next_dataset_version: () -> int
- function list_datasets: () -> List[Tuple[int, Dict]]
- function load_dataset_metadata: (version) -> Optional[Dict]
- function save_dataset_metadata: (version, metadata) -> None
- function create_dataset: (version, labeled_jsonl_path, sources, stockfish_depth) -> Path
- _...4 more_
- `modules/bot/python/src/export.py` — function export_to_nbai: (weights_file, output_file, trained_by, train_loss)
- `modules/bot/python/src/generate.py` — function play_random_game_and_collect_positions: (output_file, total_positions, samples_per_game, min_move, max_move, num_workers)
- `modules/bot/python/src/label.py` — function normalize_evaluation: (cp_value, method, scale), function label_positions_with_stockfish: (positions_file, output_file, stockfish_path, batch_size, depth, verbose, normalize, num_workers)
- `modules/bot/python/src/lichess_importer.py` — function import_lichess_evals: (input_path, output_file, max_positions, min_depth, verbose) -> int
- `modules/bot/python/src/tactical_positions_extractor.py`
- function download_and_extract_puzzle_db: (url, output_dir)
- function extract_puzzle_positions: (puzzle_csv, max_puzzles) -> Set[str]
- function load_positions_from_file: (file_path) -> Set[str]
- function merge_positions: (tactical, other, output_file)
- function extract_tactical_only: (puzzle_csv, output_file, max_puzzles) -> int
- function interactive_merge_positions: (puzzle_csv, output_file, max_puzzles)
- `modules/bot/python/src/train.py`
- function fen_to_features: (fen)
- function find_next_version: (base_name)
- function save_metadata: (weights_file, metadata)
- function train_nnue: (data_file, output_file, epochs, batch_size, lr, checkpoint, stockfish_depth, use_versioning, early_stopping_patience, weight_decay, subsample_ratio, hidden_sizes)
- function burst_train: (data_file, output_file, duration_minutes, epochs_per_season, early_stopping_patience, batch_size, lr, initial_checkpoint, stockfish_depth, use_versioning, weight_decay, subsample_ratio, hidden_sizes)
- class NNUEDataset
- _...1 more_
- `modules/bot/src/main/scala/de/nowchess/bot/BotController.scala`
- class BotController
- function getBot
- function listBots
- `modules/bot/src/main/scala/de/nowchess/bot/BotMoveRepetition.scala`
- class BotMoveRepetition
- function blockedMoves
- function repeatedMove
- function filterAllowed
- `modules/bot/src/main/scala/de/nowchess/bot/Config.scala` — class Config
- `modules/bot/src/main/scala/de/nowchess/bot/ai/Evaluation.scala`
- class Evaluation
- class CHECKMATE_SCORE
- class DRAW_SCORE
- function evaluate
- function initAccumulator
- function copyAccumulator
- _...2 more_
- `modules/bot/src/main/scala/de/nowchess/bot/bots/classic/EvaluationClassic.scala`
- class EvaluationClassic
- function evaluate
- function countRay
- `modules/bot/src/main/scala/de/nowchess/bot/bots/nnue/EvaluationNNUE.scala` — class EvaluationNNUE, function evaluate
- `modules/bot/src/main/scala/de/nowchess/bot/bots/nnue/NNUE.scala`
- class NNUE
- function initAccumulator
- function pushAccumulator
- function copyAccumulator
- function recomputeAccumulator
- function validateAccumulator
- _...4 more_
- `modules/bot/src/main/scala/de/nowchess/bot/bots/nnue/NbaiLoader.scala`
- class NbaiLoader
- function load
- function loadDefault
- `modules/bot/src/main/scala/de/nowchess/bot/bots/nnue/NbaiMigrator.scala` — class NbaiMigrator, function migrateFromBin
- `modules/bot/src/main/scala/de/nowchess/bot/bots/nnue/NbaiModel.scala`
- function toJson
- class NbaiMetadata
- function fromJson
- function str
- function num
- `modules/bot/src/main/scala/de/nowchess/bot/bots/nnue/NbaiWriter.scala` — class NbaiWriter, function write
- `modules/bot/src/main/scala/de/nowchess/bot/logic/AlphaBetaSearch.scala`
- function bestMove
- function bestMove
- function bestMoveWithTime
- function bestMoveWithTime
- function loop
- function loop
- `modules/bot/src/main/scala/de/nowchess/bot/logic/MoveOrdering.scala`
- class MoveOrdering
- class OrderingContext
- function addKillerMove
- function getKillerMoves
- function addHistory
- function getHistory
- _...3 more_
- `modules/bot/src/main/scala/de/nowchess/bot/logic/TranspositionTable.scala`
- function advance
- function probe
- function store
- function clear
- `modules/bot/src/main/scala/de/nowchess/bot/util/PolyglotBook.scala` — function probe, function select
- `modules/bot/src/main/scala/de/nowchess/bot/util/PolyglotHash.scala` — class PolyglotHash, function hash
- `modules/bot/src/main/scala/de/nowchess/bot/util/ZobristHash.scala`
- class ZobristHash
- function hash
- function nextHash
- `modules/bot-platform/src/main/scala/de/nowchess/botplatform/config/JacksonConfig.scala` — class JacksonConfig, function customize
- `modules/bot-platform/src/main/scala/de/nowchess/botplatform/config/RedisConfig.scala` — class RedisConfig
- `modules/bot-platform/src/main/scala/de/nowchess/botplatform/registry/BotRegistry.scala`
- class BotRegistry
- function register
- function unregister
- function dispatch
- function registeredBots
- `modules/bot-platform/src/main/scala/de/nowchess/botplatform/resource/BotEventResource.scala`
- class BotEventResource
- function streamEvents
- function streamGame
- function makeMove
- `modules/coordinator/src/main/scala/de/nowchess/coordinator/CoordinatorApp.scala` — class CoordinatorApp
- `modules/coordinator/src/main/scala/de/nowchess/coordinator/config/BeansProducer.scala`
- class BeansProducer
- function redissonClient
- function kubernetesClient
- `modules/coordinator/src/main/scala/de/nowchess/coordinator/config/BeansProducer.scala` — class BeansProducer, function kubernetesClient
- `modules/coordinator/src/main/scala/de/nowchess/coordinator/config/CoordinatorConfig.scala`
- class CoordinatorConfig
- function maxGamesPerCore
@@ -337,10 +255,6 @@
- `modules/core/src/main/scala/de/nowchess/chess/config/JacksonConfig.scala` — class JacksonConfig, function customize
- `modules/core/src/main/scala/de/nowchess/chess/config/NativeReflectionConfig.scala` — class NativeReflectionConfig
- `modules/core/src/main/scala/de/nowchess/chess/config/RedisConfig.scala` — class RedisConfig
- `modules/core/src/main/scala/de/nowchess/chess/config/RedissonProducer.scala`
- class RedissonProducer
- function produceRedissonClient
- function shutdown
- `modules/core/src/main/scala/de/nowchess/chess/controller/Parser.scala` — class Parser, function parseMove
- `modules/core/src/main/scala/de/nowchess/chess/engine/GameEngine.scala`
- class GameEngine
@@ -349,21 +263,14 @@
- function context
- function pendingDrawOfferBy
- function currentClockState
- _...22 more_
- _...21 more_
- `modules/core/src/main/scala/de/nowchess/chess/exception/ApiException.scala`
- class ApiException
- class GameNotFoundException
- class BadRequestException
- `modules/core/src/main/scala/de/nowchess/chess/exception/ApiExceptionMapper.scala` — class ApiExceptionMapper, function toResponse
- `modules/core/src/main/scala/de/nowchess/chess/grpc/CoordinatorServiceHandler.scala` — class CoordinatorServiceHandler
- `modules/core/src/main/scala/de/nowchess/chess/grpc/CoreProtoMapper.scala`
- class CoreProtoMapper
- function toProtoColor
- function fromProtoColor
- function toProtoPieceType
- function fromProtoPieceType
- function toProtoMoveKind
- _...9 more_
- `modules/core/src/main/scala/de/nowchess/chess/grpc/CoreProtoMapper.scala` — class CoreProtoMapper
- `modules/core/src/main/scala/de/nowchess/chess/grpc/IoGrpcClientWrapper.scala`
- class IoGrpcClientWrapper
- function exportCombined
@@ -388,15 +295,18 @@
- function unsubscribe
- _...1 more_
- `modules/core/src/main/scala/de/nowchess/chess/redis/C2sMessage.scala` — class C2sMessage
- `modules/core/src/main/scala/de/nowchess/chess/redis/GameRedisPublisher.scala` — class GameRedisPublisher, function onGameEvent
- `modules/core/src/main/scala/de/nowchess/chess/redis/GameRedisPublisher.scala`
- class GameRedisPublisher
- class GameRedisPublisher
- function onGameEvent
- `modules/core/src/main/scala/de/nowchess/chess/redis/GameRedisSubscriberManager.scala`
- class GameRedisSubscriberManager
- function subscribeGame
- function onMessage
- function unsubscribeGame
- function batchResubscribeGames
- function unsubscribeGames
- _...3 more_
- function evictGames
- _...2 more_
- `modules/core/src/main/scala/de/nowchess/chess/registry/GameRegistry.scala`
- class GameRegistry
- function store
@@ -462,14 +372,7 @@
- function importGameContext
- `modules/io/src/main/scala/de/nowchess/io/fen/FenParserSupport.scala` — function buildSquares
- `modules/io/src/main/scala/de/nowchess/io/grpc/IoGrpcService.scala` — class IoGrpcService
- `modules/io/src/main/scala/de/nowchess/io/grpc/IoProtoMapper.scala`
- class IoProtoMapper
- function toProtoColor
- function fromProtoColor
- function toProtoPieceType
- function fromProtoPieceType
- function toProtoMoveKind
- _...9 more_
- `modules/io/src/main/scala/de/nowchess/io/grpc/IoProtoMapper.scala` — class IoProtoMapper
- `modules/io/src/main/scala/de/nowchess/io/json/JsonExporter.scala` — class JsonExporter, function exportGameContext
- `modules/io/src/main/scala/de/nowchess/io/json/JsonParser.scala` — class JsonParser, function importGameContext
- `modules/io/src/main/scala/de/nowchess/io/pgn/PgnExporter.scala`
@@ -500,16 +403,124 @@
- `modules/json/src/main/scala/de/nowchess/json/SquareKeyDeserializer.scala` — class SquareKeyDeserializer
- `modules/json/src/main/scala/de/nowchess/json/SquareKeySerializer.scala` — class SquareKeySerializer
- `modules/json/src/main/scala/de/nowchess/json/SquareSerializer.scala` — class SquareSerializer
- `modules/official-bots/python/nnue.py`
- function get_weights_dir: ()
- function get_data_dir: ()
- function list_checkpoints: ()
- function migrate_legacy_data: ()
- function show_header: ()
- function show_checkpoints_table: ()
- _...10 more_
- `modules/official-bots/python/src/dataset.py`
- function get_datasets_dir: () -> Path
- function next_dataset_version: () -> int
- function list_datasets: () -> List[Tuple[int, Dict]]
- function load_dataset_metadata: (version) -> Optional[Dict]
- function save_dataset_metadata: (version, metadata) -> None
- function create_dataset: (version, labeled_jsonl_path, sources, stockfish_depth) -> Path
- _...4 more_
- `modules/official-bots/python/src/export.py` — function export_to_nbai: (weights_file, output_file, trained_by, train_loss)
- `modules/official-bots/python/src/generate.py` — function play_random_game_and_collect_positions: (output_file, total_positions, samples_per_game, min_move, max_move, num_workers)
- `modules/official-bots/python/src/label.py` — function normalize_evaluation: (cp_value, method, scale), function label_positions_with_stockfish: (positions_file, output_file, stockfish_path, batch_size, depth, verbose, normalize, num_workers)
- `modules/official-bots/python/src/lichess_importer.py` — function import_lichess_evals: (input_path, output_file, max_positions, min_depth, verbose) -> int
- `modules/official-bots/python/src/tactical_positions_extractor.py`
- function download_and_extract_puzzle_db: (url, output_dir)
- function extract_puzzle_positions: (puzzle_csv, max_puzzles) -> Set[str]
- function load_positions_from_file: (file_path) -> Set[str]
- function merge_positions: (tactical, other, output_file)
- function extract_tactical_only: (puzzle_csv, output_file, max_puzzles) -> int
- function interactive_merge_positions: (puzzle_csv, output_file, max_puzzles)
- `modules/official-bots/python/src/train.py`
- function fen_to_features: (fen)
- function find_next_version: (base_name)
- function save_metadata: (weights_file, metadata)
- function train_nnue: (data_file, output_file, epochs, batch_size, lr, checkpoint, stockfish_depth, use_versioning, early_stopping_patience, weight_decay, subsample_ratio, hidden_sizes)
- function burst_train: (data_file, output_file, duration_minutes, epochs_per_season, early_stopping_patience, batch_size, lr, initial_checkpoint, stockfish_depth, use_versioning, weight_decay, subsample_ratio, hidden_sizes)
- class NNUEDataset
- _...1 more_
- `modules/official-bots/src/main/scala/de/nowchess/bot/BotController.scala`
- class BotController
- function getBot
- function listBots
- class BotController
- function getBot
- function listBots
- `modules/official-bots/src/main/scala/de/nowchess/bot/BotMoveRepetition.scala`
- class BotMoveRepetition
- function blockedMoves
- function repeatedMove
- function filterAllowed
- `modules/official-bots/src/main/scala/de/nowchess/bot/Config.scala` — class Config
- `modules/official-bots/src/main/scala/de/nowchess/bot/ai/Evaluation.scala`
- class Evaluation
- class CHECKMATE_SCORE
- class DRAW_SCORE
- function evaluate
- function initAccumulator
- function copyAccumulator
- _...2 more_
- `modules/official-bots/src/main/scala/de/nowchess/bot/bots/ClassicalBot.scala` — class ClassicalBot, function apply
- `modules/official-bots/src/main/scala/de/nowchess/bot/bots/HybridBot.scala` — class HybridBot, function apply
- `modules/official-bots/src/main/scala/de/nowchess/bot/bots/NNUEBot.scala` — class NNUEBot, function apply
- `modules/official-bots/src/main/scala/de/nowchess/bot/bots/classic/EvaluationClassic.scala`
- class EvaluationClassic
- function evaluate
- function countRay
- `modules/official-bots/src/main/scala/de/nowchess/bot/bots/nnue/EvaluationNNUE.scala` — class EvaluationNNUE, function evaluate
- `modules/official-bots/src/main/scala/de/nowchess/bot/bots/nnue/NNUE.scala`
- class NNUE
- function initAccumulator
- function pushAccumulator
- function copyAccumulator
- function recomputeAccumulator
- function validateAccumulator
- _...4 more_
- `modules/official-bots/src/main/scala/de/nowchess/bot/bots/nnue/NbaiLoader.scala`
- class NbaiLoader
- function load
- function loadDefault
- `modules/official-bots/src/main/scala/de/nowchess/bot/bots/nnue/NbaiMigrator.scala` — class NbaiMigrator, function migrateFromBin
- `modules/official-bots/src/main/scala/de/nowchess/bot/bots/nnue/NbaiModel.scala`
- function toJson
- class NbaiMetadata
- function fromJson
- function str
- function num
- `modules/official-bots/src/main/scala/de/nowchess/bot/bots/nnue/NbaiWriter.scala` — class NbaiWriter, function write
- `modules/official-bots/src/main/scala/de/nowchess/bot/config/JacksonConfig.scala` — class JacksonConfig, function customize
- `modules/official-bots/src/main/scala/de/nowchess/bot/config/RedisConfig.scala` — class RedisConfig
- `modules/official-bots/src/main/scala/de/nowchess/bot/logic/AlphaBetaSearch.scala`
- function bestMove
- function bestMove
- function bestMoveWithTime
- function bestMoveWithTime
- function loop
- function loop
- `modules/official-bots/src/main/scala/de/nowchess/bot/logic/MoveOrdering.scala`
- class MoveOrdering
- class OrderingContext
- function addKillerMove
- function getKillerMoves
- function addHistory
- function getHistory
- _...3 more_
- `modules/official-bots/src/main/scala/de/nowchess/bot/logic/TranspositionTable.scala`
- function advance
- function probe
- function store
- function clear
- `modules/official-bots/src/main/scala/de/nowchess/bot/resource/OfficialBotChallengeResource.scala` — class OfficialBotChallengeResource, function challengeWithDifficulty
- `modules/official-bots/src/main/scala/de/nowchess/bot/service/DifficultyMapper.scala` — class DifficultyMapper, function fromElo
- `modules/official-bots/src/main/scala/de/nowchess/bot/service/OfficialBotService.scala` — class OfficialBotService, function onStart
- `modules/official-bots/src/main/scala/de/nowchess/bot/util/PolyglotBook.scala` — function probe, function select
- `modules/official-bots/src/main/scala/de/nowchess/bot/util/PolyglotHash.scala` — class PolyglotHash, function hash
- `modules/official-bots/src/main/scala/de/nowchess/bot/util/ZobristHash.scala`
- class ZobristHash
- function hash
- function nextHash
- `modules/rule/src/main/scala/de/nowchess/rules/config/JacksonConfig.scala` — class JacksonConfig, function customize
- `modules/rule/src/main/scala/de/nowchess/rules/config/NativeReflectionConfig.scala` — class NativeReflectionConfig
- `modules/rule/src/main/scala/de/nowchess/rules/grpc/ProtoMapper.scala`
- class ProtoMapper
- function toProtoColor
- function fromProtoColor
- function toProtoPieceType
- function fromProtoPieceType
- function toProtoMoveKind
- _...9 more_
- `modules/rule/src/main/scala/de/nowchess/rules/grpc/ProtoMapper.scala` — class ProtoMapper
- `modules/rule/src/main/scala/de/nowchess/rules/grpc/RuleGrpcService.scala` — class RuleGrpcService
- `modules/rule/src/main/scala/de/nowchess/rules/resource/RuleSetResource.scala`
- class RuleSetResource
@@ -520,35 +531,37 @@
- function isCheckmate
- _...6 more_
- `modules/rule/src/main/scala/de/nowchess/rules/sets/DefaultRules.scala` — class DefaultRules, function positionOf
- `modules/security/src/main/scala/de/nowchess/security/InternalAuthFilter.scala` — class InternalAuthFilter
- `modules/security/src/main/scala/de/nowchess/security/InternalGrpcAuthInterceptor.scala` — class InternalGrpcAuthInterceptor
- `modules/security/src/main/scala/de/nowchess/security/InternalGrpcSecretClientInterceptor.scala` — class InternalGrpcSecretClientInterceptor
- `modules/security/src/main/scala/de/nowchess/security/InternalSecretClientFilter.scala` — class InternalSecretClientFilter
- `modules/store/src/main/scala/de/nowchess/store/config/JacksonConfig.scala` — class JacksonConfig, function customize
- `modules/store/src/main/scala/de/nowchess/store/config/NativeReflectionConfig.scala` — class NativeReflectionConfig
- `modules/store/src/main/scala/de/nowchess/store/config/RedisConfig.scala` — class RedisConfig
- `modules/store/src/main/scala/de/nowchess/store/config/RedissonProducer.scala`
- class RedissonProducer
- function redissonClient
- function close
- `modules/store/src/main/scala/de/nowchess/store/domain/GameRecord.scala` — class GameRecord
- `modules/store/src/main/scala/de/nowchess/store/redis/GameWritebackStreamListener.scala`
- class GameWritebackStreamListener
- function startListening
- function onMessage
- `modules/store/src/main/scala/de/nowchess/store/redis/GameWritebackStreamListener.scala` — class GameWritebackStreamListener, function startListening
- `modules/store/src/main/scala/de/nowchess/store/repository/GameRecordRepository.scala`
- class GameRecordRepository
- function findByGameId
- function persist
- function merge
- `modules/store/src/main/scala/de/nowchess/store/resource/StoreGameResource.scala` — class StoreGameResource, function getGame
- function findByPlayerId
- function findByPlayerIdRunning
- `modules/store/src/main/scala/de/nowchess/store/resource/StoreGameResource.scala`
- class StoreGameResource
- function getGame
- function getRunning
- function getHistory
- `modules/store/src/main/scala/de/nowchess/store/service/GameWritebackService.scala` — class GameWritebackService, function writeBack
- `modules/ws/src/main/scala/de/nowchess/ws/config/JacksonConfig.scala` — class JacksonConfig, function customize
- `modules/ws/src/main/scala/de/nowchess/ws/config/NativeReflectionConfig.scala` — class NativeReflectionConfig
- `modules/ws/src/main/scala/de/nowchess/ws/config/RedisConfig.scala` — class RedisConfig
- `modules/ws/src/main/scala/de/nowchess/ws/config/RedissonProducer.scala`
- class RedissonProducer
- function produceRedissonClient
- function shutdown
- `modules/ws/src/main/scala/de/nowchess/ws/resource/GameWebSocketResource.scala`
- class GameWebSocketResource
- function onOpen
- function onMessage
- function onTextMessage
- function onClose
- `modules/ws/src/main/scala/de/nowchess/ws/resource/UserWebSocketResource.scala`
- class UserWebSocketResource
- function onOpen
- function onClose
+1 -1
View File
@@ -1,4 +1,4 @@
# Middleware
## custom
- generate — `modules/bot/python/src/generate.py`
- generate — `modules/official-bots/python/src/generate.py`
+46 -11
View File
@@ -19,12 +19,20 @@ jobs:
- id: check
run: |
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
echo "Triggered manually — allowing build"
echo "allowed=true" >> "$GITHUB_OUTPUT"
else
COMMIT_AUTHOR=$(git log -1 --format='%an')
COMMIT_SHA=$(git log -1 --format='%H')
COMMIT_MSG=$(git log -1 --format='%s')
echo "Commit: ${COMMIT_SHA}"
echo "Author: ${COMMIT_AUTHOR}"
echo "Message: ${COMMIT_MSG}"
if [[ "$COMMIT_AUTHOR" == "TeamCity" ]]; then
echo "Author is TeamCity — allowing build"
echo "allowed=true" >> "$GITHUB_OUTPUT"
else
echo "Author is not TeamCity — skipping build"
echo "allowed=false" >> "$GITHUB_OUTPUT"
fi
fi
@@ -53,7 +61,39 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Read version from versions.env
id: version
run: |
if [ -f "modules/${{ matrix.module }}/versions.env" ]; then
source modules/${{ matrix.module }}/versions.env
VERSION="${MAJOR}.${MINOR}.${PATCH}"
echo "[${{ matrix.module }}] Version: ${VERSION}"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
else
echo "[${{ matrix.module }}] No versions.env found — using 'latest'"
echo "version=latest" >> "$GITHUB_OUTPUT"
fi
- name: Check if image exists in GHCR
id: image-check
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PACKAGE="now-chess-systems%2F${{ matrix.module }}"
VERSION="${{ steps.version.outputs.version }}"
EXISTING_TAGS=$(gh api "orgs/now-chess/packages/container/${PACKAGE}/versions" \
--jq '.[].metadata.container.tags[]' 2>/dev/null || echo "")
echo "[${{ matrix.module }}] Existing tags: $(echo "${EXISTING_TAGS}" | tr '\n' ' ' | xargs)"
if echo "${EXISTING_TAGS}" | grep -qx "${VERSION}"; then
echo "[${{ matrix.module }}] Image ${VERSION} already exists — skipping build"
echo "exists=true" >> "$GITHUB_OUTPUT"
else
echo "[${{ matrix.module }}] Image ${VERSION} not found — will build"
echo "exists=false" >> "$GITHUB_OUTPUT"
fi
- name: Set up GraalVM
if: steps.image-check.outputs.exists == 'false'
uses: graalvm/setup-graalvm@v1
with:
java-version: '21'
@@ -61,6 +101,7 @@ jobs:
native-image-job-reports: 'true'
- name: Cache Gradle packages
if: steps.image-check.outputs.exists == 'false'
uses: actions/cache@v4
with:
path: |
@@ -69,24 +110,16 @@ jobs:
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: gradle-${{ runner.os }}-
- name: Read version from versions.env
id: version
run: |
if [ -f "modules/${{ matrix.module }}/versions.env" ]; then
source modules/${{ matrix.module }}/versions.env
VERSION="${MAJOR}.${MINOR}.${PATCH}"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
else
echo "version=latest" >> "$GITHUB_OUTPUT"
fi
- name: Build native binary
if: steps.image-check.outputs.exists == 'false'
run: ./gradlew :modules:${{ matrix.module }}:build -x test -Dquarkus.native.enabled=true -Dquarkus.package.jar.enabled=false -Dquarkus.profile=deployed --no-daemon
- name: Set up Docker Buildx
if: steps.image-check.outputs.exists == 'false'
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
if: steps.image-check.outputs.exists == 'false'
uses: docker/login-action@v3
with:
registry: ghcr.io
@@ -94,6 +127,7 @@ jobs:
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
if: steps.image-check.outputs.exists == 'false'
id: meta
uses: docker/metadata-action@v5
with:
@@ -103,6 +137,7 @@ jobs:
type=raw,value=latest
- name: Build and push
if: steps.image-check.outputs.exists == 'false'
uses: docker/build-push-action@v6
with:
context: .
+7 -3
View File
@@ -4,11 +4,15 @@ meta {
seq: 1
}
http {
method: POST
post {
url: {{accountBaseUrl}}/account
body: json
auth: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
headers {
+7 -3
View File
@@ -4,11 +4,15 @@ meta {
seq: 2
}
http {
method: POST
post {
url: {{accountBaseUrl}}/account/login
body: json
auth: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
headers {
@@ -7,7 +7,12 @@ meta {
get {
url: {{accountBaseUrl}}/account/me
body: none
auth: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
headers {
@@ -4,10 +4,15 @@ meta {
seq: 4
}
http {
method: GET
get {
url: {{accountBaseUrl}}/account/{{username}}
auth: none
body: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
headers {
+7 -3
View File
@@ -4,11 +4,15 @@ meta {
seq: 5
}
http {
method: POST
post {
url: {{accountBaseUrl}}/account/bots
body: json
auth: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
headers {
+6 -1
View File
@@ -7,7 +7,12 @@ meta {
get {
url: {{accountBaseUrl}}/account/bots
body: none
auth: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
headers {
+7 -3
View File
@@ -4,11 +4,15 @@ meta {
seq: 7
}
http {
method: PUT
put {
url: {{accountBaseUrl}}/account/bots/{{botId}}
body: json
auth: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
headers {
@@ -4,10 +4,15 @@ meta {
seq: 8
}
http {
method: POST
post {
url: {{accountBaseUrl}}/account/bots/{{botId}}/rotate-token
auth: none
body: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
headers {
+8 -3
View File
@@ -4,10 +4,15 @@ meta {
seq: 9
}
http {
method: DELETE
delete {
url: {{accountBaseUrl}}/account/bots/{{botId}}
auth: none
body: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
headers {
@@ -4,10 +4,15 @@ meta {
seq: 10
}
http {
method: GET
get {
url: {{accountBaseUrl}}/account/official-bots
auth: none
body: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
headers {
+8 -3
View File
@@ -4,10 +4,15 @@ meta {
seq: 11
}
http {
method: POST
post {
url: {{accountBaseUrl}}/account/{{userId}}/ban
auth: none
body: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
headers {
+8 -3
View File
@@ -4,10 +4,15 @@ meta {
seq: 12
}
http {
method: POST
post {
url: {{accountBaseUrl}}/account/{{userId}}/unban
auth: none
body: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
headers {
@@ -4,11 +4,15 @@ meta {
seq: 1
}
http {
method: POST
post {
url: {{accountBaseUrl}}/challenge/{{username}}
body: json
auth: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
headers {
@@ -7,7 +7,12 @@ meta {
get {
url: {{accountBaseUrl}}/challenge
body: none
auth: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
headers {
+8 -3
View File
@@ -4,10 +4,15 @@ meta {
seq: 3
}
http {
method: GET
get {
url: {{accountBaseUrl}}/challenge/{{challengeId}}
auth: none
body: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
headers {
@@ -4,10 +4,15 @@ meta {
seq: 4
}
http {
method: POST
post {
url: {{accountBaseUrl}}/challenge/{{challengeId}}/accept
auth: none
body: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
headers {
@@ -4,11 +4,15 @@ meta {
seq: 5
}
http {
method: POST
post {
url: {{accountBaseUrl}}/challenge/{{challengeId}}/decline
body: json
auth: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
headers {
@@ -4,10 +4,15 @@ meta {
seq: 6
}
http {
method: POST
post {
url: {{accountBaseUrl}}/challenge/{{challengeId}}/cancel
auth: none
body: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
headers {
@@ -4,10 +4,15 @@ meta {
seq: 1
}
http {
method: POST
post {
url: {{accountBaseUrl}}/challenge/official/{{botName}}?difficulty={{difficulty}}&color={{color}}
auth: none
body: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
headers {
@@ -15,7 +20,7 @@ headers {
Accept: application/json
}
notes {
docs {
Query Parameters:
- difficulty: 1000-2800 (ELO)
- color: white | black | random
@@ -4,11 +4,15 @@ meta {
seq: 2
}
http {
method: POST
post {
url: {{accountBaseUrl}}/account/official-bots
body: json
auth: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
headers {
@@ -4,10 +4,15 @@ meta {
seq: 3
}
http {
method: DELETE
delete {
url: {{accountBaseUrl}}/account/official-bots/{{botId}}
auth: none
body: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
headers {
+7 -3
View File
@@ -4,9 +4,13 @@ meta {
seq: 1
}
http {
method: POST
post {
url: {{baseUrl}}/api/board/game/{{gameId}}/draw/offer
body: none
auth: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
+7 -3
View File
@@ -4,9 +4,13 @@ meta {
seq: 2
}
http {
method: POST
post {
url: {{baseUrl}}/api/board/game/{{gameId}}/draw/accept
body: none
auth: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
+7 -3
View File
@@ -4,9 +4,13 @@ meta {
seq: 3
}
http {
method: POST
post {
url: {{baseUrl}}/api/board/game/{{gameId}}/draw/decline
body: none
auth: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
+7 -3
View File
@@ -4,9 +4,13 @@ meta {
seq: 4
}
http {
method: POST
post {
url: {{baseUrl}}/api/board/game/{{gameId}}/draw/claim
body: none
auth: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
+7 -3
View File
@@ -4,9 +4,13 @@ meta {
seq: 1
}
http {
method: GET
get {
url: {{baseUrl}}/api/board/game/{{gameId}}/export/fen
body: none
auth: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
+7 -3
View File
@@ -4,9 +4,13 @@ meta {
seq: 2
}
http {
method: GET
get {
url: {{baseUrl}}/api/board/game/{{gameId}}/export/pgn
body: none
auth: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
+7 -3
View File
@@ -4,11 +4,15 @@ meta {
seq: 1
}
http {
method: POST
post {
url: {{baseUrl}}/api/board/game
body: json
auth: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
headers {
+6 -1
View File
@@ -7,7 +7,12 @@ meta {
get {
url: {{baseUrl}}/api/board/game/{{gameId}}
body: none
auth: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
vars:pre-request {
+7 -3
View File
@@ -4,9 +4,13 @@ meta {
seq: 4
}
http {
method: POST
post {
url: {{baseUrl}}/api/board/game/{{gameId}}/resign
body: none
auth: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
+7 -3
View File
@@ -4,11 +4,15 @@ meta {
seq: 1
}
http {
method: POST
post {
url: {{baseUrl}}/api/board/game/import/fen
body: json
auth: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
headers {
+33
View File
@@ -0,0 +1,33 @@
meta {
name: List Instances
type: http
seq: 1
}
get {
url: {{coordinatorBaseUrl}}/api/coordinator/instances
body: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
docs {
Returns all known core instances from the in-memory registry.
Registry is populated via gRPC heartbeats from core instances.
Requires port-forward: kubectl port-forward svc/nowchess-coordinator 8086:8086 -n <namespace>
Response: InstanceMetadata[]
instanceId: string — unique instance ID
hostname: string
httpPort: int
grpcPort: int
subscriptionCount: int — active game subscriptions
localCacheSize: int
lastHeartbeat: string — ISO-8601 timestamp
state: string — "HEALTHY" | "DEAD"
}
+30
View File
@@ -0,0 +1,30 @@
meta {
name: List Instances
type: http
seq: 1
}
http {
method: GET
url: {{coordinatorBaseUrl}}/api/coordinator/instances
auth: none
}
headers {
Accept: application/json
}
notes {
Returns all known core instances from the in-memory registry.
Registry is populated via gRPC heartbeats from core instances.
Response: InstanceMetadata[]
instanceId: string — unique instance ID
hostname: string
httpPort: int
grpcPort: int
subscriptionCount: int — number of active game subscriptions
localCacheSize: int
lastHeartbeat: string — ISO-8601 timestamp
state: string — "HEALTHY" | "DEAD"
}
+32
View File
@@ -0,0 +1,32 @@
meta {
name: Get Metrics
type: http
seq: 2
}
get {
url: {{coordinatorBaseUrl}}/api/coordinator/metrics
body: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
docs {
Aggregate load metrics computed from the instance registry.
Requires port-forward: kubectl port-forward svc/nowchess-coordinator 8086:8086 -n <namespace>
Response: MetricsDto
totalInstances: int
healthyInstances: int
deadInstances: int
totalGames: int — sum of subscriptionCount across all instances
avgGamesPerCore: double
maxGamesPerCore: int
minGamesPerCore: int
instances: InstanceMetadata[]
}
+29
View File
@@ -0,0 +1,29 @@
meta {
name: Rebalance
type: http
seq: 3
}
post {
url: {{coordinatorBaseUrl}}/api/coordinator/rebalance
body: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
docs {
Triggers a manual rebalance of game subscriptions across core instances.
Runs asynchronously — response does not wait for completion.
Requires port-forward: kubectl port-forward svc/nowchess-coordinator 8086:8086 -n <namespace>
Auto-rebalance runs every 30s (rebalance-interval), min 60s between runs
(rebalance-min-interval). Triggers when load deviation exceeds 20%
(max-deviation-percent).
Response: {"status": "rebalance_started"}
}
+32
View File
@@ -0,0 +1,32 @@
meta {
name: Failover
type: http
seq: 4
}
post {
url: {{coordinatorBaseUrl}}/api/coordinator/failover/{{instanceId}}
body: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
vars:pre-request {
instanceId: core-instance-1
}
docs {
Triggers manual failover for a specific core instance.
Marks it DEAD and migrates its game subscriptions to healthy instances.
Runs asynchronously — response does not wait for completion.
Requires port-forward: kubectl port-forward svc/nowchess-coordinator 8086:8086 -n <namespace>
Path param: instanceId — from /instances response (instanceId field)
Response: {"status": "failover_started", "instanceId": "<id>"}
}
+28
View File
@@ -0,0 +1,28 @@
meta {
name: Scale Up
type: http
seq: 5
}
post {
url: {{coordinatorBaseUrl}}/api/coordinator/scale-up
body: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
docs {
Triggers manual scale-up of core replicas via Kubernetes rollout.
Requires auto-scale-enabled=true and a reachable k8s API.
Respects scale-max-replicas (default: 10).
Requires port-forward: kubectl port-forward svc/nowchess-coordinator 8086:8086 -n <namespace>
Auto-scale triggers when avg load exceeds scale-up-threshold (default: 0.8).
Response: {"status": "scale_up_started"}
}
+28
View File
@@ -0,0 +1,28 @@
meta {
name: Scale Down
type: http
seq: 6
}
post {
url: {{coordinatorBaseUrl}}/api/coordinator/scale-down
body: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
docs {
Triggers manual scale-down of core replicas via Kubernetes rollout.
Requires auto-scale-enabled=true and a reachable k8s API.
Respects scale-min-replicas (default: 2).
Requires port-forward: kubectl port-forward svc/nowchess-coordinator 8086:8086 -n <namespace>
Auto-scale triggers when avg load drops below scale-down-threshold (default: 0.3).
Response: {"status": "scale_down_started"}
}
+31
View File
@@ -0,0 +1,31 @@
meta {
name: List Instances
type: http
seq: 1
}
get {
url: {{coordinatorBaseUrl}}/api/coordinator/instances
body: none
auth: inherit
}
settings {
encodeUrl: true
timeout: 0
}
docs {
Returns all known core instances from the in-memory registry.
Registry is populated via gRPC heartbeats from core instances.
Response: InstanceMetadata[]
instanceId: string — unique instance ID
hostname: string
httpPort: int
grpcPort: int
subscriptionCount: int — number of active game subscriptions
localCacheSize: int
lastHeartbeat: string — ISO-8601 timestamp
state: string — "HEALTHY" | "DEAD"
}
@@ -1,4 +1,4 @@
meta {
name: coordinator
seq: 4
seq: 6
}
@@ -1,15 +0,0 @@
meta {
name: List Instances
type: http
seq: 1
}
http {
method: GET
url: {{baseUrl}}/coordinator/instances
auth: none
}
headers {
Accept: application/json
}
-15
View File
@@ -1,15 +0,0 @@
meta {
name: Get Metrics
type: http
seq: 2
}
http {
method: GET
url: {{baseUrl}}/coordinator/metrics
auth: none
}
headers {
Accept: application/json
}
-15
View File
@@ -1,15 +0,0 @@
meta {
name: Rebalance
type: http
seq: 3
}
http {
method: POST
url: {{baseUrl}}/coordinator/rebalance
auth: none
}
headers {
Accept: application/json
}
-15
View File
@@ -1,15 +0,0 @@
meta {
name: Failover
type: http
seq: 4
}
http {
method: POST
url: {{baseUrl}}/coordinator/failover/{{instanceId}}
auth: none
}
headers {
Accept: application/json
}
-15
View File
@@ -1,15 +0,0 @@
meta {
name: Scale Up
type: http
seq: 5
}
http {
method: POST
url: {{baseUrl}}/coordinator/scale-up
auth: none
}
headers {
Accept: application/json
}
-15
View File
@@ -1,15 +0,0 @@
meta {
name: Scale Down
type: http
seq: 6
}
http {
method: POST
url: {{baseUrl}}/coordinator/scale-down
auth: none
}
headers {
Accept: application/json
}
+3 -2
View File
@@ -1,9 +1,10 @@
vars {
baseUrl: http://localhost:8080
baseUrl: http://localhost:8080/api
wsBaseUrl: ws://localhost:8084
ioBaseUrl: http://localhost:8080
ioBaseUrl: http://localhost:8080/api
accountBaseUrl: http://localhost:8083/api
storeBaseUrl: http://localhost:8085
coordinatorBaseUrl: http://localhost:8086
token: your_jwt_token_here
adminToken: your_admin_jwt_token_here
botToken: your_bot_jwt_token_here
+1
View File
@@ -4,4 +4,5 @@ vars {
ioBaseUrl: https://nowchess.janis-eccarius.de/api
accountBaseUrl: https://nowchess.janis-eccarius.de/api
storeBaseUrl: https://nowchess.janis-eccarius.de/api
coordinatorBaseUrl: http://localhost:8086
}
+1
View File
@@ -4,4 +4,5 @@ vars {
ioBaseUrl: https://st.nowchess.janis-eccarius.de/api
accountBaseUrl: https://st.nowchess.janis-eccarius.de/api
storeBaseUrl: https://st.nowchess.janis-eccarius.de/api
coordinatorBaseUrl: http://localhost:8086
}
-31
View File
@@ -1,31 +0,0 @@
meta {
name: Game WebSocket
type: http
seq: 1
}
http {
method: GET
url: {{wsBaseUrl}}/api/board/game/{{gameId}}/ws
auth: none
}
headers {
Authorization: Bearer {{token}}
Connection: Upgrade
Upgrade: websocket
}
notes {
WebSocket connection for real-time game updates.
Local: ws://localhost:8084/api/board/game/{{gameId}}/ws
Staging: wss://st.nowchess.janis-eccarius.de/ws/api/board/game/{{gameId}}/ws
Prod: wss://nowchess.janis-eccarius.de/ws/api/board/game/{{gameId}}/ws
Message Types:
- CONNECTED: Connection established
- MOVE: Player move
- GAME_STATE: Full state update
- ERROR: Error message
}
-32
View File
@@ -1,32 +0,0 @@
meta {
name: User WebSocket
type: http
seq: 2
}
http {
method: GET
url: {{wsBaseUrl}}/api/user/ws
auth: none
}
headers {
Authorization: Bearer {{token}}
Connection: Upgrade
Upgrade: websocket
}
notes {
WebSocket connection for user notifications.
Local: ws://localhost:8084/api/user/ws
Staging: wss://st.nowchess.janis-eccarius.de/ws/api/user/ws
Prod: wss://nowchess.janis-eccarius.de/ws/api/user/ws
Message Types:
- CONNECTED: Connection established
- CHALLENGE: Challenge received
- GAME_INVITE: Game invitation
- NOTIFICATION: General notification
- ERROR: Error message
}
+23
View File
@@ -0,0 +1,23 @@
meta {
name: Game WebSocket
type: ws
seq: 1
}
ws {
url: {{wsBaseUrl}}/api/board/game/{{gameId}}/ws
body: ws
auth: inherit
}
headers {
Authorization: Bearer {{token}}
}
body:ws {
name: message 1
type: json
content: '''
{}
'''
}
+23
View File
@@ -0,0 +1,23 @@
meta {
name: User WebSocket
type: ws
seq: 2
}
ws {
url: {{wsBaseUrl}}/api/user/ws
body: ws
auth: inherit
}
headers {
Authorization: Bearer {{token}}
}
body:ws {
name: message 1
type: json
content: '''
{}
'''
}
+4
View File
@@ -0,0 +1,4 @@
meta {
name: ws
seq: 7
}
+50
View File
@@ -29,3 +29,53 @@
* **docker:** add Dockerfiles for building Quarkus application in native and JVM modes ([3f2d2bb](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3f2d2bb4c97fa8cddba66e1da4427c54236dfeed))
* **docker:** add Dockerfiles for Quarkus application in JVM and native modes ([34b9933](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/34b993304670cf2aa62cd2f6460cee7b9864b08e))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
## (2026-04-30)
### Features
* **config:** add H2 database configuration for testing environment ([39c9e49](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/39c9e492cef2515368c074da9406f95e9c0c9e64))
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* **docker:** add .dockerignore and .gitignore files for build exclusions ([c987d8e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/c987d8e258c0e6c4cfbdaa8381c64c410d7a2b83))
* **docker:** add Dockerfiles for building Quarkus application in native and JVM modes ([3f2d2bb](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3f2d2bb4c97fa8cddba66e1da4427c54236dfeed))
* **docker:** add Dockerfiles for Quarkus application in JVM and native modes ([34b9933](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/34b993304670cf2aa62cd2f6460cee7b9864b08e))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
## (2026-05-01)
### Features
* **config:** add H2 database configuration for testing environment ([39c9e49](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/39c9e492cef2515368c074da9406f95e9c0c9e64))
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* **docker:** add .dockerignore and .gitignore files for build exclusions ([c987d8e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/c987d8e258c0e6c4cfbdaa8381c64c410d7a2b83))
* **docker:** add Dockerfiles for building Quarkus application in native and JVM modes ([3f2d2bb](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3f2d2bb4c97fa8cddba66e1da4427c54236dfeed))
* **docker:** add Dockerfiles for Quarkus application in JVM and native modes ([34b9933](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/34b993304670cf2aa62cd2f6460cee7b9864b08e))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
## (2026-05-02)
### Features
* **config:** add H2 database configuration for testing environment ([39c9e49](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/39c9e492cef2515368c074da9406f95e9c0c9e64))
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* **docker:** add .dockerignore and .gitignore files for build exclusions ([c987d8e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/c987d8e258c0e6c4cfbdaa8381c64c410d7a2b83))
* **docker:** add Dockerfiles for building Quarkus application in native and JVM modes ([3f2d2bb](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3f2d2bb4c97fa8cddba66e1da4427c54236dfeed))
* **docker:** add Dockerfiles for Quarkus application in JVM and native modes ([34b9933](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/34b993304670cf2aa62cd2f6460cee7b9864b08e))
* **logging:** add DEBUG/INFO/WARN logging across services (NCS-72) ([#41](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/41)) ([804a4bf](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/804a4bf179e3dfb19e2be4390e7e543caf5237c6))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
## (2026-05-06)
### Features
* **config:** add H2 database configuration for testing environment ([39c9e49](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/39c9e492cef2515368c074da9406f95e9c0c9e64))
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* **docker:** add .dockerignore and .gitignore files for build exclusions ([c987d8e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/c987d8e258c0e6c4cfbdaa8381c64c410d7a2b83))
* **docker:** add Dockerfiles for building Quarkus application in native and JVM modes ([3f2d2bb](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3f2d2bb4c97fa8cddba66e1da4427c54236dfeed))
* **docker:** add Dockerfiles for Quarkus application in JVM and native modes ([34b9933](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/34b993304670cf2aa62cd2f6460cee7b9864b08e))
* **logging:** add DEBUG/INFO/WARN logging across services (NCS-72) ([#41](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/41)) ([804a4bf](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/804a4bf179e3dfb19e2be4390e7e543caf5237c6))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
### Bug Fixes
* **auth:** add InternalClientHeadersFactory for custom client headers management ([e279c39](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/e279c39246470156bf11e745ee72204018d4229d))
@@ -1,9 +1,9 @@
package de.nowchess.account.client
import de.nowchess.security.InternalSecretClientFilter
import de.nowchess.security.{InternalClientHeadersFactory, InternalSecretClientFilter}
import jakarta.ws.rs.*
import jakarta.ws.rs.core.MediaType
import org.eclipse.microprofile.rest.client.annotation.RegisterProvider
import org.eclipse.microprofile.rest.client.annotation.{RegisterClientHeaders, RegisterProvider}
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient
case class CorePlayerInfo(id: String, displayName: String)
@@ -19,6 +19,7 @@ case class CoreGameResponse(gameId: String)
@Path("/api/board/game")
@RegisterRestClient(configKey = "core-service")
@RegisterProvider(classOf[InternalSecretClientFilter])
@RegisterClientHeaders(classOf[InternalClientHeadersFactory])
trait CoreGameClient:
@POST
@@ -9,6 +9,7 @@ import io.smallrye.jwt.build.Jwt
import jakarta.enterprise.context.ApplicationScoped
import jakarta.inject.Inject
import jakarta.transaction.Transactional
import org.jboss.logging.Logger
import scala.compiletime.uninitialized
import java.time.Instant
@@ -17,6 +18,8 @@ import java.util.UUID
@ApplicationScoped
class AccountService:
private val log = Logger.getLogger(classOf[AccountService])
// scalafix:off DisableSyntax.var
@Inject
var userAccountRepository: UserAccountRepository = uninitialized
@@ -30,6 +33,7 @@ class AccountService:
@Transactional
def register(req: RegisterRequest): Either[AccountError, UserAccount] =
log.infof("Registering user %s", req.username)
if userAccountRepository.findByUsername(req.username).isDefined then Left(AccountError.UsernameTaken(req.username))
else if userAccountRepository.findByEmail(req.email).isDefined then
Left(AccountError.EmailAlreadyRegistered(req.email))
@@ -40,15 +44,23 @@ class AccountService:
account.passwordHash = BcryptUtil.bcryptHash(req.password)
account.createdAt = Instant.now()
userAccountRepository.persist(account)
log.infof("User %s registered successfully", req.username)
Right(account)
def login(req: LoginRequest): Either[AccountError, String] =
userAccountRepository.findByUsername(req.username) match
case None => Left(AccountError.InvalidCredentials)
case None =>
log.warnf("Login failed for unknown user %s", req.username)
Left(AccountError.InvalidCredentials)
case Some(account) =>
if !BcryptUtil.matches(req.password, account.passwordHash) then Left(AccountError.InvalidCredentials)
else if account.banned then Left(AccountError.UserBanned)
if !BcryptUtil.matches(req.password, account.passwordHash) then
log.warnf("Login failed — invalid credentials for %s", req.username)
Left(AccountError.InvalidCredentials)
else if account.banned then
log.warnf("Login rejected — user %s is banned", req.username)
Left(AccountError.UserBanned)
else
log.infof("User %s logged in successfully", req.username)
Right(
Jwt
.issuer("nowchess")
@@ -65,6 +77,7 @@ class AccountService:
@Transactional
def createBotAccount(ownerId: UUID, botName: String): Either[AccountError, BotAccount] =
log.infof("Creating bot account %s for owner %s", botName, ownerId.toString)
userAccountRepository.findById(ownerId) match
case None => Left(AccountError.UserNotFound)
case Some(owner) =>
@@ -77,6 +90,7 @@ class AccountService:
bot.token = generateBotToken(bot.id)
bot.createdAt = Instant.now()
botAccountRepository.persist(bot)
log.infof("Bot account %s created for owner %s", botName, ownerId.toString)
Right(bot)
def getBotAccounts(ownerId: UUID): List[BotAccount] =
@@ -93,6 +107,7 @@ class AccountService:
case None => Left(AccountError.BotNotFound)
case Some(_) =>
botAccountRepository.delete(botId)
log.infof("Deleting bot account %s", botId.toString)
Right(())
@Transactional
@@ -146,6 +161,7 @@ class AccountService:
@Transactional
def banUser(userId: UUID): Either[AccountError, UserAccount] =
log.infof("Banning user %s", userId.toString)
userAccountRepository.findById(userId) match
case None => Left(AccountError.UserNotFound)
case Some(user) =>
@@ -156,6 +172,7 @@ class AccountService:
@Transactional
def unbanUser(userId: UUID): Either[AccountError, UserAccount] =
log.infof("Unbanning user %s", userId.toString)
userAccountRepository.findById(userId) match
case None => Left(AccountError.UserNotFound)
case Some(user) =>
+1 -1
View File
@@ -1,3 +1,3 @@
MAJOR=0
MINOR=3
MINOR=7
PATCH=0
+31
View File
@@ -27,3 +27,34 @@
* **docker:** add Dockerfiles for building Quarkus application in native and JVM modes ([3f2d2bb](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3f2d2bb4c97fa8cddba66e1da4427c54236dfeed))
* **docker:** add Dockerfiles for Quarkus application in JVM and native modes ([34b9933](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/34b993304670cf2aa62cd2f6460cee7b9864b08e))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
## (2026-04-30)
### Features
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* **docker:** add .dockerignore and .gitignore files for build exclusions ([c987d8e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/c987d8e258c0e6c4cfbdaa8381c64c410d7a2b83))
* **docker:** add Dockerfiles for building Quarkus application in native and JVM modes ([3f2d2bb](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3f2d2bb4c97fa8cddba66e1da4427c54236dfeed))
* **docker:** add Dockerfiles for Quarkus application in JVM and native modes ([34b9933](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/34b993304670cf2aa62cd2f6460cee7b9864b08e))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
## (2026-05-01)
### Features
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* **docker:** add .dockerignore and .gitignore files for build exclusions ([c987d8e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/c987d8e258c0e6c4cfbdaa8381c64c410d7a2b83))
* **docker:** add Dockerfiles for building Quarkus application in native and JVM modes ([3f2d2bb](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3f2d2bb4c97fa8cddba66e1da4427c54236dfeed))
* **docker:** add Dockerfiles for Quarkus application in JVM and native modes ([34b9933](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/34b993304670cf2aa62cd2f6460cee7b9864b08e))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
## (2026-05-02)
### Features
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* **docker:** add .dockerignore and .gitignore files for build exclusions ([c987d8e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/c987d8e258c0e6c4cfbdaa8381c64c410d7a2b83))
* **docker:** add Dockerfiles for building Quarkus application in native and JVM modes ([3f2d2bb](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3f2d2bb4c97fa8cddba66e1da4427c54236dfeed))
* **docker:** add Dockerfiles for Quarkus application in JVM and native modes ([34b9933](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/34b993304670cf2aa62cd2f6460cee7b9864b08e))
* **logging:** add DEBUG/INFO/WARN logging across services (NCS-72) ([#41](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/41)) ([804a4bf](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/804a4bf179e3dfb19e2be4390e7e543caf5237c6))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
@@ -6,6 +6,7 @@ import io.quarkus.redis.datasource.pubsub.PubSubCommands
import io.smallrye.mutiny.subscription.MultiEmitter
import jakarta.enterprise.context.ApplicationScoped
import jakarta.inject.Inject
import org.jboss.logging.Logger
import scala.compiletime.uninitialized
import java.util.concurrent.ConcurrentHashMap
import java.util.function.Consumer
@@ -13,6 +14,8 @@ import java.util.function.Consumer
@ApplicationScoped
class BotRegistry:
private val log = Logger.getLogger(classOf[BotRegistry])
// scalafix:off DisableSyntax.var
@Inject var redis: RedisDataSource = uninitialized
@Inject var redisConfig: RedisConfig = uninitialized
@@ -25,14 +28,17 @@ class BotRegistry:
val handler: Consumer[String] = msg => emitter.emit(msg)
val subscriber = redis.pubsub(classOf[String]).subscribe(channel, handler)
connections.put(botId, (emitter, subscriber))
log.infof("Bot %s registered", botId)
()
def unregister(botId: String): Unit =
Option(connections.remove(botId)).foreach { (_, subscriber) =>
subscriber.unsubscribe(s"${redisConfig.prefix}:bot:$botId:events")
}
log.infof("Bot %s unregistered", botId)
def dispatch(botId: String, event: String): Unit =
log.debugf("Dispatching event to bot %s", botId)
redis.pubsub(classOf[String]).publish(s"${redisConfig.prefix}:bot:$botId:events", event)
()
@@ -10,6 +10,7 @@ import jakarta.inject.Inject
import jakarta.ws.rs.*
import jakarta.ws.rs.core.{MediaType, Response}
import org.eclipse.microprofile.jwt.JsonWebToken
import org.jboss.logging.Logger
import scala.compiletime.uninitialized
import java.util.function.Consumer
@@ -18,6 +19,8 @@ import java.util.function.Consumer
@RolesAllowed(Array("**"))
class BotEventResource:
private val log = Logger.getLogger(classOf[BotEventResource])
// scalafix:off DisableSyntax.var
@Inject var registry: BotRegistry = uninitialized
@Inject var jwt: JsonWebToken = uninitialized
@@ -32,8 +35,10 @@ class BotEventResource:
val tokenType = Option(jwt.getClaim[AnyRef]("type")).map(_.toString).getOrElse("")
val subject = Option(jwt.getSubject).getOrElse("")
if tokenType != "bot" || subject != botId then
log.warnf("Unauthorized bot stream access — tokenType=%s subject=%s botId=%s", tokenType, subject, botId)
Multi.createFrom().failure(new ForbiddenException("Not authorized for this bot"))
else
log.infof("Bot %s connected to event stream", botId)
Multi.createFrom().emitter[String] { emitter =>
registry.register(botId, emitter)
emitter.onTermination(() => registry.unregister(botId))
@@ -58,6 +63,7 @@ class BotEventResource:
@PathParam("uci") uci: String,
): Response =
val playerId = Option(jwt.getSubject).getOrElse("")
val moveMsg = s"""{"type":"MOVE","uci":"$uci","playerId":"$playerId"}"""
log.debugf("Bot move %s in game %s by player %s", uci, gameId, playerId)
val moveMsg = s"""{"type":"MOVE","uci":"$uci","playerId":"$playerId"}"""
redis.pubsub(classOf[String]).publish(s"${redisConfig.prefix}:game:$gameId:c2s", moveMsg)
Response.ok().build()
+1 -1
View File
@@ -1,3 +1,3 @@
MAJOR=0
MINOR=3
MINOR=6
PATCH=0
+154
View File
@@ -27,3 +27,157 @@
* **docker:** add Dockerfiles for building Quarkus application in native and JVM modes ([3f2d2bb](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3f2d2bb4c97fa8cddba66e1da4427c54236dfeed))
* **docker:** add Dockerfiles for Quarkus application in JVM and native modes ([34b9933](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/34b993304670cf2aa62cd2f6460cee7b9864b08e))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
## (2026-04-30)
### Features
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* **docker:** add .dockerignore and .gitignore files for build exclusions ([c987d8e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/c987d8e258c0e6c4cfbdaa8381c64c410d7a2b83))
* **docker:** add Dockerfiles for building Quarkus application in native and JVM modes ([3f2d2bb](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3f2d2bb4c97fa8cddba66e1da4427c54236dfeed))
* **docker:** add Dockerfiles for Quarkus application in JVM and native modes ([34b9933](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/34b993304670cf2aa62cd2f6460cee7b9864b08e))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
## (2026-05-01)
### Features
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* **docker:** add .dockerignore and .gitignore files for build exclusions ([c987d8e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/c987d8e258c0e6c4cfbdaa8381c64c410d7a2b83))
* **docker:** add Dockerfiles for building Quarkus application in native and JVM modes ([3f2d2bb](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3f2d2bb4c97fa8cddba66e1da4427c54236dfeed))
* **docker:** add Dockerfiles for Quarkus application in JVM and native modes ([34b9933](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/34b993304670cf2aa62cd2f6460cee7b9864b08e))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
### Bug Fixes
* **middleware:** update paths for bot generation and stockfish configuration ([2dd0501](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2dd0501687db08dcd242359f6837125baf8a2fdc))
## (2026-05-02)
### Features
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* **docker:** add .dockerignore and .gitignore files for build exclusions ([c987d8e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/c987d8e258c0e6c4cfbdaa8381c64c410d7a2b83))
* **docker:** add Dockerfiles for building Quarkus application in native and JVM modes ([3f2d2bb](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3f2d2bb4c97fa8cddba66e1da4427c54236dfeed))
* **docker:** add Dockerfiles for Quarkus application in JVM and native modes ([34b9933](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/34b993304670cf2aa62cd2f6460cee7b9864b08e))
* **logging:** add DEBUG/INFO/WARN logging across services (NCS-72) ([#41](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/41)) ([804a4bf](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/804a4bf179e3dfb19e2be4390e7e543caf5237c6))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
### Bug Fixes
* **middleware:** update paths for bot generation and stockfish configuration ([2dd0501](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2dd0501687db08dcd242359f6837125baf8a2fdc))
## (2026-05-02)
### Features
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* **docker:** add .dockerignore and .gitignore files for build exclusions ([c987d8e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/c987d8e258c0e6c4cfbdaa8381c64c410d7a2b83))
* **docker:** add Dockerfiles for building Quarkus application in native and JVM modes ([3f2d2bb](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3f2d2bb4c97fa8cddba66e1da4427c54236dfeed))
* **docker:** add Dockerfiles for Quarkus application in JVM and native modes ([34b9933](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/34b993304670cf2aa62cd2f6460cee7b9864b08e))
* **logging:** add DEBUG/INFO/WARN logging across services (NCS-72) ([#41](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/41)) ([804a4bf](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/804a4bf179e3dfb19e2be4390e7e543caf5237c6))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
### Bug Fixes
* **dependencies:** replace Fabric8 Kubernetes client with Quarkus Kubernetes client ([5f44570](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/5f44570b357277d09f33b7296860c421e2e70ce0))
* **middleware:** update paths for bot generation and stockfish configuration ([2dd0501](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2dd0501687db08dcd242359f6837125baf8a2fdc))
## (2026-05-02)
### Features
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* **docker:** add .dockerignore and .gitignore files for build exclusions ([c987d8e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/c987d8e258c0e6c4cfbdaa8381c64c410d7a2b83))
* **docker:** add Dockerfiles for building Quarkus application in native and JVM modes ([3f2d2bb](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3f2d2bb4c97fa8cddba66e1da4427c54236dfeed))
* **docker:** add Dockerfiles for Quarkus application in JVM and native modes ([34b9933](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/34b993304670cf2aa62cd2f6460cee7b9864b08e))
* **logging:** add DEBUG/INFO/WARN logging across services (NCS-72) ([#41](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/41)) ([804a4bf](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/804a4bf179e3dfb19e2be4390e7e543caf5237c6))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
### Bug Fixes
* **coordinator:** use genericKubernetesResources API for Argo Rollout scaling ([#43](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/43)) ([fa3c6b2](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/fa3c6b2886dc59c14c5dad834acc9b41e42023bb))
* **dependencies:** replace Fabric8 Kubernetes client with Quarkus Kubernetes client ([5f44570](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/5f44570b357277d09f33b7296860c421e2e70ce0))
* **middleware:** update paths for bot generation and stockfish configuration ([2dd0501](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2dd0501687db08dcd242359f6837125baf8a2fdc))
## (2026-05-03)
### Features
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* **docker:** add .dockerignore and .gitignore files for build exclusions ([c987d8e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/c987d8e258c0e6c4cfbdaa8381c64c410d7a2b83))
* **docker:** add Dockerfiles for building Quarkus application in native and JVM modes ([3f2d2bb](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3f2d2bb4c97fa8cddba66e1da4427c54236dfeed))
* **docker:** add Dockerfiles for Quarkus application in JVM and native modes ([34b9933](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/34b993304670cf2aa62cd2f6460cee7b9864b08e))
* **logging:** add DEBUG/INFO/WARN logging across services (NCS-72) ([#41](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/41)) ([804a4bf](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/804a4bf179e3dfb19e2be4390e7e543caf5237c6))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
### Bug Fixes
* **coordinator:** refine type casting in rolloutSpec method ([#45](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/45)) ([d522f7f](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/d522f7f6edf9c985f03dd16816439d4184f1a589))
* **coordinator:** use genericKubernetesResources API for Argo Rollout scaling ([#43](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/43)) ([fa3c6b2](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/fa3c6b2886dc59c14c5dad834acc9b41e42023bb))
* **coordinator:** use genericKubernetesResources API for Argo Rollout scaling ([#44](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/44)) ([82d0b75](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/82d0b754be1075084944b466858672d944f9f7d8))
* **dependencies:** replace Fabric8 Kubernetes client with Quarkus Kubernetes client ([5f44570](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/5f44570b357277d09f33b7296860c421e2e70ce0))
* **middleware:** update paths for bot generation and stockfish configuration ([2dd0501](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2dd0501687db08dcd242359f6837125baf8a2fdc))
## (2026-05-05)
### Features
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* **docker:** add .dockerignore and .gitignore files for build exclusions ([c987d8e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/c987d8e258c0e6c4cfbdaa8381c64c410d7a2b83))
* **docker:** add Dockerfiles for building Quarkus application in native and JVM modes ([3f2d2bb](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3f2d2bb4c97fa8cddba66e1da4427c54236dfeed))
* **docker:** add Dockerfiles for Quarkus application in JVM and native modes ([34b9933](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/34b993304670cf2aa62cd2f6460cee7b9864b08e))
* **logging:** add DEBUG/INFO/WARN logging across services (NCS-72) ([#41](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/41)) ([804a4bf](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/804a4bf179e3dfb19e2be4390e7e543caf5237c6))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
### Bug Fixes
* **coordinator:** refine type casting in rolloutSpec method ([#45](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/45)) ([d522f7f](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/d522f7f6edf9c985f03dd16816439d4184f1a589))
* **coordinator:** use genericKubernetesResources API for Argo Rollout scaling ([#43](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/43)) ([fa3c6b2](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/fa3c6b2886dc59c14c5dad834acc9b41e42023bb))
* **coordinator:** use genericKubernetesResources API for Argo Rollout scaling ([#44](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/44)) ([82d0b75](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/82d0b754be1075084944b466858672d944f9f7d8))
* **dependencies:** replace Fabric8 Kubernetes client with Quarkus Kubernetes client ([5f44570](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/5f44570b357277d09f33b7296860c421e2e70ce0))
* **middleware:** update paths for bot generation and stockfish configuration ([2dd0501](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2dd0501687db08dcd242359f6837125baf8a2fdc))
* **redis:** update Redis configuration with max pool size and waiting parameters ([5baf6a7](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/5baf6a7cdbea484fc49c02e2b5a1c3919b7fa2c4))
## (2026-05-08)
### Features
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* **docker:** add .dockerignore and .gitignore files for build exclusions ([c987d8e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/c987d8e258c0e6c4cfbdaa8381c64c410d7a2b83))
* **docker:** add Dockerfiles for building Quarkus application in native and JVM modes ([3f2d2bb](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3f2d2bb4c97fa8cddba66e1da4427c54236dfeed))
* **docker:** add Dockerfiles for Quarkus application in JVM and native modes ([34b9933](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/34b993304670cf2aa62cd2f6460cee7b9864b08e))
* **logging:** add DEBUG/INFO/WARN logging across services (NCS-72) ([#41](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/41)) ([804a4bf](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/804a4bf179e3dfb19e2be4390e7e543caf5237c6))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
### Bug Fixes
* **coordinator:** refine type casting in rolloutSpec method ([#45](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/45)) ([d522f7f](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/d522f7f6edf9c985f03dd16816439d4184f1a589))
* **coordinator:** use genericKubernetesResources API for Argo Rollout scaling ([#43](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/43)) ([fa3c6b2](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/fa3c6b2886dc59c14c5dad834acc9b41e42023bb))
* **coordinator:** use genericKubernetesResources API for Argo Rollout scaling ([#44](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/44)) ([82d0b75](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/82d0b754be1075084944b466858672d944f9f7d8))
* **dependencies:** replace Fabric8 Kubernetes client with Quarkus Kubernetes client ([5f44570](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/5f44570b357277d09f33b7296860c421e2e70ce0))
* enhance AutoScaler and InstanceRegistry for replica management and stale instance eviction ([b4920d3](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b4920d3817e58bda94d7764e608b856ce9a909f7))
* **middleware:** update paths for bot generation and stockfish configuration ([2dd0501](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2dd0501687db08dcd242359f6837125baf8a2fdc))
* **redis:** update Redis configuration with max pool size and waiting parameters ([5baf6a7](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/5baf6a7cdbea484fc49c02e2b5a1c3919b7fa2c4))
## (2026-05-08)
### Features
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* **docker:** add .dockerignore and .gitignore files for build exclusions ([c987d8e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/c987d8e258c0e6c4cfbdaa8381c64c410d7a2b83))
* **docker:** add Dockerfiles for building Quarkus application in native and JVM modes ([3f2d2bb](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3f2d2bb4c97fa8cddba66e1da4427c54236dfeed))
* **docker:** add Dockerfiles for Quarkus application in JVM and native modes ([34b9933](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/34b993304670cf2aa62cd2f6460cee7b9864b08e))
* **logging:** add DEBUG/INFO/WARN logging across services (NCS-72) ([#41](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/41)) ([804a4bf](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/804a4bf179e3dfb19e2be4390e7e543caf5237c6))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
### Bug Fixes
* **coordinator:** refine type casting in rolloutSpec method ([#45](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/45)) ([d522f7f](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/d522f7f6edf9c985f03dd16816439d4184f1a589))
* **coordinator:** use genericKubernetesResources API for Argo Rollout scaling ([#43](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/43)) ([fa3c6b2](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/fa3c6b2886dc59c14c5dad834acc9b41e42023bb))
* **coordinator:** use genericKubernetesResources API for Argo Rollout scaling ([#44](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/44)) ([82d0b75](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/82d0b754be1075084944b466858672d944f9f7d8))
* **dependencies:** replace Fabric8 Kubernetes client with Quarkus Kubernetes client ([5f44570](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/5f44570b357277d09f33b7296860c421e2e70ce0))
* enhance AutoScaler and InstanceRegistry for replica management and stale instance eviction ([b4920d3](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b4920d3817e58bda94d7764e608b856ce9a909f7))
* **middleware:** update paths for bot generation and stockfish configuration ([2dd0501](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2dd0501687db08dcd242359f6837125baf8a2fdc))
* **redis:** update Redis configuration with max pool size and waiting parameters ([5baf6a7](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/5baf6a7cdbea484fc49c02e2b5a1c3919b7fa2c4))
* update HealthMonitor to evict instances without associated pods ([0f41f13](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/0f41f13ce68b76846684bab67241a122250dfaf9))
+1 -1
View File
@@ -73,7 +73,7 @@ dependencies {
implementation("io.quarkus:quarkus-rest-client-jackson")
implementation("com.fasterxml.jackson.module:jackson-module-scala_3:${versions["JACKSON_SCALA"]!!}")
implementation("io.quarkus:quarkus-redis-client")
implementation("io.fabric8:kubernetes-client:6.13.0")
implementation("io.quarkus:quarkus-kubernetes-client")
testImplementation(platform("org.junit:junit-bom:${versions["JUNIT_BOM"]!!}"))
testImplementation("org.junit.jupiter:junit-jupiter")
@@ -5,11 +5,12 @@ quarkus:
port: 8086
redis:
hosts: redis://${REDIS_HOST:localhost}:${REDIS_PORT:6379}
max-pool-size: 64
max-pool-waiting: 128
grpc:
server:
port: 9086
rest-client:
connection-timeout: 5000
read-timeout: 10000
smallrye-openapi:
info-title: NowChess Coordinator Service
@@ -27,23 +27,36 @@ class CoordinatorGrpcServer extends CoordinatorServiceGrpc.CoordinatorServiceImp
override def heartbeatStream(
responseObserver: StreamObserver[CoordinatorCommand],
): StreamObserver[HeartbeatFrame] =
log.info("New heartbeat stream connection established")
new StreamObserver[HeartbeatFrame]:
// scalafix:off DisableSyntax.var
private var lastInstanceId = ""
private var firstFrameSeen = false
// scalafix:on DisableSyntax.var
override def onNext(frame: HeartbeatFrame): Unit =
lastInstanceId = frame.getInstanceId
try
instanceRegistry.updateInstanceFromRedis(frame.getInstanceId)
log.debugf(
"Received heartbeat from %s with %d subscriptions",
if !firstFrameSeen then
firstFrameSeen = true
log.infof(
"First heartbeat from instance %s (host=%s http=%d grpc=%d)",
frame.getInstanceId,
frame.getSubscriptionCount,
frame.getHostname,
frame.getHttpPort,
frame.getGrpcPort,
)
instanceRegistry
.updateInstanceFromRedis(frame.getInstanceId)
.subscribe()
.`with`(
_ =>
log.debugf(
"Received heartbeat from %s with %d subscriptions",
frame.getInstanceId,
frame.getSubscriptionCount,
),
ex => log.warnf(ex, "Failed to process heartbeat from %s", frame.getInstanceId),
)
catch
case ex: Exception =>
log.warnf(ex, "Failed to process heartbeat from %s", frame.getInstanceId)
override def onError(t: Throwable): Unit =
log.warnf(t, "Heartbeat stream error for instance %s", lastInstanceId)
@@ -16,10 +16,18 @@ class CoreGrpcClient:
private val channels = ConcurrentHashMap[String, ManagedChannel]()
private def getChannel(host: String, port: Int): ManagedChannel =
channels.computeIfAbsent(s"$host:$port", _ => ManagedChannelBuilder.forAddress(host, port).usePlaintext().build())
channels.computeIfAbsent(
s"$host:$port",
_ =>
log.infof("Opening gRPC channel to %s:%d", host, port)
ManagedChannelBuilder.forAddress(host, port).usePlaintext().build(),
)
private def evictStaleChannel(host: String, port: Int): Unit =
Option(channels.remove(s"$host:$port")).foreach(_.shutdownNow())
Option(channels.remove(s"$host:$port")).foreach { ch =>
log.infof("Evicting stale gRPC channel to %s:%d", host, port)
ch.shutdownNow()
}
@PreDestroy
def shutdown(): Unit =
@@ -33,7 +41,9 @@ class CoreGrpcClient:
try
val stub = CoordinatorServiceGrpc.newBlockingStub(getChannel(host, port))
val request = BatchResubscribeRequest.newBuilder().addAllGameIds(gameIds.asJava).build()
stub.batchResubscribeGames(request).getSubscribedCount
val count = stub.batchResubscribeGames(request).getSubscribedCount
log.debugf("batchResubscribeGames %s:%d — subscribed %d games", host, port, count)
count
catch
case ex: Exception =>
log.warnf(ex, "batchResubscribeGames RPC failed for %s:%d", host, port)
@@ -44,7 +54,9 @@ class CoreGrpcClient:
try
val stub = CoordinatorServiceGrpc.newBlockingStub(getChannel(host, port))
val request = UnsubscribeGamesRequest.newBuilder().addAllGameIds(gameIds.asJava).build()
stub.unsubscribeGames(request).getUnsubscribedCount
val count = stub.unsubscribeGames(request).getUnsubscribedCount
log.debugf("unsubscribeGames %s:%d — unsubscribed %d games", host, port, count)
count
catch
case ex: Exception =>
log.warnf(ex, "unsubscribeGames RPC failed for %s:%d", host, port)
@@ -55,7 +67,9 @@ class CoreGrpcClient:
try
val stub = CoordinatorServiceGrpc.newBlockingStub(getChannel(host, port))
val request = EvictGamesRequest.newBuilder().addAllGameIds(gameIds.asJava).build()
stub.evictGames(request).getEvictedCount
val count = stub.evictGames(request).getEvictedCount
log.debugf("evictGames %s:%d — evicted %d games", host, port, count)
count
catch
case ex: Exception =>
log.warnf(ex, "evictGames RPC failed for %s:%d", host, port)
@@ -30,14 +30,15 @@ class AutoScaler:
if kubeClientInstance.isUnsatisfied then None
else Some(kubeClientInstance.get())
private val argoApiVersion = "argoproj.io/v1alpha1"
private val argoKind = "Rollout"
// scalafix:off DisableSyntax.asInstanceOf
// scalafix:off DisableSyntax.isInstanceOf
private def rolloutSpec(rollout: GenericKubernetesResource): Option[java.util.Map[String, AnyRef]] =
Option(rollout.get("spec")).collect {
case m if m.isInstanceOf[java.util.Map[?, ?]] => m.asInstanceOf[java.util.Map[String, AnyRef]]
Option(rollout.get[AnyRef]("spec")).collect { case m: java.util.Map[?, ?] =>
m.asInstanceOf[java.util.Map[String, AnyRef]]
}
// scalafix:on DisableSyntax.asInstanceOf
// scalafix:on DisableSyntax.isInstanceOf
def checkAndScale: Unit =
if config.autoScaleEnabled then
@@ -61,7 +62,7 @@ class AutoScaler:
try
Option(
kube
.resources(classOf[GenericKubernetesResource])
.genericKubernetesResources(argoApiVersion, argoKind)
.inNamespace(config.k8sNamespace)
.withName(config.k8sRolloutName)
.get(),
@@ -73,11 +74,11 @@ class AutoScaler:
val maxReplicas = config.scaleMaxReplicas
if currentReplicas < maxReplicas then
spec.put("replicas", String.valueOf(currentReplicas + 1))
spec.put("replicas", Integer.valueOf(currentReplicas + 1))
kube
.resources(classOf[GenericKubernetesResource])
.genericKubernetesResources(argoApiVersion, argoKind)
.inNamespace(config.k8sNamespace)
.withName(config.k8sRolloutName)
.resource(rollout)
.update()
log.infof(
"Scaled up %s from %d to %d replicas",
@@ -102,7 +103,7 @@ class AutoScaler:
try
Option(
kube
.resources(classOf[GenericKubernetesResource])
.genericKubernetesResources(argoApiVersion, argoKind)
.inNamespace(config.k8sNamespace)
.withName(config.k8sRolloutName)
.get(),
@@ -114,11 +115,11 @@ class AutoScaler:
val minReplicas = config.scaleMinReplicas
if currentReplicas > minReplicas then
spec.put("replicas", String.valueOf(currentReplicas - 1))
spec.put("replicas", Integer.valueOf(currentReplicas - 1))
kube
.resources(classOf[GenericKubernetesResource])
.genericKubernetesResources(argoApiVersion, argoKind)
.inNamespace(config.k8sNamespace)
.withName(config.k8sRolloutName)
.resource(rollout)
.update()
log.infof(
"Scaled down %s from %d to %d replicas",
@@ -39,6 +39,8 @@ class HealthMonitor:
redisPrefix = prefix
def checkInstanceHealth: Unit =
val evicted = instanceRegistry.evictStaleInstances(config.heartbeatTtl)
if evicted.nonEmpty then log.warnf("Evicted %d stale instances: %s", evicted.size, evicted.mkString(", "))
val instances = instanceRegistry.getAllInstances
instances.foreach { inst =>
val isHealthy = checkHealth(inst.instanceId)
@@ -109,9 +111,8 @@ class HealthMonitor:
log.warnf("Pod %s not ready, marking instance %s dead", pod.getMetadata.getName, inst.instanceId)
instanceRegistry.markInstanceDead(inst.instanceId)
case None =>
if inst.state == "HEALTHY" then
log.warnf("No pod found for instance %s, marking dead", inst.instanceId)
instanceRegistry.markInstanceDead(inst.instanceId)
log.warnf("No pod found for instance %s, evicting from registry", inst.instanceId)
instanceRegistry.removeInstance(inst.instanceId)
}
catch
case ex: Exception =>
@@ -2,21 +2,25 @@ package de.nowchess.coordinator.service
import jakarta.enterprise.context.ApplicationScoped
import jakarta.inject.Inject
import io.quarkus.redis.datasource.RedisDataSource
import io.quarkus.redis.datasource.ReactiveRedisDataSource
import scala.jdk.CollectionConverters.*
import scala.compiletime.uninitialized
import com.fasterxml.jackson.databind.ObjectMapper
import de.nowchess.coordinator.dto.InstanceMetadata
import java.util.concurrent.ConcurrentHashMap
import java.time.{Duration, Instant}
import io.smallrye.mutiny.Uni
import org.jboss.logging.Logger
@ApplicationScoped
class InstanceRegistry:
// scalafix:off DisableSyntax.var
@Inject
private var redis: RedisDataSource = uninitialized
private var redisPrefix = "nowchess"
private var redis: ReactiveRedisDataSource = uninitialized
private var redisPrefix = "nowchess"
// scalafix:on DisableSyntax.var
private val log = Logger.getLogger(classOf[InstanceRegistry])
private val mapper = ObjectMapper()
private val instances = ConcurrentHashMap[String, InstanceMetadata]()
@@ -29,19 +33,56 @@ class InstanceRegistry:
def getAllInstances: List[InstanceMetadata] =
instances.values.asScala.toList
def updateInstanceFromRedis(instanceId: String): Unit =
def updateInstanceFromRedis(instanceId: String): Uni[Unit] =
val key = s"$redisPrefix:instances:$instanceId"
Option(redis.value(classOf[String]).get(key)).foreach { value =>
try
val metadata = mapper.readValue(value, classOf[InstanceMetadata])
instances.put(instanceId, metadata)
catch case _: Exception => ()
}
redis
.value(classOf[String])
.get(key)
.onItem()
.transformToUni { value =>
try
val metadata = mapper.readValue(value, classOf[InstanceMetadata])
val isNew = !instances.containsKey(instanceId)
instances.put(instanceId, metadata)
if isNew then
log.infof("Instance %s joined registry (subscriptions=%d)", instanceId, metadata.subscriptionCount)
else
log.debugf(
"Instance %s updated (subscriptions=%d state=%s)",
instanceId,
metadata.subscriptionCount,
metadata.state,
)
Uni.createFrom().item(())
catch
case ex: Exception =>
log.warnf(ex, "Failed to parse instance metadata for %s", instanceId)
Uni.createFrom().item(())
}
.onFailure()
.recoverWithItem(())
def markInstanceDead(instanceId: String): Unit =
instances.computeIfPresent(instanceId, (_, inst) => inst.copy(state = "DEAD"))
()
log.infof("Instance %s marked dead", instanceId)
def removeInstance(instanceId: String): Unit =
instances.remove(instanceId)
()
log.infof("Instance %s removed from registry", instanceId)
def evictStaleInstances(maxAge: Duration): List[String] =
val cutoff = Instant.now().minus(maxAge)
val stale = instances.asScala
.collect { case (id, inst) =>
try
if Instant.parse(inst.lastHeartbeat).isBefore(cutoff) then Some(id)
else None
catch case _: Exception => None
}
.flatten
.toList
stale.foreach { id =>
instances.remove(id)
log.warnf("Evicted stale instance %s (heartbeat older than %s)", id, maxAge)
}
stale
+1 -1
View File
@@ -1,3 +1,3 @@
MAJOR=0
MINOR=3
MINOR=12
PATCH=0
+275
View File
@@ -567,3 +567,278 @@
* IO microservice ([#38](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/38)) ([a386f57](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/a386f57c21d34ead6cc6f92836c52b714597e289))
* update main class path in build configuration and adjust VCS directory mapping ([7b1f8b1](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/7b1f8b117623d327232a1a92a8a44d18582e0189))
* update move validation to check for king safety ([#13](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/13)) ([e5e20c5](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/e5e20c566e368b12ca1dc59680c34e9112bf6762))
## (2026-04-30)
### Features
* add GameRules stub with PositionStatus enum ([76d4168](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/76d4168038de23e5d6083d4e8f0504fbf31d15a3))
* add MovedInCheck/Checkmate/Stalemate MoveResult variants (stub dispatch) ([8b7ec57](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/8b7ec57e5ea6ee1615a1883848a426dc07d26364))
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* implement GameRules with isInCheck, legalMoves, gameStatus ([94a02ff](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/94a02ff6849436d9496c70a0f16c21666dae8e4e))
* implement legal castling ([#1](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/1)) ([00d326c](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/00d326c1ba67711fbe180f04e1100c3f01dd0254))
* NCS-10 Implement Pawn Promotion ([#12](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/12)) ([13bfc16](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/13bfc16cfe25db78ec607db523ca6d993c13430c))
* NCS-11 50-move rule ([#9](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/9)) ([412ed98](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/412ed986a95703a3b282276540153480ceed229d))
* NCS-13 Implement Threefold Repetition ([#31](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/31)) ([767d305](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/767d3051a76c266050b6335774d66e2db2273c16))
* NCS-14 implemented insufficient moves rule ([#30](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/30)) ([b0399a4](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b0399a4e489950083066c9538df9a84dcc7a4613))
* NCS-16 Core Separation via Patterns ([#10](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/10)) ([1361dfc](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/1361dfc89553b146864fb8ff3526cf12cf3f293a))
* NCS-17 Implement basic ScalaFX UI ([#14](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/14)) ([3ff8031](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3ff80318b4f16c59733a46498581a5c27f048287))
* NCS-21 Write Scripts to automate certain tasks ([#15](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/15)) ([8051871](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/80518719d536a087d339fe02530825dc07f8b388))
* NCS-25 Add linters to keep quality up ([#27](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/27)) ([fd4e67d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/fd4e67d4f782a7e955822d90cb909d0a81676fb2))
* NCS-37 Quarkus integration ([#35](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/35)) ([f088c4e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/f088c4e9ffcc498d3d1b6f01e8f50042d5830d55))
* NCS-40 Rework Draw System ([#34](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/34)) ([33e785d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/33e785d22af87724839b62ae91dfe74a05b398c3))
* NCS-41 Bot Platform ([#33](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/33)) ([8744bee](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/8744bee2dd20966dae90a09c21a43d5b06f59e00))
* NCS-53 changed IO to MicroService for easier scaling ([#37](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/37)) ([b5a2966](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b5a2966adafa9650f0f7d601bdeb8fdd13710327))
* NCS-6 Implementing FEN & PGN ([#7](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/7)) ([f28e69d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/f28e69dc181416aa2f221fdc4b45c2cda5efbf07))
* NCS-9 En passant implementation ([#8](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/8)) ([919beb3](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/919beb3b4bfa8caf2f90976a415fe9b19b7e9747))
* **rule:** Rules as a microservice ([#39](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/39)) ([093134d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/093134d36c6844ba02a36a28d5d044f09291cd1d))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
* wire check/checkmate/stalemate into processMove and gameLoop ([5264a22](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/5264a225418b885c5e6ea6411b96f85e38837f6c))
### Bug Fixes
* add missing kings to gameLoop capture test board ([aedd787](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/aedd787b77203c2af934751dba7b784eaf165032))
* correct test board positions and captureOutput/withInput interaction ([f0481e2](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/f0481e2561b779df00925b46ee281dc36a795150))
* IO microservice ([#38](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/38)) ([a386f57](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/a386f57c21d34ead6cc6f92836c52b714597e289))
* update main class path in build configuration and adjust VCS directory mapping ([7b1f8b1](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/7b1f8b117623d327232a1a92a8a44d18582e0189))
* update move validation to check for king safety ([#13](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/13)) ([e5e20c5](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/e5e20c566e368b12ca1dc59680c34e9112bf6762))
## (2026-05-01)
### Features
* add GameRules stub with PositionStatus enum ([76d4168](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/76d4168038de23e5d6083d4e8f0504fbf31d15a3))
* add MovedInCheck/Checkmate/Stalemate MoveResult variants (stub dispatch) ([8b7ec57](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/8b7ec57e5ea6ee1615a1883848a426dc07d26364))
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* implement GameRules with isInCheck, legalMoves, gameStatus ([94a02ff](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/94a02ff6849436d9496c70a0f16c21666dae8e4e))
* implement legal castling ([#1](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/1)) ([00d326c](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/00d326c1ba67711fbe180f04e1100c3f01dd0254))
* NCS-10 Implement Pawn Promotion ([#12](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/12)) ([13bfc16](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/13bfc16cfe25db78ec607db523ca6d993c13430c))
* NCS-11 50-move rule ([#9](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/9)) ([412ed98](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/412ed986a95703a3b282276540153480ceed229d))
* NCS-13 Implement Threefold Repetition ([#31](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/31)) ([767d305](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/767d3051a76c266050b6335774d66e2db2273c16))
* NCS-14 implemented insufficient moves rule ([#30](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/30)) ([b0399a4](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b0399a4e489950083066c9538df9a84dcc7a4613))
* NCS-16 Core Separation via Patterns ([#10](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/10)) ([1361dfc](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/1361dfc89553b146864fb8ff3526cf12cf3f293a))
* NCS-17 Implement basic ScalaFX UI ([#14](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/14)) ([3ff8031](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3ff80318b4f16c59733a46498581a5c27f048287))
* NCS-21 Write Scripts to automate certain tasks ([#15](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/15)) ([8051871](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/80518719d536a087d339fe02530825dc07f8b388))
* NCS-25 Add linters to keep quality up ([#27](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/27)) ([fd4e67d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/fd4e67d4f782a7e955822d90cb909d0a81676fb2))
* NCS-37 Quarkus integration ([#35](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/35)) ([f088c4e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/f088c4e9ffcc498d3d1b6f01e8f50042d5830d55))
* NCS-40 Rework Draw System ([#34](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/34)) ([33e785d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/33e785d22af87724839b62ae91dfe74a05b398c3))
* NCS-41 Bot Platform ([#33](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/33)) ([8744bee](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/8744bee2dd20966dae90a09c21a43d5b06f59e00))
* NCS-53 changed IO to MicroService for easier scaling ([#37](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/37)) ([b5a2966](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b5a2966adafa9650f0f7d601bdeb8fdd13710327))
* NCS-6 Implementing FEN & PGN ([#7](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/7)) ([f28e69d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/f28e69dc181416aa2f221fdc4b45c2cda5efbf07))
* NCS-9 En passant implementation ([#8](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/8)) ([919beb3](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/919beb3b4bfa8caf2f90976a415fe9b19b7e9747))
* **rule:** Rules as a microservice ([#39](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/39)) ([093134d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/093134d36c6844ba02a36a28d5d044f09291cd1d))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
* wire check/checkmate/stalemate into processMove and gameLoop ([5264a22](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/5264a225418b885c5e6ea6411b96f85e38837f6c))
### Bug Fixes
* add missing kings to gameLoop capture test board ([aedd787](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/aedd787b77203c2af934751dba7b784eaf165032))
* correct test board positions and captureOutput/withInput interaction ([f0481e2](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/f0481e2561b779df00925b46ee281dc36a795150))
* IO microservice ([#38](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/38)) ([a386f57](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/a386f57c21d34ead6cc6f92836c52b714597e289))
* update main class path in build configuration and adjust VCS directory mapping ([7b1f8b1](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/7b1f8b117623d327232a1a92a8a44d18582e0189))
* update move validation to check for king safety ([#13](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/13)) ([e5e20c5](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/e5e20c566e368b12ca1dc59680c34e9112bf6762))
## (2026-05-02)
### Features
* add GameRules stub with PositionStatus enum ([76d4168](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/76d4168038de23e5d6083d4e8f0504fbf31d15a3))
* add MovedInCheck/Checkmate/Stalemate MoveResult variants (stub dispatch) ([8b7ec57](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/8b7ec57e5ea6ee1615a1883848a426dc07d26364))
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* implement GameRules with isInCheck, legalMoves, gameStatus ([94a02ff](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/94a02ff6849436d9496c70a0f16c21666dae8e4e))
* implement legal castling ([#1](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/1)) ([00d326c](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/00d326c1ba67711fbe180f04e1100c3f01dd0254))
* **logging:** add DEBUG/INFO/WARN logging across services (NCS-72) ([#41](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/41)) ([804a4bf](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/804a4bf179e3dfb19e2be4390e7e543caf5237c6))
* NCS-10 Implement Pawn Promotion ([#12](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/12)) ([13bfc16](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/13bfc16cfe25db78ec607db523ca6d993c13430c))
* NCS-11 50-move rule ([#9](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/9)) ([412ed98](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/412ed986a95703a3b282276540153480ceed229d))
* NCS-13 Implement Threefold Repetition ([#31](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/31)) ([767d305](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/767d3051a76c266050b6335774d66e2db2273c16))
* NCS-14 implemented insufficient moves rule ([#30](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/30)) ([b0399a4](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b0399a4e489950083066c9538df9a84dcc7a4613))
* NCS-16 Core Separation via Patterns ([#10](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/10)) ([1361dfc](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/1361dfc89553b146864fb8ff3526cf12cf3f293a))
* NCS-17 Implement basic ScalaFX UI ([#14](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/14)) ([3ff8031](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3ff80318b4f16c59733a46498581a5c27f048287))
* NCS-21 Write Scripts to automate certain tasks ([#15](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/15)) ([8051871](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/80518719d536a087d339fe02530825dc07f8b388))
* NCS-25 Add linters to keep quality up ([#27](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/27)) ([fd4e67d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/fd4e67d4f782a7e955822d90cb909d0a81676fb2))
* NCS-37 Quarkus integration ([#35](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/35)) ([f088c4e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/f088c4e9ffcc498d3d1b6f01e8f50042d5830d55))
* NCS-40 Rework Draw System ([#34](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/34)) ([33e785d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/33e785d22af87724839b62ae91dfe74a05b398c3))
* NCS-41 Bot Platform ([#33](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/33)) ([8744bee](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/8744bee2dd20966dae90a09c21a43d5b06f59e00))
* NCS-53 changed IO to MicroService for easier scaling ([#37](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/37)) ([b5a2966](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b5a2966adafa9650f0f7d601bdeb8fdd13710327))
* NCS-6 Implementing FEN & PGN ([#7](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/7)) ([f28e69d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/f28e69dc181416aa2f221fdc4b45c2cda5efbf07))
* NCS-9 En passant implementation ([#8](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/8)) ([919beb3](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/919beb3b4bfa8caf2f90976a415fe9b19b7e9747))
* **rule:** Rules as a microservice ([#39](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/39)) ([093134d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/093134d36c6844ba02a36a28d5d044f09291cd1d))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
* wire check/checkmate/stalemate into processMove and gameLoop ([5264a22](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/5264a225418b885c5e6ea6411b96f85e38837f6c))
### Bug Fixes
* add missing kings to gameLoop capture test board ([aedd787](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/aedd787b77203c2af934751dba7b784eaf165032))
* correct test board positions and captureOutput/withInput interaction ([f0481e2](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/f0481e2561b779df00925b46ee281dc36a795150))
* IO microservice ([#38](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/38)) ([a386f57](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/a386f57c21d34ead6cc6f92836c52b714597e289))
* update main class path in build configuration and adjust VCS directory mapping ([7b1f8b1](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/7b1f8b117623d327232a1a92a8a44d18582e0189))
* update move validation to check for king safety ([#13](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/13)) ([e5e20c5](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/e5e20c566e368b12ca1dc59680c34e9112bf6762))
## (2026-05-02)
### Features
* add GameRules stub with PositionStatus enum ([76d4168](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/76d4168038de23e5d6083d4e8f0504fbf31d15a3))
* add MovedInCheck/Checkmate/Stalemate MoveResult variants (stub dispatch) ([8b7ec57](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/8b7ec57e5ea6ee1615a1883848a426dc07d26364))
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* implement GameRules with isInCheck, legalMoves, gameStatus ([94a02ff](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/94a02ff6849436d9496c70a0f16c21666dae8e4e))
* implement legal castling ([#1](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/1)) ([00d326c](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/00d326c1ba67711fbe180f04e1100c3f01dd0254))
* **logging:** add DEBUG/INFO/WARN logging across services (NCS-72) ([#41](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/41)) ([804a4bf](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/804a4bf179e3dfb19e2be4390e7e543caf5237c6))
* NCS-10 Implement Pawn Promotion ([#12](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/12)) ([13bfc16](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/13bfc16cfe25db78ec607db523ca6d993c13430c))
* NCS-11 50-move rule ([#9](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/9)) ([412ed98](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/412ed986a95703a3b282276540153480ceed229d))
* NCS-13 Implement Threefold Repetition ([#31](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/31)) ([767d305](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/767d3051a76c266050b6335774d66e2db2273c16))
* NCS-14 implemented insufficient moves rule ([#30](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/30)) ([b0399a4](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b0399a4e489950083066c9538df9a84dcc7a4613))
* NCS-16 Core Separation via Patterns ([#10](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/10)) ([1361dfc](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/1361dfc89553b146864fb8ff3526cf12cf3f293a))
* NCS-17 Implement basic ScalaFX UI ([#14](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/14)) ([3ff8031](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3ff80318b4f16c59733a46498581a5c27f048287))
* NCS-21 Write Scripts to automate certain tasks ([#15](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/15)) ([8051871](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/80518719d536a087d339fe02530825dc07f8b388))
* NCS-25 Add linters to keep quality up ([#27](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/27)) ([fd4e67d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/fd4e67d4f782a7e955822d90cb909d0a81676fb2))
* NCS-37 Quarkus integration ([#35](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/35)) ([f088c4e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/f088c4e9ffcc498d3d1b6f01e8f50042d5830d55))
* NCS-40 Rework Draw System ([#34](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/34)) ([33e785d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/33e785d22af87724839b62ae91dfe74a05b398c3))
* NCS-41 Bot Platform ([#33](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/33)) ([8744bee](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/8744bee2dd20966dae90a09c21a43d5b06f59e00))
* NCS-53 changed IO to MicroService for easier scaling ([#37](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/37)) ([b5a2966](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b5a2966adafa9650f0f7d601bdeb8fdd13710327))
* NCS-6 Implementing FEN & PGN ([#7](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/7)) ([f28e69d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/f28e69dc181416aa2f221fdc4b45c2cda5efbf07))
* NCS-9 En passant implementation ([#8](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/8)) ([919beb3](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/919beb3b4bfa8caf2f90976a415fe9b19b7e9747))
* **rule:** Rules as a microservice ([#39](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/39)) ([093134d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/093134d36c6844ba02a36a28d5d044f09291cd1d))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
* wire check/checkmate/stalemate into processMove and gameLoop ([5264a22](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/5264a225418b885c5e6ea6411b96f85e38837f6c))
### Bug Fixes
* add missing kings to gameLoop capture test board ([aedd787](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/aedd787b77203c2af934751dba7b784eaf165032))
* correct test board positions and captureOutput/withInput interaction ([f0481e2](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/f0481e2561b779df00925b46ee281dc36a795150))
* **heartbeat:** inject ObjectMapper into InstanceHeartbeatService ([#42](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/42)) ([0c98151](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/0c981517da1f94cd10ae396e47bde2b35d0b3ba0))
* IO microservice ([#38](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/38)) ([a386f57](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/a386f57c21d34ead6cc6f92836c52b714597e289))
* update main class path in build configuration and adjust VCS directory mapping ([7b1f8b1](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/7b1f8b117623d327232a1a92a8a44d18582e0189))
* update move validation to check for king safety ([#13](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/13)) ([e5e20c5](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/e5e20c566e368b12ca1dc59680c34e9112bf6762))
## (2026-05-05)
### Features
* add GameRules stub with PositionStatus enum ([76d4168](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/76d4168038de23e5d6083d4e8f0504fbf31d15a3))
* add MovedInCheck/Checkmate/Stalemate MoveResult variants (stub dispatch) ([8b7ec57](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/8b7ec57e5ea6ee1615a1883848a426dc07d26364))
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* implement GameRules with isInCheck, legalMoves, gameStatus ([94a02ff](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/94a02ff6849436d9496c70a0f16c21666dae8e4e))
* implement legal castling ([#1](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/1)) ([00d326c](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/00d326c1ba67711fbe180f04e1100c3f01dd0254))
* **logging:** add DEBUG/INFO/WARN logging across services (NCS-72) ([#41](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/41)) ([804a4bf](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/804a4bf179e3dfb19e2be4390e7e543caf5237c6))
* NCS-10 Implement Pawn Promotion ([#12](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/12)) ([13bfc16](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/13bfc16cfe25db78ec607db523ca6d993c13430c))
* NCS-11 50-move rule ([#9](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/9)) ([412ed98](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/412ed986a95703a3b282276540153480ceed229d))
* NCS-13 Implement Threefold Repetition ([#31](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/31)) ([767d305](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/767d3051a76c266050b6335774d66e2db2273c16))
* NCS-14 implemented insufficient moves rule ([#30](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/30)) ([b0399a4](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b0399a4e489950083066c9538df9a84dcc7a4613))
* NCS-16 Core Separation via Patterns ([#10](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/10)) ([1361dfc](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/1361dfc89553b146864fb8ff3526cf12cf3f293a))
* NCS-17 Implement basic ScalaFX UI ([#14](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/14)) ([3ff8031](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3ff80318b4f16c59733a46498581a5c27f048287))
* NCS-21 Write Scripts to automate certain tasks ([#15](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/15)) ([8051871](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/80518719d536a087d339fe02530825dc07f8b388))
* NCS-25 Add linters to keep quality up ([#27](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/27)) ([fd4e67d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/fd4e67d4f782a7e955822d90cb909d0a81676fb2))
* NCS-37 Quarkus integration ([#35](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/35)) ([f088c4e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/f088c4e9ffcc498d3d1b6f01e8f50042d5830d55))
* NCS-40 Rework Draw System ([#34](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/34)) ([33e785d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/33e785d22af87724839b62ae91dfe74a05b398c3))
* NCS-41 Bot Platform ([#33](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/33)) ([8744bee](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/8744bee2dd20966dae90a09c21a43d5b06f59e00))
* NCS-53 changed IO to MicroService for easier scaling ([#37](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/37)) ([b5a2966](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b5a2966adafa9650f0f7d601bdeb8fdd13710327))
* NCS-6 Implementing FEN & PGN ([#7](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/7)) ([f28e69d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/f28e69dc181416aa2f221fdc4b45c2cda5efbf07))
* NCS-9 En passant implementation ([#8](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/8)) ([919beb3](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/919beb3b4bfa8caf2f90976a415fe9b19b7e9747))
* **rule:** Rules as a microservice ([#39](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/39)) ([093134d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/093134d36c6844ba02a36a28d5d044f09291cd1d))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
* wire check/checkmate/stalemate into processMove and gameLoop ([5264a22](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/5264a225418b885c5e6ea6411b96f85e38837f6c))
### Bug Fixes
* add missing kings to gameLoop capture test board ([aedd787](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/aedd787b77203c2af934751dba7b784eaf165032))
* **auth:** change InternalAuthFilter to use @Singleton and add HTTP tests for secret validation ([c08d530](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/c08d5303eb9e70d36c8eebf6a061ccb71e118fe5))
* **auth:** update InternalAuthFilter to use @ApplicationScoped and add index-dependency configuration ([6e0fd95](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6e0fd9523e001756ce7109e639ebb54be4fcdabf))
* correct test board positions and captureOutput/withInput interaction ([f0481e2](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/f0481e2561b779df00925b46ee281dc36a795150))
* **heartbeat:** inject ObjectMapper into InstanceHeartbeatService ([#42](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/42)) ([0c98151](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/0c981517da1f94cd10ae396e47bde2b35d0b3ba0))
* IO microservice ([#38](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/38)) ([a386f57](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/a386f57c21d34ead6cc6f92836c52b714597e289))
* Lints ([dc224ab](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/dc224abe26acf5361c56956006e1cc51b75b0b7e))
* **redis:** add max pool wait time and switch to ReactiveRedisDataSource for heartbeat updates ([33e5017](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/33e5017f51a998327b180f778f73964cc10c05d3))
* **redis:** prevent concurrent Redis heartbeat refreshes using AtomicBoolean ([847b132](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/847b13202cb909d18ca3304c27ebe17ce2312b8e))
* **redis:** simplify refreshRedisHeartbeat logic and ensure proper error handling ([1813ea1](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/1813ea1d2d5d093f7925f87371b5e29820bf1136))
* update main class path in build configuration and adjust VCS directory mapping ([7b1f8b1](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/7b1f8b117623d327232a1a92a8a44d18582e0189))
* update move validation to check for king safety ([#13](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/13)) ([e5e20c5](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/e5e20c566e368b12ca1dc59680c34e9112bf6762))
## (2026-05-05)
### Features
* add GameRules stub with PositionStatus enum ([76d4168](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/76d4168038de23e5d6083d4e8f0504fbf31d15a3))
* add MovedInCheck/Checkmate/Stalemate MoveResult variants (stub dispatch) ([8b7ec57](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/8b7ec57e5ea6ee1615a1883848a426dc07d26364))
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* implement GameRules with isInCheck, legalMoves, gameStatus ([94a02ff](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/94a02ff6849436d9496c70a0f16c21666dae8e4e))
* implement legal castling ([#1](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/1)) ([00d326c](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/00d326c1ba67711fbe180f04e1100c3f01dd0254))
* **logging:** add DEBUG/INFO/WARN logging across services (NCS-72) ([#41](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/41)) ([804a4bf](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/804a4bf179e3dfb19e2be4390e7e543caf5237c6))
* NCS-10 Implement Pawn Promotion ([#12](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/12)) ([13bfc16](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/13bfc16cfe25db78ec607db523ca6d993c13430c))
* NCS-11 50-move rule ([#9](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/9)) ([412ed98](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/412ed986a95703a3b282276540153480ceed229d))
* NCS-13 Implement Threefold Repetition ([#31](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/31)) ([767d305](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/767d3051a76c266050b6335774d66e2db2273c16))
* NCS-14 implemented insufficient moves rule ([#30](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/30)) ([b0399a4](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b0399a4e489950083066c9538df9a84dcc7a4613))
* NCS-16 Core Separation via Patterns ([#10](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/10)) ([1361dfc](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/1361dfc89553b146864fb8ff3526cf12cf3f293a))
* NCS-17 Implement basic ScalaFX UI ([#14](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/14)) ([3ff8031](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3ff80318b4f16c59733a46498581a5c27f048287))
* NCS-21 Write Scripts to automate certain tasks ([#15](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/15)) ([8051871](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/80518719d536a087d339fe02530825dc07f8b388))
* NCS-25 Add linters to keep quality up ([#27](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/27)) ([fd4e67d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/fd4e67d4f782a7e955822d90cb909d0a81676fb2))
* NCS-37 Quarkus integration ([#35](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/35)) ([f088c4e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/f088c4e9ffcc498d3d1b6f01e8f50042d5830d55))
* NCS-40 Rework Draw System ([#34](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/34)) ([33e785d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/33e785d22af87724839b62ae91dfe74a05b398c3))
* NCS-41 Bot Platform ([#33](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/33)) ([8744bee](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/8744bee2dd20966dae90a09c21a43d5b06f59e00))
* NCS-53 changed IO to MicroService for easier scaling ([#37](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/37)) ([b5a2966](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b5a2966adafa9650f0f7d601bdeb8fdd13710327))
* NCS-6 Implementing FEN & PGN ([#7](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/7)) ([f28e69d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/f28e69dc181416aa2f221fdc4b45c2cda5efbf07))
* NCS-9 En passant implementation ([#8](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/8)) ([919beb3](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/919beb3b4bfa8caf2f90976a415fe9b19b7e9747))
* **rule:** Rules as a microservice ([#39](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/39)) ([093134d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/093134d36c6844ba02a36a28d5d044f09291cd1d))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
* wire check/checkmate/stalemate into processMove and gameLoop ([5264a22](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/5264a225418b885c5e6ea6411b96f85e38837f6c))
### Bug Fixes
* add missing kings to gameLoop capture test board ([aedd787](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/aedd787b77203c2af934751dba7b784eaf165032))
* **auth:** change InternalAuthFilter to use @Singleton and add HTTP tests for secret validation ([c08d530](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/c08d5303eb9e70d36c8eebf6a061ccb71e118fe5))
* **auth:** update InternalAuthFilter to use @ApplicationScoped and add index-dependency configuration ([6e0fd95](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6e0fd9523e001756ce7109e639ebb54be4fcdabf))
* correct test board positions and captureOutput/withInput interaction ([f0481e2](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/f0481e2561b779df00925b46ee281dc36a795150))
* **heartbeat:** inject ObjectMapper into InstanceHeartbeatService ([#42](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/42)) ([0c98151](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/0c981517da1f94cd10ae396e47bde2b35d0b3ba0))
* IO microservice ([#38](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/38)) ([a386f57](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/a386f57c21d34ead6cc6f92836c52b714597e289))
* Lints ([dc224ab](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/dc224abe26acf5361c56956006e1cc51b75b0b7e))
* **redis:** add max pool wait time and switch to ReactiveRedisDataSource for heartbeat updates ([33e5017](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/33e5017f51a998327b180f778f73964cc10c05d3))
* **redis:** prevent concurrent Redis heartbeat refreshes using AtomicBoolean ([847b132](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/847b13202cb909d18ca3304c27ebe17ce2312b8e))
* **redis:** simplify refreshRedisHeartbeat logic and ensure proper error handling ([1813ea1](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/1813ea1d2d5d093f7925f87371b5e29820bf1136))
* **redis:** update Redis configuration with max pool size and waiting parameters ([5baf6a7](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/5baf6a7cdbea484fc49c02e2b5a1c3919b7fa2c4))
* update main class path in build configuration and adjust VCS directory mapping ([7b1f8b1](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/7b1f8b117623d327232a1a92a8a44d18582e0189))
* update move validation to check for king safety ([#13](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/13)) ([e5e20c5](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/e5e20c566e368b12ca1dc59680c34e9112bf6762))
## (2026-05-06)
### Features
* add GameRules stub with PositionStatus enum ([76d4168](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/76d4168038de23e5d6083d4e8f0504fbf31d15a3))
* add MovedInCheck/Checkmate/Stalemate MoveResult variants (stub dispatch) ([8b7ec57](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/8b7ec57e5ea6ee1615a1883848a426dc07d26364))
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* implement GameRules with isInCheck, legalMoves, gameStatus ([94a02ff](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/94a02ff6849436d9496c70a0f16c21666dae8e4e))
* implement legal castling ([#1](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/1)) ([00d326c](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/00d326c1ba67711fbe180f04e1100c3f01dd0254))
* **logging:** add DEBUG/INFO/WARN logging across services (NCS-72) ([#41](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/41)) ([804a4bf](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/804a4bf179e3dfb19e2be4390e7e543caf5237c6))
* NCS-10 Implement Pawn Promotion ([#12](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/12)) ([13bfc16](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/13bfc16cfe25db78ec607db523ca6d993c13430c))
* NCS-11 50-move rule ([#9](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/9)) ([412ed98](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/412ed986a95703a3b282276540153480ceed229d))
* NCS-13 Implement Threefold Repetition ([#31](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/31)) ([767d305](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/767d3051a76c266050b6335774d66e2db2273c16))
* NCS-14 implemented insufficient moves rule ([#30](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/30)) ([b0399a4](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b0399a4e489950083066c9538df9a84dcc7a4613))
* NCS-16 Core Separation via Patterns ([#10](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/10)) ([1361dfc](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/1361dfc89553b146864fb8ff3526cf12cf3f293a))
* NCS-17 Implement basic ScalaFX UI ([#14](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/14)) ([3ff8031](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3ff80318b4f16c59733a46498581a5c27f048287))
* NCS-21 Write Scripts to automate certain tasks ([#15](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/15)) ([8051871](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/80518719d536a087d339fe02530825dc07f8b388))
* NCS-25 Add linters to keep quality up ([#27](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/27)) ([fd4e67d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/fd4e67d4f782a7e955822d90cb909d0a81676fb2))
* NCS-37 Quarkus integration ([#35](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/35)) ([f088c4e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/f088c4e9ffcc498d3d1b6f01e8f50042d5830d55))
* NCS-40 Rework Draw System ([#34](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/34)) ([33e785d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/33e785d22af87724839b62ae91dfe74a05b398c3))
* NCS-41 Bot Platform ([#33](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/33)) ([8744bee](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/8744bee2dd20966dae90a09c21a43d5b06f59e00))
* NCS-53 changed IO to MicroService for easier scaling ([#37](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/37)) ([b5a2966](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b5a2966adafa9650f0f7d601bdeb8fdd13710327))
* NCS-6 Implementing FEN & PGN ([#7](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/7)) ([f28e69d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/f28e69dc181416aa2f221fdc4b45c2cda5efbf07))
* NCS-9 En passant implementation ([#8](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/8)) ([919beb3](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/919beb3b4bfa8caf2f90976a415fe9b19b7e9747))
* **rule:** Rules as a microservice ([#39](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/39)) ([093134d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/093134d36c6844ba02a36a28d5d044f09291cd1d))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
* wire check/checkmate/stalemate into processMove and gameLoop ([5264a22](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/5264a225418b885c5e6ea6411b96f85e38837f6c))
### Bug Fixes
* add missing kings to gameLoop capture test board ([aedd787](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/aedd787b77203c2af934751dba7b784eaf165032))
* **auth:** change InternalAuthFilter to use @Singleton and add HTTP tests for secret validation ([c08d530](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/c08d5303eb9e70d36c8eebf6a061ccb71e118fe5))
* **auth:** update InternalAuthFilter to use @ApplicationScoped and add index-dependency configuration ([6e0fd95](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6e0fd9523e001756ce7109e639ebb54be4fcdabf))
* correct test board positions and captureOutput/withInput interaction ([f0481e2](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/f0481e2561b779df00925b46ee281dc36a795150))
* **heartbeat:** inject ObjectMapper into InstanceHeartbeatService ([#42](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/42)) ([0c98151](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/0c981517da1f94cd10ae396e47bde2b35d0b3ba0))
* IO microservice ([#38](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/38)) ([a386f57](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/a386f57c21d34ead6cc6f92836c52b714597e289))
* Lints ([dc224ab](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/dc224abe26acf5361c56956006e1cc51b75b0b7e))
* **redis:** add max pool wait time and switch to ReactiveRedisDataSource for heartbeat updates ([33e5017](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/33e5017f51a998327b180f778f73964cc10c05d3))
* **redis:** enhance GameRedisSubscriberManager to use ReactiveRedisDataSource and improve subscription handling ([0eb752d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/0eb752d4935377f75aab710b7f4eda4b29098e6a))
* **redis:** prevent concurrent Redis heartbeat refreshes using AtomicBoolean ([847b132](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/847b13202cb909d18ca3304c27ebe17ce2312b8e))
* **redis:** simplify refreshRedisHeartbeat logic and ensure proper error handling ([1813ea1](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/1813ea1d2d5d093f7925f87371b5e29820bf1136))
* **redis:** update Redis configuration with max pool size and waiting parameters ([5baf6a7](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/5baf6a7cdbea484fc49c02e2b5a1c3919b7fa2c4))
* update main class path in build configuration and adjust VCS directory mapping ([7b1f8b1](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/7b1f8b117623d327232a1a92a8a44d18582e0189))
* update move validation to check for king safety ([#13](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/13)) ([e5e20c5](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/e5e20c566e368b12ca1dc59680c34e9112bf6762))
@@ -3,8 +3,15 @@ quarkus:
port: 8080
application:
name: nowchess-core
index-dependency:
security:
group-id: de.nowchess
artifact-id: security
redis:
hosts: redis://${REDIS_HOST:localhost}:${REDIS_PORT:6379}
max-pool-wait-time: 30s
max-pool-size: 64
max-pool-waiting: 128
grpc:
clients:
rule-grpc:
@@ -7,11 +7,15 @@ import scala.compiletime.uninitialized
import de.nowchess.coordinator.proto.{CoordinatorServiceGrpc, *}
import de.nowchess.chess.redis.GameRedisSubscriberManager
import io.grpc.stub.StreamObserver
import org.jboss.logging.Logger
import scala.jdk.CollectionConverters.*
@GrpcService
@Singleton
class CoordinatorServiceHandler extends CoordinatorServiceGrpc.CoordinatorServiceImplBase:
private val log = Logger.getLogger(classOf[CoordinatorServiceHandler])
// scalafix:off DisableSyntax.var
@Inject
private var gameSubscriberManager: GameRedisSubscriberManager = uninitialized
@@ -22,6 +26,7 @@ class CoordinatorServiceHandler extends CoordinatorServiceGrpc.CoordinatorServic
responseObserver: StreamObserver[BatchResubscribeResponse],
): Unit =
val count = gameSubscriberManager.batchResubscribeGames(request.getGameIdsList)
log.infof("Coordinator: batch resubscribe %d games → subscribed %d", request.getGameIdsList.size(), count)
val response = BatchResubscribeResponse
.newBuilder()
.setSubscribedCount(count)
@@ -34,6 +39,7 @@ class CoordinatorServiceHandler extends CoordinatorServiceGrpc.CoordinatorServic
responseObserver: StreamObserver[UnsubscribeGamesResponse],
): Unit =
val count = gameSubscriberManager.unsubscribeGames(request.getGameIdsList)
log.infof("Coordinator: unsubscribe %d games → unsubscribed %d", request.getGameIdsList.size(), count)
val response = UnsubscribeGamesResponse
.newBuilder()
.setUnsubscribedCount(count)
@@ -46,6 +52,7 @@ class CoordinatorServiceHandler extends CoordinatorServiceGrpc.CoordinatorServic
responseObserver: StreamObserver[EvictGamesResponse],
): Unit =
val count = gameSubscriberManager.evictGames(request.getGameIdsList)
log.infof("Coordinator: evict %d games → evicted %d", request.getGameIdsList.size(), count)
val response = EvictGamesResponse
.newBuilder()
.setEvictedCount(count)
@@ -58,6 +65,7 @@ class CoordinatorServiceHandler extends CoordinatorServiceGrpc.CoordinatorServic
responseObserver: StreamObserver[DrainInstanceResponse],
): Unit =
val migrated = gameSubscriberManager.drainInstance()
log.infof("Coordinator: drain instance → migrated %d games", migrated)
val response = DrainInstanceResponse
.newBuilder()
.setGamesMigrated(migrated)
@@ -5,29 +5,63 @@ import de.nowchess.chess.client.CombinedExportResponse
import de.nowchess.core.proto.*
import io.quarkus.grpc.GrpcClient
import jakarta.enterprise.context.ApplicationScoped
import org.jboss.logging.Logger
import scala.compiletime.uninitialized
@ApplicationScoped
class IoGrpcClientWrapper:
private val log = Logger.getLogger(classOf[IoGrpcClientWrapper])
// scalafix:off DisableSyntax.var
@GrpcClient("io-grpc")
var stub: IoServiceGrpc.IoServiceBlockingStub = uninitialized
// scalafix:on DisableSyntax.var
def exportCombined(ctx: GameContext): CombinedExportResponse =
val combined = stub.exportCombined(CoreProtoMapper.toProtoGameContext(ctx))
CombinedExportResponse(combined.getFen, combined.getPgn)
try
val combined = stub.exportCombined(CoreProtoMapper.toProtoGameContext(ctx))
CombinedExportResponse(combined.getFen, combined.getPgn)
catch
case ex: Exception =>
log.warnf(ex, "IO gRPC exportCombined failed")
// scalafix:off DisableSyntax.throw
throw ex
// scalafix:on DisableSyntax.throw
def importFen(fen: String): GameContext =
CoreProtoMapper.fromProtoGameContext(stub.importFen(ProtoImportFenRequest.newBuilder().setFen(fen).build()))
try CoreProtoMapper.fromProtoGameContext(stub.importFen(ProtoImportFenRequest.newBuilder().setFen(fen).build()))
catch
case ex: Exception =>
log.warnf(ex, "IO gRPC importFen failed for fen %s", fen)
// scalafix:off DisableSyntax.throw
throw ex
// scalafix:on DisableSyntax.throw
def importPgn(pgn: String): GameContext =
CoreProtoMapper.fromProtoGameContext(stub.importPgn(ProtoImportPgnRequest.newBuilder().setPgn(pgn).build()))
try CoreProtoMapper.fromProtoGameContext(stub.importPgn(ProtoImportPgnRequest.newBuilder().setPgn(pgn).build()))
catch
case ex: Exception =>
log.warnf(ex, "IO gRPC importPgn failed")
// scalafix:off DisableSyntax.throw
throw ex
// scalafix:on DisableSyntax.throw
def exportFen(ctx: GameContext): String =
stub.exportFen(CoreProtoMapper.toProtoGameContext(ctx)).getValue
try stub.exportFen(CoreProtoMapper.toProtoGameContext(ctx)).getValue
catch
case ex: Exception =>
log.warnf(ex, "IO gRPC exportFen failed")
// scalafix:off DisableSyntax.throw
throw ex
// scalafix:on DisableSyntax.throw
def exportPgn(ctx: GameContext): String =
stub.exportPgn(CoreProtoMapper.toProtoGameContext(ctx)).getValue
try stub.exportPgn(CoreProtoMapper.toProtoGameContext(ctx)).getValue
catch
case ex: Exception =>
log.warnf(ex, "IO gRPC exportPgn failed")
// scalafix:off DisableSyntax.throw
throw ex
// scalafix:on DisableSyntax.throw
@@ -7,6 +7,7 @@ import de.nowchess.api.rules.{PostMoveStatus, RuleSet}
import de.nowchess.core.proto.*
import io.quarkus.grpc.GrpcClient
import jakarta.enterprise.context.ApplicationScoped
import org.jboss.logging.Logger
import scala.compiletime.uninitialized
import scala.jdk.CollectionConverters.*
@@ -14,28 +15,59 @@ import scala.jdk.CollectionConverters.*
@ApplicationScoped
class RuleSetGrpcAdapter extends RuleSet:
private val log = Logger.getLogger(classOf[RuleSetGrpcAdapter])
// scalafix:off DisableSyntax.var
@GrpcClient("rule-grpc")
var stub: RuleServiceGrpc.RuleServiceBlockingStub = uninitialized
// scalafix:on DisableSyntax.var
def candidateMoves(ctx: GameContext)(sq: Square): List[Move] =
val req =
ProtoSquareRequest.newBuilder().setContext(CoreProtoMapper.toProtoGameContext(ctx)).setSquare(sq.toString).build()
stub.candidateMoves(req).getMovesList.asScala.flatMap(CoreProtoMapper.fromProtoMove).toList
try
val req =
ProtoSquareRequest
.newBuilder()
.setContext(CoreProtoMapper.toProtoGameContext(ctx))
.setSquare(sq.toString)
.build()
stub.candidateMoves(req).getMovesList.asScala.flatMap(CoreProtoMapper.fromProtoMove).toList
catch
case ex: Exception =>
log.warnf(ex, "Rule gRPC candidateMoves failed")
// scalafix:off DisableSyntax.throw
throw ex
// scalafix:on DisableSyntax.throw
def legalMoves(ctx: GameContext)(sq: Square): List[Move] =
val req =
ProtoSquareRequest.newBuilder().setContext(CoreProtoMapper.toProtoGameContext(ctx)).setSquare(sq.toString).build()
stub.legalMoves(req).getMovesList.asScala.flatMap(CoreProtoMapper.fromProtoMove).toList
try
val req =
ProtoSquareRequest
.newBuilder()
.setContext(CoreProtoMapper.toProtoGameContext(ctx))
.setSquare(sq.toString)
.build()
stub.legalMoves(req).getMovesList.asScala.flatMap(CoreProtoMapper.fromProtoMove).toList
catch
case ex: Exception =>
log.warnf(ex, "Rule gRPC legalMoves failed")
// scalafix:off DisableSyntax.throw
throw ex
// scalafix:on DisableSyntax.throw
def allLegalMoves(ctx: GameContext): List[Move] =
stub
.allLegalMoves(CoreProtoMapper.toProtoGameContext(ctx))
.getMovesList
.asScala
.flatMap(CoreProtoMapper.fromProtoMove)
.toList
try
stub
.allLegalMoves(CoreProtoMapper.toProtoGameContext(ctx))
.getMovesList
.asScala
.flatMap(CoreProtoMapper.fromProtoMove)
.toList
catch
case ex: Exception =>
log.warnf(ex, "Rule gRPC allLegalMoves failed")
// scalafix:off DisableSyntax.throw
throw ex
// scalafix:on DisableSyntax.throw
def isCheck(ctx: GameContext): Boolean =
stub.isCheck(CoreProtoMapper.toProtoGameContext(ctx)).getValue
@@ -56,19 +88,33 @@ class RuleSetGrpcAdapter extends RuleSet:
stub.isThreefoldRepetition(CoreProtoMapper.toProtoGameContext(ctx)).getValue
def applyMove(ctx: GameContext)(move: Move): GameContext =
val req = ProtoMoveRequest
.newBuilder()
.setContext(CoreProtoMapper.toProtoGameContext(ctx))
.setMove(CoreProtoMapper.toProtoMove(move))
.build()
CoreProtoMapper.fromProtoGameContext(stub.applyMove(req))
try
val req = ProtoMoveRequest
.newBuilder()
.setContext(CoreProtoMapper.toProtoGameContext(ctx))
.setMove(CoreProtoMapper.toProtoMove(move))
.build()
CoreProtoMapper.fromProtoGameContext(stub.applyMove(req))
catch
case ex: Exception =>
log.warnf(ex, "Rule gRPC applyMove failed")
// scalafix:off DisableSyntax.throw
throw ex
// scalafix:on DisableSyntax.throw
override def postMoveStatus(ctx: GameContext): PostMoveStatus =
val p = stub.postMoveStatus(CoreProtoMapper.toProtoGameContext(ctx))
PostMoveStatus(
p.getIsCheckmate,
p.getIsStalemate,
p.getIsInsufficientMaterial,
p.getIsCheck,
p.getIsThreefoldRepetition,
)
try
val p = stub.postMoveStatus(CoreProtoMapper.toProtoGameContext(ctx))
PostMoveStatus(
p.getIsCheckmate,
p.getIsStalemate,
p.getIsInsufficientMaterial,
p.getIsCheck,
p.getIsThreefoldRepetition,
)
catch
case ex: Exception =>
log.warnf(ex, "Rule gRPC postMoveStatus failed")
// scalafix:off DisableSyntax.throw
throw ex
// scalafix:on DisableSyntax.throw
@@ -10,6 +10,10 @@ import de.nowchess.chess.observer.{GameEvent, Observer}
import de.nowchess.chess.registry.GameRegistry
import de.nowchess.chess.resource.GameDtoMapper
import io.quarkus.redis.datasource.RedisDataSource
import org.jboss.logging.Logger
object GameRedisPublisher:
private val log = Logger.getLogger(classOf[GameRedisPublisher])
class GameRedisPublisher(
gameId: String,
@@ -23,57 +27,60 @@ class GameRedisPublisher(
) extends Observer:
def onGameEvent(event: GameEvent): Unit =
registry.get(gameId).foreach { entry =>
val dto = GameDtoMapper.toGameStateDto(entry, ioClient)
val json = objectMapper.writeValueAsString(GameStateEventDto(dto))
redis.pubsub(classOf[String]).publish(s2cTopicName, json)
try
GameRedisPublisher.log.debugf("Publishing game event for game %s", gameId)
registry.get(gameId).foreach { entry =>
val dto = GameDtoMapper.toGameStateDto(entry, ioClient)
val json = objectMapper.writeValueAsString(GameStateEventDto(dto))
redis.pubsub(classOf[String]).publish(s2cTopicName, json)
val clock = entry.engine.currentClockState
val wb = GameWritebackEventDto(
gameId = gameId,
fen = dto.fen,
pgn = dto.pgn,
moveCount = entry.engine.context.moves.size,
whiteId = entry.white.id.value,
whiteName = entry.white.displayName,
blackId = entry.black.id.value,
blackName = entry.black.displayName,
mode = entry.mode.toString,
resigned = entry.resigned,
limitSeconds = entry.engine.timeControl match {
case de.nowchess.api.game.TimeControl.Clock(l, _) => Some(l); case _ => None
},
incrementSeconds = entry.engine.timeControl match {
case de.nowchess.api.game.TimeControl.Clock(_, i) => Some(i); case _ => None
},
daysPerMove = entry.engine.timeControl match {
case de.nowchess.api.game.TimeControl.Correspondence(d) => Some(d); case _ => None
},
whiteRemainingMs = clock.collect { case c: LiveClockState => c.whiteRemainingMs },
blackRemainingMs = clock.collect { case c: LiveClockState => c.blackRemainingMs },
incrementMs = clock.collect { case c: LiveClockState => c.incrementMs },
clockLastTickAt = clock.collect { case c: LiveClockState => c.lastTickAt.toEpochMilli },
clockMoveDeadline = clock.collect { case c: CorrespondenceClockState => c.moveDeadline.toEpochMilli },
clockActiveColor = clock.map(_.activeColor.label.toLowerCase),
pendingDrawOffer = entry.engine.pendingDrawOfferBy.map(_.label.toLowerCase),
result = entry.engine.context.result.map {
case GameResult.Win(Color.White, _) => "white"
case GameResult.Win(Color.Black, _) => "black"
case GameResult.Draw(_) => "draw"
},
terminationReason = entry.engine.context.result.map {
case GameResult.Win(_, WinReason.Checkmate) => "checkmate"
case GameResult.Win(_, WinReason.Resignation) => "resignation"
case GameResult.Win(_, WinReason.TimeControl) => "timeout"
case GameResult.Draw(DrawReason.Stalemate) => "stalemate"
case GameResult.Draw(DrawReason.InsufficientMaterial) => "insufficient_material"
case GameResult.Draw(DrawReason.FiftyMoveRule) => "fifty_move"
case GameResult.Draw(DrawReason.ThreefoldRepetition) => "repetition"
case GameResult.Draw(DrawReason.Agreement) => "agreement"
},
redoStack = entry.engine.redoStackMoves.map(GameDtoMapper.moveToUci),
pendingTakebackRequest = entry.engine.pendingTakebackRequestBy.map(_.label.toLowerCase),
)
writebackEmit(objectMapper.writeValueAsString(wb))
if entry.engine.context.result.isDefined then onGameOver(gameId)
}
val clock = entry.engine.currentClockState
val wb = GameWritebackEventDto(
gameId = gameId,
fen = dto.fen,
pgn = dto.pgn,
moveCount = entry.engine.context.moves.size,
whiteId = entry.white.id.value,
whiteName = entry.white.displayName,
blackId = entry.black.id.value,
blackName = entry.black.displayName,
mode = entry.mode.toString,
resigned = entry.resigned,
limitSeconds = entry.engine.timeControl match {
case de.nowchess.api.game.TimeControl.Clock(l, _) => Some(l); case _ => None
},
incrementSeconds = entry.engine.timeControl match {
case de.nowchess.api.game.TimeControl.Clock(_, i) => Some(i); case _ => None
},
daysPerMove = entry.engine.timeControl match {
case de.nowchess.api.game.TimeControl.Correspondence(d) => Some(d); case _ => None
},
whiteRemainingMs = clock.collect { case c: LiveClockState => c.whiteRemainingMs },
blackRemainingMs = clock.collect { case c: LiveClockState => c.blackRemainingMs },
incrementMs = clock.collect { case c: LiveClockState => c.incrementMs },
clockLastTickAt = clock.collect { case c: LiveClockState => c.lastTickAt.toEpochMilli },
clockMoveDeadline = clock.collect { case c: CorrespondenceClockState => c.moveDeadline.toEpochMilli },
clockActiveColor = clock.map(_.activeColor.label.toLowerCase),
pendingDrawOffer = entry.engine.pendingDrawOfferBy.map(_.label.toLowerCase),
result = entry.engine.context.result.map {
case GameResult.Win(Color.White, _) => "white"
case GameResult.Win(Color.Black, _) => "black"
case GameResult.Draw(_) => "draw"
},
terminationReason = entry.engine.context.result.map {
case GameResult.Win(_, WinReason.Checkmate) => "checkmate"
case GameResult.Win(_, WinReason.Resignation) => "resignation"
case GameResult.Win(_, WinReason.TimeControl) => "timeout"
case GameResult.Draw(DrawReason.Stalemate) => "stalemate"
case GameResult.Draw(DrawReason.InsufficientMaterial) => "insufficient_material"
case GameResult.Draw(DrawReason.FiftyMoveRule) => "fifty_move"
case GameResult.Draw(DrawReason.ThreefoldRepetition) => "repetition"
case GameResult.Draw(DrawReason.Agreement) => "agreement"
},
redoStack = entry.engine.redoStackMoves.map(GameDtoMapper.moveToUci),
pendingTakebackRequest = entry.engine.pendingTakebackRequestBy.map(_.label.toLowerCase),
)
writebackEmit(objectMapper.writeValueAsString(wb))
if entry.engine.context.result.isDefined then onGameOver(gameId)
}
catch case ex: Exception => GameRedisPublisher.log.warnf(ex, "Failed to publish game event for game %s", gameId)
@@ -10,12 +10,14 @@ import de.nowchess.chess.observer.Observer
import de.nowchess.chess.registry.GameRegistry
import de.nowchess.chess.resource.GameDtoMapper
import de.nowchess.chess.service.InstanceHeartbeatService
import io.quarkus.redis.datasource.ReactiveRedisDataSource
import io.quarkus.redis.datasource.RedisDataSource
import io.quarkus.redis.datasource.pubsub.PubSubCommands
import io.quarkus.redis.datasource.pubsub.ReactivePubSubCommands
import jakarta.annotation.PreDestroy
import jakarta.enterprise.context.ApplicationScoped
import jakarta.enterprise.inject.Instance
import jakarta.inject.Inject
import org.jboss.logging.Logger
import scala.compiletime.uninitialized
import scala.util.Try
import java.util.concurrent.ConcurrentHashMap
@@ -24,8 +26,11 @@ import java.util.function.Consumer
@ApplicationScoped
class GameRedisSubscriberManager:
private val log = Logger.getLogger(classOf[GameRedisSubscriberManager])
// scalafix:off DisableSyntax.var
@Inject var redis: RedisDataSource = uninitialized
@Inject var reactiveRedis: ReactiveRedisDataSource = uninitialized
@Inject var registry: GameRegistry = uninitialized
@Inject var objectMapper: ObjectMapper = uninitialized
@Inject var redisConfig: RedisConfig = uninitialized
@@ -37,7 +42,7 @@ class GameRedisSubscriberManager:
if heartbeatServiceInstance.isUnsatisfied then None
else Some(heartbeatServiceInstance.get())
private val c2sListeners = new ConcurrentHashMap[String, PubSubCommands.RedisSubscriber]()
private val c2sListeners = new ConcurrentHashMap[String, ReactivePubSubCommands.ReactiveRedisSubscriber]()
private val s2cObservers = new ConcurrentHashMap[String, Observer]()
private def c2sTopic(gameId: String): String =
@@ -47,40 +52,44 @@ class GameRedisSubscriberManager:
s"${redisConfig.prefix}:game:$gameId:s2c"
def subscribeGame(gameId: String): Unit =
try
val handler: Consumer[String] = msg => handleC2sMessage(gameId, msg)
val subscriber = redis.pubsub(classOf[String]).subscribe(c2sTopic(gameId), handler)
c2sListeners.put(gameId, subscriber)
val writebackFn: String => Unit = json => redis.pubsub(classOf[String]).publish("game-writeback", json)
val obs = new GameRedisPublisher(
gameId,
registry,
redis,
objectMapper,
s2cTopicName(gameId),
writebackFn,
ioClient,
unsubscribeGame,
)
s2cObservers.put(gameId, obs)
registry.get(gameId).foreach(_.engine.subscribe(obs))
heartbeatServiceOpt.foreach(_.addGameSubscription(gameId))
val writebackFn: String => Unit = json => redis.pubsub(classOf[String]).publish("game-writeback", json)
val obs = new GameRedisPublisher(
gameId,
registry,
redis,
objectMapper,
s2cTopicName(gameId),
writebackFn,
ioClient,
unsubscribeGame,
val handler: Consumer[String] = msg => handleC2sMessage(gameId, msg)
reactiveRedis
.pubsub(classOf[String])
.subscribe(c2sTopic(gameId), handler)
.subscribe()
.`with`(
subscriber => {
c2sListeners.put(gameId, subscriber)
log.debugf("Subscribed to game %s", gameId)
},
failure => log.warnf(failure, "Redis subscription failed for game %s", gameId),
)
s2cObservers.put(gameId, obs)
registry.get(gameId).foreach(_.engine.subscribe(obs))
heartbeatServiceOpt.foreach(_.addGameSubscription(gameId))
catch
case e: Exception =>
System.err.println(s"Warning: Redis subscription failed for game $gameId: ${e.getMessage}")
()
def unsubscribeGame(gameId: String): Unit =
Option(c2sListeners.remove(gameId)).foreach { subscriber =>
subscriber.unsubscribe(c2sTopic(gameId))
subscriber.unsubscribe(c2sTopic(gameId)).subscribe().`with`(_ => (), _ => ())
}
Option(s2cObservers.remove(gameId)).foreach { obs =>
registry.get(gameId).foreach(_.engine.unsubscribe(obs))
}
heartbeatServiceOpt.foreach(_.removeGameSubscription(gameId))
log.debugf("Unsubscribed from game %s", gameId)
private def handleC2sMessage(gameId: String, msg: String): Unit =
parseC2sMessage(msg) match
@@ -97,6 +106,7 @@ class GameRedisSubscriberManager:
}
private def handleMove(gameId: String, uci: String, playerId: Option[String]): Unit =
log.debugf("Processing move %s for game %s by player %s", uci, gameId, playerId.getOrElse("anonymous"))
registry.get(gameId).foreach { entry =>
entry.mode match
case GameMode.Open => entry.engine.processUserInput(uci)
@@ -127,6 +137,7 @@ class GameRedisSubscriberManager:
def batchResubscribeGames(gameIds: java.util.List[String]): Int =
gameIds.forEach(subscribeGame)
log.infof("Batch resubscribed %d games", gameIds.size())
gameIds.size()
def unsubscribeGames(gameIds: java.util.List[String]): Int =
@@ -135,15 +146,17 @@ class GameRedisSubscriberManager:
def evictGames(gameIds: java.util.List[String]): Int =
gameIds.forEach(unsubscribeGame)
log.infof("Evicting %d games", gameIds.size())
gameIds.size()
def drainInstance(): Int =
val gameIds = new java.util.ArrayList(c2sListeners.keySet())
val count = gameIds.size()
gameIds.forEach(unsubscribeGame)
log.infof("Draining instance, unsubscribing %d games", count)
count
@PreDestroy
def cleanup(): Unit =
c2sListeners.forEach((gameId, subscriber) => subscriber.unsubscribe(c2sTopic(gameId)))
c2sListeners.forEach((gameId, subscriber) => subscriber.unsubscribe(c2sTopic(gameId)).await().indefinitely())
s2cObservers.forEach((gameId, obs) => registry.get(gameId).foreach(_.engine.unsubscribe(obs)))
@@ -17,6 +17,7 @@ import jakarta.enterprise.context.ApplicationScoped
import jakarta.inject.Inject
import org.eclipse.microprofile.rest.client.inject.RestClient
import scala.compiletime.uninitialized
import org.jboss.logging.Logger
import scala.util.Try
import java.nio.charset.StandardCharsets
import java.security.{MessageDigest, SecureRandom}
@@ -35,6 +36,7 @@ class RedisGameRegistry extends GameRegistry:
@Inject @RestClient var storeClient: StoreServiceClient = uninitialized
// scalafix:on
private val log = Logger.getLogger(classOf[RedisGameRegistry])
private val localEngines = ConcurrentHashMap[String, GameEntry]()
private val rng = new SecureRandom()
@@ -48,6 +50,12 @@ class RedisGameRegistry extends GameRegistry:
localEngines.put(entry.gameId, entry)
val combined = ioClient.exportCombined(entry.engine.context)
redis.value(classOf[String]).setex(cacheKey(entry.gameId), 1800L, toJson(entry, combined.fen, combined.pgn))
log.infof(
"Stored game %s in registry (white=%s black=%s)",
entry.gameId,
entry.white.displayName,
entry.black.displayName,
)
def get(gameId: String): Option[GameEntry] =
Option(localEngines.get(gameId)) match
@@ -71,9 +79,15 @@ class RedisGameRegistry extends GameRegistry:
private def fromRedis(gameId: String): Option[GameEntry] =
readRedisDto(gameId)
.flatMap(dto => Try(reconstruct(dto)).toOption)
.flatMap { dto =>
Try(reconstruct(dto)).toOption.orElse {
log.warnf("Failed to reconstruct game %s from Redis", gameId)
None
}
}
.map { entry =>
localEngines.put(gameId, entry)
log.infof("Loaded game %s from Redis cache", gameId)
entry
}
@@ -102,12 +116,15 @@ class RedisGameRegistry extends GameRegistry:
pendingDrawOffer = Option(record.pendingDrawOffer),
)
(dto, reconstruct(dto))
}.toOption
.map { case (dto, entry) =>
} match
case scala.util.Success((dto, entry)) =>
log.infof("Loaded game %s from store service", gameId)
localEngines.put(gameId, entry)
redis.value(classOf[String]).setex(cacheKey(gameId), 1800L, objectMapper.writeValueAsString(dto))
entry
}
Some(entry)
case scala.util.Failure(ex) =>
log.warnf(ex, "Failed to load game %s from store service", gameId)
None
private def reconstruct(dto: GameCacheDto): GameEntry =
val ctx = if dto.pgn.nonEmpty then ioClient.importPgn(dto.pgn) else GameContext.initial
@@ -30,6 +30,7 @@ import jakarta.inject.Inject
import jakarta.ws.rs.*
import jakarta.ws.rs.core.{MediaType, Response}
import org.eclipse.microprofile.jwt.JsonWebToken
import org.jboss.logging.Logger
import java.util.concurrent.atomic.AtomicReference
import scala.compiletime.uninitialized
@@ -38,6 +39,8 @@ import scala.compiletime.uninitialized
@ApplicationScoped
class GameResource:
private val log = Logger.getLogger(classOf[GameResource])
// scalafix:off DisableSyntax.var
@Inject
var registry: GameRegistry = uninitialized
@@ -165,7 +168,13 @@ class GameResource:
val entry = newEntry(GameContext.initial, white, black, tc, mode)
registry.store(entry)
subscriberManager.subscribeGame(entry.gameId)
println(s"Created game ${entry.gameId}")
log.infof(
"Game %s created — white=%s black=%s mode=%s",
entry.gameId,
white.displayName,
black.displayName,
mode.toString,
)
created(GameDtoMapper.toGameFullDto(entry, ioClient))
@GET
@@ -182,6 +191,7 @@ class GameResource:
val entry = registry.get(gameId).getOrElse(throw GameNotFoundException(gameId))
assertGameNotOver(entry)
val color = colorOf(entry)
log.infof("Game %s — resign by %s", gameId, color.label)
entry.engine.resign(color)
registry.update(entry.copy(resigned = true))
ok(OkResponseDto())
@@ -194,6 +204,7 @@ class GameResource:
val entry = registry.get(gameId).getOrElse(throw GameNotFoundException(gameId))
assertGameNotOver(entry)
assertIsCurrentPlayer(entry)
log.debugf("Game %s — move %s by %s", gameId, uci, colorOf(entry).label)
if Parser.parseMove(uci).isEmpty then
throw BadRequestException("INVALID_UCI", s"Invalid UCI notation: $uci", Some("uci"))
applyMoveInput(entry.engine, uci).foreach(err => throw BadRequestException("INVALID_MOVE", err, Some("uci")))
@@ -284,6 +295,7 @@ class GameResource:
val entry = newEntry(ctx, white, black, tc)
registry.store(entry)
subscriberManager.subscribeGame(entry.gameId)
log.infof("Imported FEN game %s", entry.gameId)
created(GameDtoMapper.toGameFullDto(entry, ioClient))
@POST
@@ -295,6 +307,7 @@ class GameResource:
val entry = newEntry(ctx, DefaultWhite, DefaultBlack)
registry.store(entry)
subscriberManager.subscribeGame(entry.gameId)
log.infof("Imported PGN game %s", entry.gameId)
created(GameDtoMapper.toGameFullDto(entry, ioClient))
@GET
@@ -8,8 +8,10 @@ import io.quarkus.runtime.ShutdownEvent
import io.quarkus.grpc.GrpcClient
import org.eclipse.microprofile.config.inject.ConfigProperty
import io.quarkus.redis.datasource.RedisDataSource
import io.quarkus.redis.datasource.ReactiveRedisDataSource
import scala.compiletime.uninitialized
import java.util.concurrent.{Executors, TimeUnit}
import java.util.concurrent.atomic.AtomicBoolean
import java.net.InetAddress
import com.fasterxml.jackson.databind.ObjectMapper
import org.jboss.logging.Logger
@@ -24,6 +26,12 @@ class InstanceHeartbeatService:
@Inject
private var redis: RedisDataSource = uninitialized
@Inject
private var reactiveRedis: ReactiveRedisDataSource = uninitialized
@Inject
private var mapper: ObjectMapper = uninitialized
@GrpcClient("coordinator-grpc")
private var channel: Channel = uninitialized
@@ -38,7 +46,6 @@ class InstanceHeartbeatService:
private var coordinatorStub: CoordinatorServiceStub = uninitialized
private val log = Logger.getLogger(classOf[InstanceHeartbeatService])
private val mapper = ObjectMapper()
private var instanceId = ""
private var redisPrefix = "nowchess"
private var streamObserver: Option[StreamObserver[HeartbeatFrame]] = None
@@ -49,6 +56,7 @@ class InstanceHeartbeatService:
private var serviceActive = false
private var shuttingDown = false
// scalafix:on DisableSyntax.var
private val redisHeartbeatPending = new AtomicBoolean(false)
def onStart(@Observes event: StartupEvent): Unit =
if coordinatorEnabled then
@@ -165,25 +173,36 @@ class InstanceHeartbeatService:
}
private def refreshRedisHeartbeat(): Unit =
try
val key = s"$redisPrefix:instances:$instanceId"
if redisHeartbeatPending.compareAndSet(false, true) then
try
val key = s"$redisPrefix:instances:$instanceId"
val metadata = Map(
"instanceId" -> instanceId,
"hostname" -> getHostname,
"httpPort" -> httpPort,
"grpcPort" -> grpcPort,
"subscriptionCount" -> subscriptionCount,
"localCacheSize" -> localCacheSize,
"lastHeartbeat" -> java.time.Instant.now().toString,
"state" -> "HEALTHY",
)
val metadata = Map(
"instanceId" -> instanceId,
"hostname" -> getHostname,
"httpPort" -> httpPort,
"grpcPort" -> grpcPort,
"subscriptionCount" -> subscriptionCount,
"localCacheSize" -> localCacheSize,
"lastHeartbeat" -> java.time.Instant.now().toString,
"state" -> "HEALTHY",
)
val json = mapper.writeValueAsString(metadata)
redis.value(classOf[String]).setex(key, 5L, json)
catch
case ex: Exception =>
log.warnf(ex, "Failed to refresh Redis heartbeat")
val json = mapper.writeValueAsString(metadata)
reactiveRedis
.value(classOf[String])
.setex(key, 5L, json)
.subscribe()
.`with`(
_ => redisHeartbeatPending.set(false),
(ex: Throwable) =>
redisHeartbeatPending.set(false)
log.warnf(ex, "Failed to refresh Redis heartbeat"),
)
catch
case ex: Exception =>
redisHeartbeatPending.set(false)
log.warnf(ex, "Failed to serialize Redis heartbeat metadata")
private def getHostname: String =
try InetAddress.getLocalHost.getHostName
@@ -0,0 +1,72 @@
package de.nowchess.chess.resource
import de.nowchess.chess.grpc.{IoGrpcClientWrapper, RuleSetGrpcAdapter}
import de.nowchess.chess.redis.GameRedisSubscriberManager
import io.quarkus.test.InjectMock
import io.quarkus.test.junit.{QuarkusTest, TestProfile}
import io.quarkus.test.junit.QuarkusTestProfile
import io.restassured.RestAssured
import jakarta.ws.rs.core.MediaType
import org.junit.jupiter.api.{DisplayName, Test}
import java.util.Map as JMap
// scalafix:off
class InternalAuthEnabledProfile extends QuarkusTestProfile:
override def getConfigOverrides(): JMap[String, String] =
JMap.of(
"nowchess.internal.auth.enabled",
"true",
"nowchess.internal.secret",
"test-secret-123",
)
@QuarkusTest
@TestProfile(classOf[InternalAuthEnabledProfile])
@DisplayName("InternalAuthFilter HTTP")
class InternalAuthFilterHttpTest:
@InjectMock
var ioWrapper: IoGrpcClientWrapper = scala.compiletime.uninitialized
@InjectMock
var ruleAdapter: RuleSetGrpcAdapter = scala.compiletime.uninitialized
@InjectMock
var subscriberManager: GameRedisSubscriberManager = scala.compiletime.uninitialized
@Test
@DisplayName("POST /api/board/game without secret returns 401")
def rejectNoSecret(): Unit =
RestAssured
.`given`()
.contentType(MediaType.APPLICATION_JSON)
.body("{}")
.when()
.post("/api/board/game")
.`then`()
.statusCode(401)
@Test
@DisplayName("POST /api/board/game with wrong secret returns 401")
def rejectWrongSecret(): Unit =
RestAssured
.`given`()
.contentType(MediaType.APPLICATION_JSON)
.header("X-Internal-Secret", "wrong-secret")
.body("{}")
.when()
.post("/api/board/game")
.`then`()
.statusCode(401)
@Test
@DisplayName("GET /api/board/game/{id} without secret returns 404 not 401")
def nonInternalEndpointNotBlocked(): Unit =
RestAssured
.`given`()
.when()
.get("/api/board/game/nonexistent")
.`then`()
.statusCode(404)
// scalafix:on
+1 -1
View File
@@ -1,3 +1,3 @@
MAJOR=0
MINOR=23
MINOR=30
PATCH=0
+57
View File
@@ -171,3 +171,60 @@
### Bug Fixes
* IO microservice ([#38](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/38)) ([a386f57](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/a386f57c21d34ead6cc6f92836c52b714597e289))
## (2026-04-30)
### Features
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* NCS-14 implemented insufficient moves rule ([#30](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/30)) ([b0399a4](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b0399a4e489950083066c9538df9a84dcc7a4613))
* NCS-25 Add linters to keep quality up ([#27](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/27)) ([fd4e67d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/fd4e67d4f782a7e955822d90cb909d0a81676fb2))
* NCS-29 JSON - Cherry Picked ([#28](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/28)) ([dbcafd2](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/dbcafd286993e0604a6fa286c5543581a149439e))
* NCS-30 FEN Parser using ParserCombinators ([#21](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/21)) ([b4bc72f](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b4bc72f7e49f94d6e1bc805c68680e5fe8ef8e36))
* NCS-31 FastParse FEN ([#22](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/22)) ([7a045d3](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/7a045d31d757bbc5aa6f4bad2664ebe8b8519cac))
* NCS-37 Quarkus integration ([#35](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/35)) ([f088c4e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/f088c4e9ffcc498d3d1b6f01e8f50042d5830d55))
* NCS-41 Bot Platform ([#33](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/33)) ([8744bee](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/8744bee2dd20966dae90a09c21a43d5b06f59e00))
* NCS-53 changed IO to MicroService for easier scaling ([#37](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/37)) ([b5a2966](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b5a2966adafa9650f0f7d601bdeb8fdd13710327))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
### Bug Fixes
* IO microservice ([#38](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/38)) ([a386f57](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/a386f57c21d34ead6cc6f92836c52b714597e289))
## (2026-05-01)
### Features
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* NCS-14 implemented insufficient moves rule ([#30](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/30)) ([b0399a4](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b0399a4e489950083066c9538df9a84dcc7a4613))
* NCS-25 Add linters to keep quality up ([#27](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/27)) ([fd4e67d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/fd4e67d4f782a7e955822d90cb909d0a81676fb2))
* NCS-29 JSON - Cherry Picked ([#28](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/28)) ([dbcafd2](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/dbcafd286993e0604a6fa286c5543581a149439e))
* NCS-30 FEN Parser using ParserCombinators ([#21](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/21)) ([b4bc72f](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b4bc72f7e49f94d6e1bc805c68680e5fe8ef8e36))
* NCS-31 FastParse FEN ([#22](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/22)) ([7a045d3](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/7a045d31d757bbc5aa6f4bad2664ebe8b8519cac))
* NCS-37 Quarkus integration ([#35](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/35)) ([f088c4e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/f088c4e9ffcc498d3d1b6f01e8f50042d5830d55))
* NCS-41 Bot Platform ([#33](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/33)) ([8744bee](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/8744bee2dd20966dae90a09c21a43d5b06f59e00))
* NCS-53 changed IO to MicroService for easier scaling ([#37](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/37)) ([b5a2966](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b5a2966adafa9650f0f7d601bdeb8fdd13710327))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
### Bug Fixes
* IO microservice ([#38](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/38)) ([a386f57](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/a386f57c21d34ead6cc6f92836c52b714597e289))
## (2026-05-02)
### Features
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* NCS-14 implemented insufficient moves rule ([#30](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/30)) ([b0399a4](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b0399a4e489950083066c9538df9a84dcc7a4613))
* NCS-25 Add linters to keep quality up ([#27](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/27)) ([fd4e67d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/fd4e67d4f782a7e955822d90cb909d0a81676fb2))
* NCS-29 JSON - Cherry Picked ([#28](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/28)) ([dbcafd2](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/dbcafd286993e0604a6fa286c5543581a149439e))
* NCS-30 FEN Parser using ParserCombinators ([#21](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/21)) ([b4bc72f](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b4bc72f7e49f94d6e1bc805c68680e5fe8ef8e36))
* NCS-31 FastParse FEN ([#22](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/22)) ([7a045d3](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/7a045d31d757bbc5aa6f4bad2664ebe8b8519cac))
* NCS-37 Quarkus integration ([#35](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/35)) ([f088c4e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/f088c4e9ffcc498d3d1b6f01e8f50042d5830d55))
* NCS-41 Bot Platform ([#33](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/33)) ([8744bee](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/8744bee2dd20966dae90a09c21a43d5b06f59e00))
* NCS-53 changed IO to MicroService for easier scaling ([#37](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/37)) ([b5a2966](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b5a2966adafa9650f0f7d601bdeb8fdd13710327))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
### Bug Fixes
* IO microservice ([#38](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/38)) ([a386f57](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/a386f57c21d34ead6cc6f92836c52b714597e289))
+1 -1
View File
@@ -1,3 +1,3 @@
MAJOR=0
MINOR=16
MINOR=19
PATCH=0
+15
View File
@@ -13,3 +13,18 @@
### Features
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
## (2026-04-30)
### Features
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
## (2026-05-01)
### Features
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
## (2026-05-02)
### Features
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
+1 -1
View File
@@ -1,3 +1,3 @@
MAJOR=0
MINOR=3
MINOR=6
PATCH=0
+30
View File
@@ -27,3 +27,33 @@
* **docker:** add Dockerfiles for building Quarkus application in native and JVM modes ([3f2d2bb](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3f2d2bb4c97fa8cddba66e1da4427c54236dfeed))
* **docker:** add Dockerfiles for Quarkus application in JVM and native modes ([34b9933](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/34b993304670cf2aa62cd2f6460cee7b9864b08e))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
## (2026-04-30)
### Features
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* **docker:** add .dockerignore and .gitignore files for build exclusions ([c987d8e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/c987d8e258c0e6c4cfbdaa8381c64c410d7a2b83))
* **docker:** add Dockerfiles for building Quarkus application in native and JVM modes ([3f2d2bb](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3f2d2bb4c97fa8cddba66e1da4427c54236dfeed))
* **docker:** add Dockerfiles for Quarkus application in JVM and native modes ([34b9933](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/34b993304670cf2aa62cd2f6460cee7b9864b08e))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
## (2026-05-01)
### Features
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* **docker:** add .dockerignore and .gitignore files for build exclusions ([c987d8e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/c987d8e258c0e6c4cfbdaa8381c64c410d7a2b83))
* **docker:** add Dockerfiles for building Quarkus application in native and JVM modes ([3f2d2bb](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3f2d2bb4c97fa8cddba66e1da4427c54236dfeed))
* **docker:** add Dockerfiles for Quarkus application in JVM and native modes ([34b9933](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/34b993304670cf2aa62cd2f6460cee7b9864b08e))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
## (2026-05-02)
### Features
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* **docker:** add .dockerignore and .gitignore files for build exclusions ([c987d8e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/c987d8e258c0e6c4cfbdaa8381c64c410d7a2b83))
* **docker:** add Dockerfiles for building Quarkus application in native and JVM modes ([3f2d2bb](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/3f2d2bb4c97fa8cddba66e1da4427c54236dfeed))
* **docker:** add Dockerfiles for Quarkus application in JVM and native modes ([34b9933](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/34b993304670cf2aa62cd2f6460cee7b9864b08e))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
+1 -1
View File
@@ -1,3 +1,3 @@
MAJOR=0
MINOR=3
MINOR=6
PATCH=0
+54
View File
@@ -185,3 +185,57 @@
### Bug Fixes
* NCS-32 Queenside Castle doesn't care about pieces in the way ([#23](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/23)) ([fe8e3c0](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/fe8e3c05397f433bfa34d1999e9738c82790adf7))
## (2026-04-30)
### Features
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* **docker:** update COPY command in native Dockerfile to reflect new build path ([952cf00](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/952cf00413fcbc5e9df1bad224d2e99f07064bf7))
* NCS-13 Implement Threefold Repetition ([#31](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/31)) ([767d305](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/767d3051a76c266050b6335774d66e2db2273c16))
* NCS-14 implemented insufficient moves rule ([#30](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/30)) ([b0399a4](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b0399a4e489950083066c9538df9a84dcc7a4613))
* NCS-25 Add linters to keep quality up ([#27](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/27)) ([fd4e67d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/fd4e67d4f782a7e955822d90cb909d0a81676fb2))
* NCS-37 Quarkus integration ([#35](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/35)) ([f088c4e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/f088c4e9ffcc498d3d1b6f01e8f50042d5830d55))
* NCS-41 Bot Platform ([#33](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/33)) ([8744bee](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/8744bee2dd20966dae90a09c21a43d5b06f59e00))
* **rule:** Rules as a microservice ([#39](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/39)) ([093134d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/093134d36c6844ba02a36a28d5d044f09291cd1d))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
### Bug Fixes
* NCS-32 Queenside Castle doesn't care about pieces in the way ([#23](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/23)) ([fe8e3c0](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/fe8e3c05397f433bfa34d1999e9738c82790adf7))
## (2026-05-01)
### Features
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* **docker:** update COPY command in native Dockerfile to reflect new build path ([952cf00](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/952cf00413fcbc5e9df1bad224d2e99f07064bf7))
* NCS-13 Implement Threefold Repetition ([#31](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/31)) ([767d305](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/767d3051a76c266050b6335774d66e2db2273c16))
* NCS-14 implemented insufficient moves rule ([#30](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/30)) ([b0399a4](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b0399a4e489950083066c9538df9a84dcc7a4613))
* NCS-25 Add linters to keep quality up ([#27](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/27)) ([fd4e67d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/fd4e67d4f782a7e955822d90cb909d0a81676fb2))
* NCS-37 Quarkus integration ([#35](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/35)) ([f088c4e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/f088c4e9ffcc498d3d1b6f01e8f50042d5830d55))
* NCS-41 Bot Platform ([#33](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/33)) ([8744bee](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/8744bee2dd20966dae90a09c21a43d5b06f59e00))
* **rule:** Rules as a microservice ([#39](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/39)) ([093134d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/093134d36c6844ba02a36a28d5d044f09291cd1d))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
### Bug Fixes
* NCS-32 Queenside Castle doesn't care about pieces in the way ([#23](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/23)) ([fe8e3c0](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/fe8e3c05397f433bfa34d1999e9738c82790adf7))
## (2026-05-02)
### Features
* **config:** update application.yml for PostgreSQL and remove staging/production configurations ([2404e61](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/2404e6164c3b50ffccbea5238d636060d6abe4d6))
* **config:** update application.yml for staging and production environments ([6113432](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6113432a14c476a3a0dfc0d449e17d023697f2ba))
* **docker:** update COPY command in native Dockerfile to reflect new build path ([952cf00](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/952cf00413fcbc5e9df1bad224d2e99f07064bf7))
* NCS-13 Implement Threefold Repetition ([#31](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/31)) ([767d305](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/767d3051a76c266050b6335774d66e2db2273c16))
* NCS-14 implemented insufficient moves rule ([#30](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/30)) ([b0399a4](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/b0399a4e489950083066c9538df9a84dcc7a4613))
* NCS-25 Add linters to keep quality up ([#27](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/27)) ([fd4e67d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/fd4e67d4f782a7e955822d90cb909d0a81676fb2))
* NCS-37 Quarkus integration ([#35](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/35)) ([f088c4e](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/f088c4e9ffcc498d3d1b6f01e8f50042d5830d55))
* NCS-41 Bot Platform ([#33](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/33)) ([8744bee](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/8744bee2dd20966dae90a09c21a43d5b06f59e00))
* **rule:** Rules as a microservice ([#39](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/39)) ([093134d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/093134d36c6844ba02a36a28d5d044f09291cd1d))
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
### Bug Fixes
* NCS-32 Queenside Castle doesn't care about pieces in the way ([#23](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/23)) ([fe8e3c0](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/fe8e3c05397f433bfa34d1999e9738c82790adf7))
+1 -1
View File
@@ -1,3 +1,3 @@
MAJOR=0
MINOR=12
MINOR=15
PATCH=0
+37
View File
@@ -13,3 +13,40 @@
### Features
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
## (2026-04-30)
### Features
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
## (2026-05-01)
### Features
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
## (2026-05-02)
### Features
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
## (2026-05-03)
### Features
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
### Bug Fixes
* **auth:** correct internal secret validation logic in InternalAuthFilter ([85b1872](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/85b187293f12f149494986872d6b06789945ea18))
## (2026-05-06)
### Features
* true-microservices ([#40](https://git.janis-eccarius.de/NowChess/NowChessSystems/issues/40)) ([5909242](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/590924254e8a2754de661a57a03e43f89ceb6299))
### Bug Fixes
* **auth:** add InternalClientHeadersFactory for custom client headers management ([e279c39](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/e279c39246470156bf11e745ee72204018d4229d))
* **auth:** change InternalAuthFilter to use @Singleton and add HTTP tests for secret validation ([c08d530](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/c08d5303eb9e70d36c8eebf6a061ccb71e118fe5))
* **auth:** correct internal secret validation logic in InternalAuthFilter ([85b1872](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/85b187293f12f149494986872d6b06789945ea18))
* **auth:** update InternalAuthFilter to use @ApplicationScoped and add index-dependency configuration ([6e0fd95](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/6e0fd9523e001756ce7109e639ebb54be4fcdabf))
* **redis:** enhance GameRedisSubscriberManager to use ReactiveRedisDataSource and improve subscription handling ([0eb752d](https://git.janis-eccarius.de/NowChess/NowChessSystems/commit/0eb752d4935377f75aab710b7f4eda4b29098e6a))
@@ -23,5 +23,5 @@ class InternalAuthFilter extends ContainerRequestFilter:
override def filter(ctx: ContainerRequestContext): Unit =
if authEnabled then
val header = Option(ctx.getHeaderString("X-Internal-Secret"))
if header.isEmpty || header.get.equals(secret) then
if header.isEmpty || (!header.get.equals(secret)) then
ctx.abortWith(Response.status(Response.Status.UNAUTHORIZED).build())
@@ -0,0 +1,30 @@
package de.nowchess.security
import jakarta.enterprise.context.ApplicationScoped
import jakarta.ws.rs.core.MultivaluedMap
import org.eclipse.microprofile.config.inject.ConfigProperty
import org.eclipse.microprofile.rest.client.ext.DefaultClientHeadersFactoryImpl
import scala.compiletime.uninitialized
@ApplicationScoped
class InternalClientHeadersFactory extends DefaultClientHeadersFactoryImpl {
@ConfigProperty(name = "nowchess.internal.secret", defaultValue = "")
// scalafix:off DisableSyntax.var
var secret: String = uninitialized
@ConfigProperty(name = "nowchess.internal.auth.enabled", defaultValue = "true")
var authEnabled: Boolean = uninitialized
// scalafix:on DisableSyntax.var
override def update(
incomingHeaders: MultivaluedMap[String, String],
clientOutgoingHeaders: MultivaluedMap[String, String],
): MultivaluedMap[String, String] = {
val default = super.update(incomingHeaders, clientOutgoingHeaders)
default.putSingle("X-Internal-Secret", secret)
default
}
}

Some files were not shown because too many files have changed in this diff Show More