From 76b75bab135d964e07416e781339bfee685e8e78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Por=C4=99bski?= <164040529+TexablePlum@users.noreply.github.com> Date: Mon, 6 Jul 2026 14:34:24 +0200 Subject: [PATCH 1/9] feat(contracts): define WebSocket payload schemas (#75) - Add draft 2020-12 contracts for authoritative game-state and player-specific match-found STOMP messages. - Document destinations, direction, recovery semantics, and additive v1 evolution rules. - Validate real publisher DTO serialization with each service's Spring-configured ObjectMapper and networknt. - Tests: game-service verify passed 214 tests; matchmaking-service verify passed 105 tests; a deliberate match-found field rename failed the contract test. --- checkers-contracts/README.md | 3 +- checkers-contracts/ws/v1/README.md | 25 +++++++ .../ws/v1/game-state.schema.json | 64 ++++++++++++++++ .../ws/v1/match-found.schema.json | 23 ++++++ services/game-service/README.md | 3 + services/game-service/pom.xml | 6 ++ .../game/websocket/GameStateContractTest.java | 75 +++++++++++++++++++ services/matchmaking-service/README.md | 3 + services/matchmaking-service/pom.xml | 6 ++ .../websocket/MatchFoundContractTest.java | 55 ++++++++++++++ 10 files changed, 262 insertions(+), 1 deletion(-) create mode 100644 checkers-contracts/ws/v1/README.md create mode 100644 checkers-contracts/ws/v1/game-state.schema.json create mode 100644 checkers-contracts/ws/v1/match-found.schema.json create mode 100644 services/game-service/src/test/java/com/checkers/gameservice/game/websocket/GameStateContractTest.java create mode 100644 services/matchmaking-service/src/test/java/com/checkers/matchmakingservice/matchmaking/websocket/MatchFoundContractTest.java diff --git a/checkers-contracts/README.md b/checkers-contracts/README.md index 2cff866..2451399 100644 --- a/checkers-contracts/README.md +++ b/checkers-contracts/README.md @@ -4,7 +4,8 @@ This directory is the versioned source of truth for platform boundaries: - `*.proto` defines the `checkers.v1` gRPC APIs; - `http/v1/api-error.schema.json` defines the common Java HTTP error body; -- `auth/v1/` defines JWT access/refresh claims and the Redis access-token blacklist protocol. +- `auth/v1/` defines JWT access/refresh claims and the Redis access-token blacklist protocol; +- `ws/v1/` defines server-to-client STOMP payloads and their destinations. The Protobuf API is stable under the `checkers.v1` package. Java code is generated under `com.checkers.contracts.v1`; Python keeps the standard module names generated from each `.proto` file. diff --git a/checkers-contracts/ws/v1/README.md b/checkers-contracts/ws/v1/README.md new file mode 100644 index 0000000..de21379 --- /dev/null +++ b/checkers-contracts/ws/v1/README.md @@ -0,0 +1,25 @@ +# WebSocket contracts v1 + +These JSON Schemas describe every server-to-client STOMP payload in the platform. Both publishers +send application DTOs through Spring's Jackson-backed STOMP message converter. + +| Service | Destination | Direction | Schema | +|---|---|---|---| +| `game-service` | `/topic/games/{gameId}` | server to subscribed client | `game-state.schema.json` | +| `matchmaking-service` | `/user/queue/matchmaking` | server to authenticated user | `match-found.schema.json` | + +`game-state` is the complete authoritative `GameResponse` snapshot. `match-found` is a best-effort, +player-specific notification; clients recover missed delivery through the matchmaking REST status +endpoint. + +## Evolution rules + +- Keep v1 changes additive: existing property names, JSON types, enum values and meanings remain stable. +- Add optional properties when extending a payload so old clients can continue to consume it. +- Update the schema and its service contract test in the same change as an additive DTO extension. +- Publish incompatible replacements under `ws/v2` and on versioned destinations rather than changing v1. +- Treat destination names and routing direction as part of the contract. + +Each publishing service serializes its real DTO with the application `ObjectMapper` and validates the +result against the corresponding schema during `mvn verify`. This catches DTO/schema drift before a +payload reaches clients. diff --git a/checkers-contracts/ws/v1/game-state.schema.json b/checkers-contracts/ws/v1/game-state.schema.json new file mode 100644 index 0000000..8b92732 --- /dev/null +++ b/checkers-contracts/ws/v1/game-state.schema.json @@ -0,0 +1,64 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://checkers.example/contracts/ws/v1/game-state.schema.json", + "title": "Game state v1", + "description": "Authoritative game snapshot published by game-service.", + "type": "object", + "additionalProperties": false, + "required": [ + "id", "variant", "status", "whitePlayer", "blackPlayer", "timeControl", "clock", + "moves", "currentFen", "legalMoves", "currentTurn", "result", "endReason", + "createdAt", "finishedAt" + ], + "properties": { + "id": { "type": "string", "format": "uuid" }, + "variant": { "$ref": "#/$defs/variant" }, + "status": { "enum": ["WAITING_FOR_OPPONENT", "IN_PROGRESS", "FINISHED"] }, + "whitePlayer": { "oneOf": [{ "$ref": "#/$defs/player" }, { "type": "null" }] }, + "blackPlayer": { "oneOf": [{ "$ref": "#/$defs/player" }, { "type": "null" }] }, + "timeControl": { "oneOf": [{ "$ref": "#/$defs/timeControl" }, { "type": "null" }] }, + "clock": { "oneOf": [{ "$ref": "#/$defs/clock" }, { "type": "null" }] }, + "moves": { "type": "array", "items": { "type": "string" } }, + "currentFen": { "type": "string", "minLength": 1 }, + "legalMoves": { "type": "array", "items": { "type": "string" } }, + "currentTurn": { "type": ["string", "null"], "enum": ["WHITE", "BLACK", null] }, + "result": { "type": ["string", "null"], "enum": ["WHITE_WON", "BLACK_WON", "DRAW", null] }, + "endReason": { + "type": ["string", "null"], + "enum": ["NORMAL", "RESIGNATION", "TIMEOUT", "ABANDONMENT", null] + }, + "createdAt": { "type": "string", "format": "date-time" }, + "finishedAt": { "type": ["string", "null"], "format": "date-time" } + }, + "$defs": { + "variant": { + "enum": [ + "STANDARD", "AMERICAN", "FRISIAN", "RUSSIAN", "BRAZILIAN", "ANTIDRAUGHTS", + "BREAKTHROUGH", "FRYSK" + ] + }, + "timeControl": { + "enum": ["BULLET_1_0", "BLITZ_3_0", "BLITZ_5_0", "RAPID_10_0", "CLASSICAL_30_0"] + }, + "player": { + "type": "object", + "additionalProperties": false, + "required": ["type", "userId", "aiDifficulty"], + "properties": { + "type": { "enum": ["HUMAN", "AI"] }, + "userId": { "type": ["string", "null"], "format": "uuid" }, + "aiDifficulty": { "type": ["integer", "null"] } + } + }, + "clock": { + "type": "object", + "additionalProperties": false, + "required": ["whiteRemainingMillis", "blackRemainingMillis", "lastSwitchAt"], + "properties": { + "whiteRemainingMillis": { "type": "integer", "minimum": 0 }, + "blackRemainingMillis": { "type": "integer", "minimum": 0 }, + "lastSwitchAt": { "type": "string", "format": "date-time" } + } + } + } +} diff --git a/checkers-contracts/ws/v1/match-found.schema.json b/checkers-contracts/ws/v1/match-found.schema.json new file mode 100644 index 0000000..66d92c0 --- /dev/null +++ b/checkers-contracts/ws/v1/match-found.schema.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://checkers.example/contracts/ws/v1/match-found.schema.json", + "title": "Match found v1", + "description": "Player-specific notification published by matchmaking-service after game creation.", + "type": "object", + "additionalProperties": false, + "required": ["gameId", "color", "opponentId", "variant", "timeControl"], + "properties": { + "gameId": { "type": "string", "format": "uuid" }, + "color": { "enum": ["WHITE", "BLACK"] }, + "opponentId": { "type": "string", "format": "uuid" }, + "variant": { + "enum": [ + "STANDARD", "AMERICAN", "FRISIAN", "RUSSIAN", "BRAZILIAN", "ANTIDRAUGHTS", + "BREAKTHROUGH", "FRYSK" + ] + }, + "timeControl": { + "enum": ["BULLET_1_0", "BLITZ_3_0", "BLITZ_5_0", "RAPID_10_0", "CLASSICAL_30_0"] + } + } +} diff --git a/services/game-service/README.md b/services/game-service/README.md index dff6d11..af5a400 100644 --- a/services/game-service/README.md +++ b/services/game-service/README.md @@ -1007,6 +1007,9 @@ The build generates gRPC stubs, runs the suite and enforces **100% line and bran handwritten service code via JaCoCo. **Docker must be running** (Testcontainers + embedded WebSocket server). Layers covered (194 tests): +The suite also serializes the real game-state WebSocket DTO with the application Jackson +configuration and validates it against `checkers-contracts/ws/v1/game-state.schema.json`. + - **Unit (Mockito):** game lifecycle, moves and completion, AI turns, ELO reporting, deadline and abandonment managers, the domain model, runtime support (clocks, locks, executors) and the variant parity guard. diff --git a/services/game-service/pom.xml b/services/game-service/pom.xml index cb9c9db..b16862a 100644 --- a/services/game-service/pom.xml +++ b/services/game-service/pom.xml @@ -128,6 +128,12 @@ spring-boot-starter-test test + + com.networknt + json-schema-validator + 1.5.6 + test + org.springframework.security spring-security-test diff --git a/services/game-service/src/test/java/com/checkers/gameservice/game/websocket/GameStateContractTest.java b/services/game-service/src/test/java/com/checkers/gameservice/game/websocket/GameStateContractTest.java new file mode 100644 index 0000000..0959546 --- /dev/null +++ b/services/game-service/src/test/java/com/checkers/gameservice/game/websocket/GameStateContractTest.java @@ -0,0 +1,75 @@ +package com.checkers.gameservice.game.websocket; + +import com.checkers.gameservice.game.dto.GameClockResponse; +import com.checkers.gameservice.game.dto.GameResponse; +import com.checkers.gameservice.game.dto.PlayerResponse; +import com.checkers.gameservice.game.dto.PlayerType; +import com.checkers.gameservice.game.entity.GameStatus; +import com.checkers.gameservice.game.entity.GameVariant; +import com.checkers.gameservice.game.entity.PlayerColor; +import com.checkers.gameservice.game.entity.TimeControl; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.networknt.schema.JsonSchema; +import com.networknt.schema.JsonSchemaFactory; +import com.networknt.schema.SpecVersion; +import com.networknt.schema.ValidationMessage; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.json.JsonTest; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.Instant; +import java.util.List; +import java.util.Set; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +@JsonTest +class GameStateContractTest { + + @Autowired + private ObjectMapper objectMapper; + + @Test + void applicationSerializationMatchesGameStateV1Schema() throws Exception { + Instant now = Instant.parse("2026-07-06T10:15:30Z"); + GameResponse payload = new GameResponse( + UUID.fromString("00000000-0000-0000-0000-000000000001"), + GameVariant.STANDARD, + GameStatus.IN_PROGRESS, + new PlayerResponse( + PlayerType.HUMAN, + UUID.fromString("00000000-0000-0000-0000-000000000002"), + null), + new PlayerResponse(PlayerType.AI, null, 3), + TimeControl.BLITZ_5_0, + new GameClockResponse(299_000, 300_000, now), + List.of("31-27"), + "W:W27,32:B1,6", + List.of("27-23", "27-24"), + PlayerColor.WHITE, + null, + null, + now, + null); + + Set errors = schema().validate(objectMapper.valueToTree(payload)); + + assertTrue(errors.isEmpty(), () -> "game-state schema violations: " + errors); + } + + private JsonSchema schema() throws Exception { + JsonNode schemaNode = objectMapper.readTree(Files.readString(contractPath())); + return JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V202012).getSchema(schemaNode); + } + + private static Path contractPath() { + Path fromRoot = Path.of("checkers-contracts/ws/v1/game-state.schema.json"); + return Files.exists(fromRoot) + ? fromRoot + : Path.of("../../checkers-contracts/ws/v1/game-state.schema.json"); + } +} diff --git a/services/matchmaking-service/README.md b/services/matchmaking-service/README.md index a90cf15..6f348d1 100644 --- a/services/matchmaking-service/README.md +++ b/services/matchmaking-service/README.md @@ -675,6 +675,9 @@ The build generates gRPC stubs, runs the suite and enforces **100% line and bran handwritten service code via JaCoCo. Docker must be running for Redis Testcontainers. Layers covered (102 tests): +The suite also serializes the real match-found WebSocket DTO with the application Jackson +configuration and validates it against `checkers-contracts/ws/v1/match-found.schema.json`. + - **Unit (Mockito):** queue service, ticket invariants, ELO window policy, matcher decisions, scheduler error isolation, color assignment, presence registry/listener and disconnect grace. - **In-process gRPC (`grpc-testing`):** `GrpcEloClient` and `GrpcMatchedGameClient` request mapping, diff --git a/services/matchmaking-service/pom.xml b/services/matchmaking-service/pom.xml index f25d130..a57b72a 100644 --- a/services/matchmaking-service/pom.xml +++ b/services/matchmaking-service/pom.xml @@ -107,6 +107,12 @@ spring-boot-starter-test test + + com.networknt + json-schema-validator + 1.5.6 + test + org.springframework.security spring-security-test diff --git a/services/matchmaking-service/src/test/java/com/checkers/matchmakingservice/matchmaking/websocket/MatchFoundContractTest.java b/services/matchmaking-service/src/test/java/com/checkers/matchmakingservice/matchmaking/websocket/MatchFoundContractTest.java new file mode 100644 index 0000000..56d10e0 --- /dev/null +++ b/services/matchmaking-service/src/test/java/com/checkers/matchmakingservice/matchmaking/websocket/MatchFoundContractTest.java @@ -0,0 +1,55 @@ +package com.checkers.matchmakingservice.matchmaking.websocket; + +import com.checkers.matchmakingservice.matchmaking.dto.MatchFoundMessage; +import com.checkers.matchmakingservice.queue.entity.GameVariant; +import com.checkers.matchmakingservice.queue.entity.PlayerColor; +import com.checkers.matchmakingservice.queue.entity.TimeControl; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.networknt.schema.JsonSchema; +import com.networknt.schema.JsonSchemaFactory; +import com.networknt.schema.SpecVersion; +import com.networknt.schema.ValidationMessage; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.json.JsonTest; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Set; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +@JsonTest +class MatchFoundContractTest { + + @Autowired + private ObjectMapper objectMapper; + + @Test + void applicationSerializationMatchesMatchFoundV1Schema() throws Exception { + MatchFoundMessage payload = new MatchFoundMessage( + UUID.fromString("00000000-0000-0000-0000-000000000001"), + PlayerColor.BLACK, + UUID.fromString("00000000-0000-0000-0000-000000000002"), + GameVariant.STANDARD, + TimeControl.BLITZ_5_0); + + Set errors = schema().validate(objectMapper.valueToTree(payload)); + + assertTrue(errors.isEmpty(), () -> "match-found schema violations: " + errors); + } + + private JsonSchema schema() throws Exception { + JsonNode schemaNode = objectMapper.readTree(Files.readString(contractPath())); + return JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V202012).getSchema(schemaNode); + } + + private static Path contractPath() { + Path fromRoot = Path.of("checkers-contracts/ws/v1/match-found.schema.json"); + return Files.exists(fromRoot) + ? fromRoot + : Path.of("../../checkers-contracts/ws/v1/match-found.schema.json"); + } +} From 67fe17d2a3020caaa81c57f253003d7e345d5df4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Por=C4=99bski?= <164040529+TexablePlum@users.noreply.github.com> Date: Mon, 6 Jul 2026 14:34:42 +0200 Subject: [PATCH 2/9] ci(contracts): validate JSON contract instances (#77) * feat(contracts): define WebSocket payload schemas - Add draft 2020-12 contracts for authoritative game-state and player-specific match-found STOMP messages. - Document destinations, direction, recovery semantics, and additive v1 evolution rules. - Validate real publisher DTO serialization with each service's Spring-configured ObjectMapper and networknt. - Tests: game-service verify passed 214 tests; matchmaking-service verify passed 105 tests; a deliberate match-found field rename failed the contract test. * ci(contracts): validate JSON contract instances - Define the draft 2020-12 schema for the authentication protocol manifest. - Add explicit access and refresh claim instances and verify the access instance matches the compact JWT payload. - Validate auth instances plus auth, HTTP, and WebSocket schema metaschemas with check-jsonschema in CI. - Tests: the full local check-jsonschema sequence passed; JwtContractTest passed in api-gateway, user-service, game-service, and matchmaking-service. --- .github/workflows/protobuf-contracts.yml | 38 ++++++++++++++- checkers-contracts/README.md | 3 ++ checkers-contracts/auth/v1/README.md | 2 + .../auth/v1/contract.schema.json | 48 +++++++++++++++++++ checkers-contracts/auth/v1/test-vectors.json | 21 ++++++++ 5 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 checkers-contracts/auth/v1/contract.schema.json diff --git a/.github/workflows/protobuf-contracts.yml b/.github/workflows/protobuf-contracts.yml index a105363..a5458c4 100644 --- a/.github/workflows/protobuf-contracts.yml +++ b/.github/workflows/protobuf-contracts.yml @@ -86,8 +86,44 @@ jobs: python -m pip install --disable-pip-version-check check-jsonschema check-jsonschema --check-metaschema \ checkers-contracts/http/v1/api-error.schema.json \ + checkers-contracts/auth/v1/contract.schema.json \ checkers-contracts/auth/v1/access-token-claims.schema.json \ - checkers-contracts/auth/v1/refresh-token-claims.schema.json + checkers-contracts/auth/v1/refresh-token-claims.schema.json \ + checkers-contracts/ws/v1/game-state.schema.json \ + checkers-contracts/ws/v1/match-found.schema.json + check-jsonschema \ + --schemafile checkers-contracts/auth/v1/contract.schema.json \ + checkers-contracts/auth/v1/contract.json + python - <<'PY' + import base64 + import json + import os + from pathlib import Path + + vectors = json.loads( + Path("checkers-contracts/auth/v1/test-vectors.json").read_text(encoding="utf-8") + ) + encoded_payload = vectors["accessToken"].split(".")[1] + padding = "=" * (-len(encoded_payload) % 4) + token_claims = json.loads(base64.urlsafe_b64decode(encoded_payload + padding)) + if token_claims != vectors["accessClaims"]: + raise SystemExit("accessClaims does not match the compact accessToken payload") + + output = Path(os.environ["RUNNER_TEMP"]) / "auth-claim-instances" + output.mkdir() + (output / "access.json").write_text( + json.dumps(vectors["accessClaims"]), encoding="utf-8" + ) + (output / "refresh.json").write_text( + json.dumps(vectors["refreshClaims"]), encoding="utf-8" + ) + PY + check-jsonschema \ + --schemafile checkers-contracts/auth/v1/access-token-claims.schema.json \ + "$RUNNER_TEMP/auth-claim-instances/access.json" + check-jsonschema \ + --schemafile checkers-contracts/auth/v1/refresh-token-claims.schema.json \ + "$RUNNER_TEMP/auth-claim-instances/refresh.json" - name: Reject breaking changes on pull requests if: github.event_name == 'pull_request' # Same baseline guard as the push variant below: a PR whose base predates the versioned diff --git a/checkers-contracts/README.md b/checkers-contracts/README.md index 2451399..26fd161 100644 --- a/checkers-contracts/README.md +++ b/checkers-contracts/README.md @@ -34,3 +34,6 @@ Validate every JSON artifact locally with Python: python -m json.tool checkers-contracts/http/v1/api-error.schema.json > /dev/null python -m json.tool checkers-contracts/auth/v1/contract.json > /dev/null ``` + +CI additionally validates schema metaschemas, `auth/v1/contract.json`, the decoded access and refresh +claim vectors, and the `ws/v1` schemas with `check-jsonschema`. diff --git a/checkers-contracts/auth/v1/README.md b/checkers-contracts/auth/v1/README.md index 7767087..844c367 100644 --- a/checkers-contracts/auth/v1/README.md +++ b/checkers-contracts/auth/v1/README.md @@ -17,6 +17,8 @@ The schemas validate decoded payloads. JWT headers additionally require `alg = H present, remains the standard `JWT` header and is not the application token discriminator. `test-vectors.json` contains a long-lived, non-production access token representing issuer output; every Java validator consumes it to prove producer/consumer interoperability and constant parity. +The file also carries explicit access and refresh claim instances. CI verifies that the access +instance equals the compact token payload and validates both instances against their v1 schemas. ## Redis access-token blacklist diff --git a/checkers-contracts/auth/v1/contract.schema.json b/checkers-contracts/auth/v1/contract.schema.json new file mode 100644 index 0000000..eb49512 --- /dev/null +++ b/checkers-contracts/auth/v1/contract.schema.json @@ -0,0 +1,48 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://checkers.example/contracts/auth/v1/contract.schema.json", + "title": "Authentication protocol contract v1", + "type": "object", + "additionalProperties": false, + "required": ["version", "jwt", "blacklist"], + "properties": { + "version": { "const": "v1" }, + "jwt": { + "type": "object", + "additionalProperties": false, + "required": [ + "algorithm", "minimumSecretBytes", "issuer", "audience", "tokenTypeClaim", + "accessTokenType", "refreshTokenType", "jtiFormat", "subjectFormat" + ], + "properties": { + "algorithm": { "const": "HS256" }, + "minimumSecretBytes": { "type": "integer", "minimum": 32 }, + "issuer": { "const": "checkers-user-service" }, + "audience": { "const": "checkers-platform" }, + "tokenTypeClaim": { "const": "token_type" }, + "accessTokenType": { "const": "access" }, + "refreshTokenType": { "const": "refresh" }, + "jtiFormat": { "const": "uuid" }, + "subjectFormat": { "const": "uuid" } + } + }, + "blacklist": { + "type": "object", + "additionalProperties": false, + "required": [ + "keyPrefix", "keyFormat", "value", "ttlUnit", "ttlRounding", "expiredTokenBehavior", + "writeFailurePolicy", "readFailurePolicy" + ], + "properties": { + "keyPrefix": { "const": "auth:blacklist:" }, + "keyFormat": { "const": "auth:blacklist:" }, + "value": { "const": "1" }, + "ttlUnit": { "const": "seconds" }, + "ttlRounding": { "const": "ceiling" }, + "expiredTokenBehavior": { "const": "skip-write" }, + "writeFailurePolicy": { "const": "fail-closed" }, + "readFailurePolicy": { "const": "fail-open" } + } + } + } +} diff --git a/checkers-contracts/auth/v1/test-vectors.json b/checkers-contracts/auth/v1/test-vectors.json index 72073ec..b46c02a 100644 --- a/checkers-contracts/auth/v1/test-vectors.json +++ b/checkers-contracts/auth/v1/test-vectors.json @@ -1,6 +1,27 @@ { "secret": "checkers-contract-test-secret-0123456789-ABCDEFGHIJKLMNOPQRSTUVWXYZ", "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJjaGVja2Vycy11c2VyLXNlcnZpY2UiLCJhdWQiOlsiY2hlY2tlcnMtcGxhdGZvcm0iXSwic3ViIjoiMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAxIiwianRpIjoiMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAyIiwiaWF0IjoxNzA0MDY3MjAwLCJleHAiOjQxMDI0NDQ4MDAsInRva2VuX3R5cGUiOiJhY2Nlc3MiLCJzaWQiOiIwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDMiLCJ1c2VybmFtZSI6ImNvbnRyYWN0LXVzZXIiLCJlbWFpbCI6ImNvbnRyYWN0QGV4YW1wbGUuY29tIn0.KTNdSTuuU-xp9qWX5CFWApoZ86MIHfmfas9Tk5-5Fso", + "accessClaims": { + "iss": "checkers-user-service", + "aud": ["checkers-platform"], + "sub": "00000000-0000-0000-0000-000000000001", + "jti": "00000000-0000-0000-0000-000000000002", + "iat": 1704067200, + "exp": 4102444800, + "token_type": "access", + "sid": "00000000-0000-0000-0000-000000000003", + "username": "contract-user", + "email": "contract@example.com" + }, + "refreshClaims": { + "iss": "checkers-user-service", + "aud": ["checkers-platform"], + "sub": "00000000-0000-0000-0000-000000000001", + "jti": "00000000-0000-0000-0000-000000000004", + "iat": 1704067200, + "exp": 4102444800, + "token_type": "refresh" + }, "expectedUserId": "00000000-0000-0000-0000-000000000001", "expectedJti": "00000000-0000-0000-0000-000000000002", "note": "Public interoperability vector only; this secret must never be used outside tests." From 11b5fcb51f4d09d985afed27547630cae6e98d48 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Jul 2026 14:37:10 +0200 Subject: [PATCH 3/9] build(deps): bump the minor-and-patch group (#71) Bumps the minor-and-patch group in /services/game-service with 6 updates: | Package | From | To | | --- | --- | --- | | [org.springframework.boot:spring-boot-starter-parent](https://github.com/spring-projects/spring-boot) | `3.5.11` | `3.5.16` | | [org.springdoc:springdoc-openapi-starter-webmvc-ui](https://github.com/springdoc/springdoc-openapi) | `2.8.6` | `2.8.17` | | [io.jsonwebtoken:jjwt-api](https://github.com/jwtk/jjwt) | `0.12.6` | `0.13.0` | | [io.jsonwebtoken:jjwt-impl](https://github.com/jwtk/jjwt) | `0.12.6` | `0.13.0` | | io.jsonwebtoken:jjwt-jackson | `0.12.6` | `0.13.0` | | [com.google.protobuf:protobuf-java](https://github.com/protocolbuffers/protobuf) | `4.29.3` | `4.35.1` | Updates `org.springframework.boot:spring-boot-starter-parent` from 3.5.11 to 3.5.16 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.5.11...v3.5.16) Updates `org.springdoc:springdoc-openapi-starter-webmvc-ui` from 2.8.6 to 2.8.17 - [Release notes](https://github.com/springdoc/springdoc-openapi/releases) - [Changelog](https://github.com/springdoc/springdoc-openapi/blob/main/CHANGELOG.md) - [Commits](https://github.com/springdoc/springdoc-openapi/compare/v2.8.6...v2.8.17) Updates `io.jsonwebtoken:jjwt-api` from 0.12.6 to 0.13.0 - [Release notes](https://github.com/jwtk/jjwt/releases) - [Changelog](https://github.com/jwtk/jjwt/blob/main/CHANGELOG.md) - [Commits](https://github.com/jwtk/jjwt/compare/0.12.6...0.13.0) Updates `io.jsonwebtoken:jjwt-impl` from 0.12.6 to 0.13.0 - [Release notes](https://github.com/jwtk/jjwt/releases) - [Changelog](https://github.com/jwtk/jjwt/blob/main/CHANGELOG.md) - [Commits](https://github.com/jwtk/jjwt/compare/0.12.6...0.13.0) Updates `io.jsonwebtoken:jjwt-jackson` from 0.12.6 to 0.13.0 Updates `com.google.protobuf:protobuf-java` from 4.29.3 to 4.35.1 - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Commits](https://github.com/protocolbuffers/protobuf/commits) --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot-starter-parent dependency-version: 3.5.16 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: minor-and-patch - dependency-name: org.springdoc:springdoc-openapi-starter-webmvc-ui dependency-version: 2.8.17 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: minor-and-patch - dependency-name: io.jsonwebtoken:jjwt-api dependency-version: 0.13.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: minor-and-patch - dependency-name: io.jsonwebtoken:jjwt-impl dependency-version: 0.13.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: minor-and-patch - dependency-name: io.jsonwebtoken:jjwt-jackson dependency-version: 0.13.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: minor-and-patch - dependency-name: com.google.protobuf:protobuf-java dependency-version: 4.35.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: minor-and-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- services/game-service/pom.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/services/game-service/pom.xml b/services/game-service/pom.xml index b16862a..1112036 100644 --- a/services/game-service/pom.xml +++ b/services/game-service/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.11 + 3.5.16 com.checkers @@ -16,7 +16,7 @@ 21 1.82.1 - 4.29.3 + 4.35.1 0.8.15 @@ -43,7 +43,7 @@ org.springdoc springdoc-openapi-starter-webmvc-ui - 2.8.6 + 2.8.17 org.springframework.boot @@ -79,18 +79,18 @@ io.jsonwebtoken jjwt-api - 0.12.6 + 0.13.0 io.jsonwebtoken jjwt-impl - 0.12.6 + 0.13.0 runtime io.jsonwebtoken jjwt-jackson - 0.12.6 + 0.13.0 runtime From f465e779bf586652b56af9a24d2605c826e08a13 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Jul 2026 14:37:13 +0200 Subject: [PATCH 4/9] build(deps): bump the minor-and-patch group (#72) Bumps the minor-and-patch group in /services/user-service with 6 updates: | Package | From | To | | --- | --- | --- | | [org.springframework.boot:spring-boot-starter-parent](https://github.com/spring-projects/spring-boot) | `3.5.11` | `3.5.16` | | [org.springdoc:springdoc-openapi-starter-webmvc-ui](https://github.com/springdoc/springdoc-openapi) | `2.8.6` | `2.8.17` | | [com.google.protobuf:protobuf-java](https://github.com/protocolbuffers/protobuf) | `4.29.3` | `4.35.1` | | [io.jsonwebtoken:jjwt-api](https://github.com/jwtk/jjwt) | `0.12.6` | `0.13.0` | | [io.jsonwebtoken:jjwt-impl](https://github.com/jwtk/jjwt) | `0.12.6` | `0.13.0` | | io.jsonwebtoken:jjwt-jackson | `0.12.6` | `0.13.0` | Updates `org.springframework.boot:spring-boot-starter-parent` from 3.5.11 to 3.5.16 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.5.11...v3.5.16) Updates `org.springdoc:springdoc-openapi-starter-webmvc-ui` from 2.8.6 to 2.8.17 - [Release notes](https://github.com/springdoc/springdoc-openapi/releases) - [Changelog](https://github.com/springdoc/springdoc-openapi/blob/main/CHANGELOG.md) - [Commits](https://github.com/springdoc/springdoc-openapi/compare/v2.8.6...v2.8.17) Updates `com.google.protobuf:protobuf-java` from 4.29.3 to 4.35.1 - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Commits](https://github.com/protocolbuffers/protobuf/commits) Updates `io.jsonwebtoken:jjwt-api` from 0.12.6 to 0.13.0 - [Release notes](https://github.com/jwtk/jjwt/releases) - [Changelog](https://github.com/jwtk/jjwt/blob/main/CHANGELOG.md) - [Commits](https://github.com/jwtk/jjwt/compare/0.12.6...0.13.0) Updates `io.jsonwebtoken:jjwt-impl` from 0.12.6 to 0.13.0 - [Release notes](https://github.com/jwtk/jjwt/releases) - [Changelog](https://github.com/jwtk/jjwt/blob/main/CHANGELOG.md) - [Commits](https://github.com/jwtk/jjwt/compare/0.12.6...0.13.0) Updates `io.jsonwebtoken:jjwt-jackson` from 0.12.6 to 0.13.0 --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot-starter-parent dependency-version: 3.5.16 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: minor-and-patch - dependency-name: org.springdoc:springdoc-openapi-starter-webmvc-ui dependency-version: 2.8.17 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: minor-and-patch - dependency-name: com.google.protobuf:protobuf-java dependency-version: 4.35.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: minor-and-patch - dependency-name: io.jsonwebtoken:jjwt-api dependency-version: 0.13.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: minor-and-patch - dependency-name: io.jsonwebtoken:jjwt-impl dependency-version: 0.13.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: minor-and-patch - dependency-name: io.jsonwebtoken:jjwt-jackson dependency-version: 0.13.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: minor-and-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- services/user-service/pom.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/services/user-service/pom.xml b/services/user-service/pom.xml index 3a74816..1553453 100644 --- a/services/user-service/pom.xml +++ b/services/user-service/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.11 + 3.5.16 com.checkers @@ -29,7 +29,7 @@ 21 1.82.1 - 4.29.3 + 4.35.1 0.8.15 @@ -73,7 +73,7 @@ org.springdoc springdoc-openapi-starter-webmvc-ui - 2.8.6 + 2.8.17 @@ -128,18 +128,18 @@ io.jsonwebtoken jjwt-api - 0.12.6 + 0.13.0 io.jsonwebtoken jjwt-impl - 0.12.6 + 0.13.0 runtime io.jsonwebtoken jjwt-jackson - 0.12.6 + 0.13.0 runtime From 349ff93934bc92fbe9fbcf809b621a2f09f35a05 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Jul 2026 14:37:15 +0200 Subject: [PATCH 5/9] build(deps): bump the minor-and-patch group (#74) Bumps the minor-and-patch group in /services/matchmaking-service with 6 updates: | Package | From | To | | --- | --- | --- | | [org.springframework.boot:spring-boot-starter-parent](https://github.com/spring-projects/spring-boot) | `3.5.11` | `3.5.16` | | [org.springdoc:springdoc-openapi-starter-webmvc-ui](https://github.com/springdoc/springdoc-openapi) | `2.8.6` | `2.8.17` | | [io.jsonwebtoken:jjwt-api](https://github.com/jwtk/jjwt) | `0.12.6` | `0.13.0` | | [io.jsonwebtoken:jjwt-impl](https://github.com/jwtk/jjwt) | `0.12.6` | `0.13.0` | | io.jsonwebtoken:jjwt-jackson | `0.12.6` | `0.13.0` | | [org.jacoco:jacoco-maven-plugin](https://github.com/jacoco/jacoco) | `0.8.13` | `0.8.15` | Updates `org.springframework.boot:spring-boot-starter-parent` from 3.5.11 to 3.5.16 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.5.11...v3.5.16) Updates `org.springdoc:springdoc-openapi-starter-webmvc-ui` from 2.8.6 to 2.8.17 - [Release notes](https://github.com/springdoc/springdoc-openapi/releases) - [Changelog](https://github.com/springdoc/springdoc-openapi/blob/main/CHANGELOG.md) - [Commits](https://github.com/springdoc/springdoc-openapi/compare/v2.8.6...v2.8.17) Updates `io.jsonwebtoken:jjwt-api` from 0.12.6 to 0.13.0 - [Release notes](https://github.com/jwtk/jjwt/releases) - [Changelog](https://github.com/jwtk/jjwt/blob/main/CHANGELOG.md) - [Commits](https://github.com/jwtk/jjwt/compare/0.12.6...0.13.0) Updates `io.jsonwebtoken:jjwt-impl` from 0.12.6 to 0.13.0 - [Release notes](https://github.com/jwtk/jjwt/releases) - [Changelog](https://github.com/jwtk/jjwt/blob/main/CHANGELOG.md) - [Commits](https://github.com/jwtk/jjwt/compare/0.12.6...0.13.0) Updates `io.jsonwebtoken:jjwt-jackson` from 0.12.6 to 0.13.0 Updates `org.jacoco:jacoco-maven-plugin` from 0.8.13 to 0.8.15 - [Release notes](https://github.com/jacoco/jacoco/releases) - [Commits](https://github.com/jacoco/jacoco/compare/v0.8.13...v0.8.15) --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot-starter-parent dependency-version: 3.5.16 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: minor-and-patch - dependency-name: org.springdoc:springdoc-openapi-starter-webmvc-ui dependency-version: 2.8.17 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: minor-and-patch - dependency-name: io.jsonwebtoken:jjwt-api dependency-version: 0.13.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: minor-and-patch - dependency-name: io.jsonwebtoken:jjwt-impl dependency-version: 0.13.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: minor-and-patch - dependency-name: io.jsonwebtoken:jjwt-jackson dependency-version: 0.13.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: minor-and-patch - dependency-name: org.jacoco:jacoco-maven-plugin dependency-version: 0.8.15 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: minor-and-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- services/matchmaking-service/pom.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/services/matchmaking-service/pom.xml b/services/matchmaking-service/pom.xml index a57b72a..132d290 100644 --- a/services/matchmaking-service/pom.xml +++ b/services/matchmaking-service/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.11 + 3.5.16 com.checkers @@ -17,7 +17,7 @@ 21 1.82.1 4.35.1 - 0.8.13 + 0.8.15