From 1c021b896d7c66b5d84c625df4ca8654874c6fcc Mon Sep 17 00:00:00 2001 From: Dereku92 Date: Sun, 22 Mar 2026 06:53:50 +0800 Subject: [PATCH 1/2] fix: use generic default database name and add iterations .gitignore - Change hardcoded default database name in cosmos_database fixture from 'gaming-leaderboard-db' to 'test-db'. The previous default was specific to the gaming-leaderboard scenario and would silently use the wrong database for other scenarios when iteration-config.yaml omits the 'database' field. - Add .gitignore to each scenario's iterations/ directory to prevent accidentally committing language-specific build artifacts (node_modules, __pycache__, bin/obj, target, etc.) and CI temp files. --- testing-v2/harness/conftest_base.py | 2 +- .../ai-chat-rag/iterations/.gitignore | 21 +++++++++++++++++++ .../ecommerce-order-api/iterations/.gitignore | 21 +++++++++++++++++++ .../gaming-leaderboard/iterations/.gitignore | 21 +++++++++++++++++++ .../iterations/.gitignore | 21 +++++++++++++++++++ .../multitenant-saas/iterations/.gitignore | 21 +++++++++++++++++++ 6 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 testing-v2/scenarios/ai-chat-rag/iterations/.gitignore create mode 100644 testing-v2/scenarios/ecommerce-order-api/iterations/.gitignore create mode 100644 testing-v2/scenarios/gaming-leaderboard/iterations/.gitignore create mode 100644 testing-v2/scenarios/iot-device-telemetry/iterations/.gitignore create mode 100644 testing-v2/scenarios/multitenant-saas/iterations/.gitignore diff --git a/testing-v2/harness/conftest_base.py b/testing-v2/harness/conftest_base.py index 1c1699c5..2d2dbf47 100644 --- a/testing-v2/harness/conftest_base.py +++ b/testing-v2/harness/conftest_base.py @@ -228,7 +228,7 @@ def cosmos_client(): @pytest.fixture(scope="session") def cosmos_database(cosmos_client, iteration_config): """The Cosmos DB database used by the app.""" - db_name = iteration_config.get("database", "gaming-leaderboard-db") + db_name = iteration_config.get("database", "test-db") return cosmos_client.get_database_client(db_name) diff --git a/testing-v2/scenarios/ai-chat-rag/iterations/.gitignore b/testing-v2/scenarios/ai-chat-rag/iterations/.gitignore new file mode 100644 index 00000000..ac29147f --- /dev/null +++ b/testing-v2/scenarios/ai-chat-rag/iterations/.gitignore @@ -0,0 +1,21 @@ +# Build artifacts (per-language) +__pycache__/ +*.pyc +*.pyo +node_modules/ +bin/ +obj/ +target/ +.gradle/ +build/ +dist/ +*.egg-info/ +venv/ +.venv/ + +# Runtime logs and temp files +app-output.log +app-error.log +_start-app.cmd +build-output.log +build-error.log diff --git a/testing-v2/scenarios/ecommerce-order-api/iterations/.gitignore b/testing-v2/scenarios/ecommerce-order-api/iterations/.gitignore new file mode 100644 index 00000000..ac29147f --- /dev/null +++ b/testing-v2/scenarios/ecommerce-order-api/iterations/.gitignore @@ -0,0 +1,21 @@ +# Build artifacts (per-language) +__pycache__/ +*.pyc +*.pyo +node_modules/ +bin/ +obj/ +target/ +.gradle/ +build/ +dist/ +*.egg-info/ +venv/ +.venv/ + +# Runtime logs and temp files +app-output.log +app-error.log +_start-app.cmd +build-output.log +build-error.log diff --git a/testing-v2/scenarios/gaming-leaderboard/iterations/.gitignore b/testing-v2/scenarios/gaming-leaderboard/iterations/.gitignore new file mode 100644 index 00000000..ac29147f --- /dev/null +++ b/testing-v2/scenarios/gaming-leaderboard/iterations/.gitignore @@ -0,0 +1,21 @@ +# Build artifacts (per-language) +__pycache__/ +*.pyc +*.pyo +node_modules/ +bin/ +obj/ +target/ +.gradle/ +build/ +dist/ +*.egg-info/ +venv/ +.venv/ + +# Runtime logs and temp files +app-output.log +app-error.log +_start-app.cmd +build-output.log +build-error.log diff --git a/testing-v2/scenarios/iot-device-telemetry/iterations/.gitignore b/testing-v2/scenarios/iot-device-telemetry/iterations/.gitignore new file mode 100644 index 00000000..ac29147f --- /dev/null +++ b/testing-v2/scenarios/iot-device-telemetry/iterations/.gitignore @@ -0,0 +1,21 @@ +# Build artifacts (per-language) +__pycache__/ +*.pyc +*.pyo +node_modules/ +bin/ +obj/ +target/ +.gradle/ +build/ +dist/ +*.egg-info/ +venv/ +.venv/ + +# Runtime logs and temp files +app-output.log +app-error.log +_start-app.cmd +build-output.log +build-error.log diff --git a/testing-v2/scenarios/multitenant-saas/iterations/.gitignore b/testing-v2/scenarios/multitenant-saas/iterations/.gitignore new file mode 100644 index 00000000..ac29147f --- /dev/null +++ b/testing-v2/scenarios/multitenant-saas/iterations/.gitignore @@ -0,0 +1,21 @@ +# Build artifacts (per-language) +__pycache__/ +*.pyc +*.pyo +node_modules/ +bin/ +obj/ +target/ +.gradle/ +build/ +dist/ +*.egg-info/ +venv/ +.venv/ + +# Runtime logs and temp files +app-output.log +app-error.log +_start-app.cmd +build-output.log +build-error.log From 61d5bbb9bc3893b33d2d52e316b02677a9077d16 Mon Sep 17 00:00:00 2001 From: Dereku92 Date: Sun, 22 Mar 2026 06:58:24 +0800 Subject: [PATCH 2/2] fix(rule): add @JsonIgnoreProperties(ignoreUnknown=true) requirement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses #28 — Cosmos DB entity classes without this annotation fail with UnrecognizedPropertyException on system metadata fields (_lsn, _rid, _ts, _etag, _self) during Change Feed deserialization. This was the most prevalent defect in SCOPE evaluation (94% hit rate across all profiles). Added as Rule 5 in model-json-serialization. --- .../rules/model-json-serialization.md | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/skills/cosmosdb-best-practices/rules/model-json-serialization.md b/skills/cosmosdb-best-practices/rules/model-json-serialization.md index de83f83b..5acc4815 100644 --- a/skills/cosmosdb-best-practices/rules/model-json-serialization.md +++ b/skills/cosmosdb-best-practices/rules/model-json-serialization.md @@ -2,7 +2,7 @@ title: Handle JSON serialization correctly for Cosmos DB documents impact: HIGH impactDescription: prevents data loss, null constructor errors, and serialization failures -tags: model, serialization, json, jackson, jsonignore, jsonproperty, bigdecimal +tags: model, serialization, json, jackson, jsonignore, jsonproperty, bigdecimal, jsonignoreproperties, change-feed --- ## Handle JSON Serialization Correctly for Cosmos DB @@ -139,4 +139,36 @@ private Set authorities; Convert between simple and complex types in the service layer, not in the entity. +**Rule 5: Always add `@JsonIgnoreProperties(ignoreUnknown = true)` to entity classes** + +Cosmos DB documents contain system metadata fields (`_rid`, `_self`, `_etag`, `_ts`, `_lsn`) that are not part of your entity model. Without this annotation, Jackson throws `UnrecognizedPropertyException` when deserializing documents — especially during Change Feed processing where these fields are always present: + +``` +com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: + Unrecognized field "_lsn" (class PlayerProfile), not marked as ignorable +``` + +```java +// ❌ Fails on system metadata fields from Cosmos DB +@Container(containerName = "players") +public class PlayerProfile { + @Id + private String id; + private String playerId; + private int score; +} + +// ✅ Ignores unknown fields — safe for Cosmos DB system metadata +@JsonIgnoreProperties(ignoreUnknown = true) +@Container(containerName = "players") +public class PlayerProfile { + @Id + private String id; + private String playerId; + private int score; +} +``` + +This is critical for Change Feed consumers where system metadata fields are always included in the document payload. + Reference: [Jackson annotations guide](https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations)