Skip to content

feat(api)!: complete entity dynamic mapping dry-run workflow - #99

Open
foukou19 wants to merge 9 commits into
mainfrom
feat/idp-core-entity-dynamic-mapping-dry-run
Open

feat(api)!: complete entity dynamic mapping dry-run workflow#99
foukou19 wants to merge 9 commits into
mainfrom
feat/idp-core-entity-dynamic-mapping-dry-run

Conversation

@foukou19

@foukou19 foukou19 commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

PR Description

feat(entity-dynamic-mapping): implement dry-run endpoint and add relations support to entity dynamic mappings

What this PR Provides

New Feature: Dry-Run Endpoint

  • Created /api/v1/entity_dynamic_mappings/dry-run POST endpoint: Allows users to validate JSLT mapping definitions against sample payloads without persisting data
  • Dry-run response structure: Returns validation results including:
    • Extracted entity (identifier, name, properties)
    • Extracted relations with name and target entity identifiers
    • Success/error status and error details for failed mappings
  • New DTOs for dry-run:
    • EntityDynamicMappingDryRunDtoIn - Request input with mapping definition and sample payload
    • EntityDynamicMappingDryRunDtoOut - Response with DryRunEntityDto containing properties AND relations
    • DryRunRelationDto - Serialization format for extracted relations

Relations Support for Entity Dynamic Mappings

  • Updated data model:
    • EntityMappingDtoIn now includes relations: List<RelationMappingDtoIn> (array format)
    • RelationMappingDtoIn contains name and target_entity_identifiers: List<String>
    • Domain model RelationMapping stores name and list of JSLT expressions
  • Fixed database migration: V6_4 now correctly generates expressions array format (not singular expression)

Enhanced Test Coverage

  • Integration tests for dry-run endpoint:
    • Success case: validates properties and relations extraction
    • APIM API scenario: multiple relations with payload traversal
    • Failure cases: missing properties, template not found, expression errors
    • Skipped payloads: filter excludes the event
  • Relation-specific tests:
    • Unit tests for deserialization: accepts both object map and array formats
    • Integration tests validate RelationMappingDtoOut serialization
    • Tests for null/empty relations handling
  • Updated test fixtures:
    • Added api-link relation to microservice template
    • Enhanced webhook test data with real relation expressions
    • Created component entities for relation targets

Review

The reviewer must double-check these points:

  • The reviewer has tested the new dry-run endpoint with both simple and complex APIM API payloads
  • The reviewer has verified relations are correctly extracted and returned in dry-run response
  • The reviewer has confirmed GET and POST mapping endpoints include relations in responses
  • The reviewer has tested deserialization of both object map ({"name": "expr"}) and array ([{"name":"...","target_entity_identifiers":[...]}]) formats
  • The reviewer has verified null/empty relations are handled gracefully
  • The reviewer confirmed code coverage for dry-run and relation handling remains above 80%
  • The reviewer validated database migration V6_4 produces correct JSONB format

How to test

Initial State

1.Microservice and APIM API templates exist with relation definitions

What and How to Test

Test 1: Simple Dry-Run (Properties Only)

  1. POST to /api/v1/entity_dynamic_mappings/dry-run:
    {
      "mapping": {
        "identifier": "github-dry-run",
        "entity_template_identifier": "microservice",
        "filter": ".action == \"pushed\"",
        "name": "GitHub mapping",
        "entity": {
          "identifier": ".repository.full_name",
          "name": ".repository.name",
          "properties": {
            "applicationName": ".repository.name",
            "ownerEmail": ".sender.email",
            "environment": "\"DEV\"",
            "version": ".ref",
            "port": "8080",
            "programmingLanguage": ".repository.language"
          },
          "relations": []
        }
      },
      "payload": {
        "action": "pushed",
        "repository": {
          "full_name": "org/repo",
          "name": "repo",
          "language": "Java"
        },
        "ref": "1.0.0",
        "sender": {"email": "user@example.com"}
      }
    }
  2. Verify response includes extracted properties with status 200

Test 2: Dry-Run with Relations (APIM API)

  1. POST to /api/v1/entity_dynamic_mappings/dry-run with APIM API mapping containing relations:
    {
      "mapping": {
        "entity_template_identifier": "apim-api",
        "entity": {
          "relations": [
            {
              "name": "apim-api-consumed_by-component",
              "target_entity_identifiers": [".relations.\"apim-api-consumed_by-component\""]
            }
          ]
        }
      },
      "payload": {
        "relations": {
          "apim-api-consumed_by-component": [
            {"identifier": "e5d9813e-b16f-4f24-bdf9-376f18f3a9ac", "name": "sportyswap-be"},
            {"identifier": "f2e2ab44-5d19-44de-a77a-42ef6aa51676", "name": "user-profile-sync"}
          ]
        }
      }
    }
  2. Verify response includes:
    • entity.relations[0].name: "apim-api-consumed_by-component"
    • entity.relations[0].target_entity_identifiers: array with 2 component UUIDs
  3. Verify HTTP 200 with success

Test 3: Dry-Run Error - Missing Required Properties

  1. POST dry-run with incomplete properties mapping
  2. Verify response includes error details and status success=false with error type

Test 4: Create Mapping with Relations

  1. POST to /api/v1/entity_dynamic_mappings with mapping containing relations
  2. Verify response includes entity.relations in returned object
  3. Verify HTTP 201 Created

Test 5: Get Mapping - Relations Persistence

  1. GET /api/v1/entity_dynamic_mappings/microservice-mapping
  2. Verify response includes entity.relations[] with correct format
  3. Relations should match what was created (persisted in JSONB)

Test 6: Relations Format Compatibility

  1. Test deserialization with legacy object map format:
    "relations": {"relation-name": ".expression"}
  2. Test new array format:
    "relations": [{"name": "relation-name", "target_entity_identifiers": [".expression"]}]
  3. Both should deserialize correctly and extract relations

Expected Results

  • Dry-run endpoint validates JSLT filter, properties extraction, and relations extraction
  • Response includes all extracted entity data (identifier, name, properties, relations)
  • Relations are serialized with target_entity_identifiers as array
  • Dry-run shows exactly what would be persisted by POST endpoint
  • No data is persisted by dry-run endpoint
  • GET and POST endpoints return relations in consistent format
  • Both object map and array formats for relations are accepted during input
  • 80%+ code coverage for dry-run and relations logic

Breaking Changes

N/A

No breaking changes introduced:

  • API Response: Relations field is new and additive - existing clients without relations continue unchanged
  • API Input: Relations are optional - mappings without relations work as before
  • Database: JSONB relations column already exists; format now consistent across all operations
  • Deserialization: Backward compatibility with multiple input formats (object map or array)

Context & Rationale

Why Dry-Run?

Previously, users had to save a mapping and manually verify it worked. The dry-run endpoint provides:

  • Validation before persistence: Test JSLT filter and expressions against real payloads
  • Visibility into extraction: See exactly what identifier, name, properties, and relations will be extracted
  • Safety: No data written, no relations created - pure validation

@foukou19
foukou19 marked this pull request as draft July 21, 2026 11:26
@foukou19 foukou19 changed the title feat(mapping): implement entity dynamic mapping dry-run workflow for … feat(mapping): complete entity dynamic mapping dry-run workflow Jul 21, 2026
@github-code-quality

github-code-quality Bot commented Jul 21, 2026

Copy link
Copy Markdown

Code Coverage Overview

Languages: Java

Java / code-coverage/jacoco

The overall coverage in commit e73413c in the feat/idp-core-entity... branch remains at 90%, unchanged from commit fb2197a in the main branch.

Show a code coverage summary of the most impacted files.
File main fb2197a feat/idp-core-entity... e73413c +/-
com/decathlon/i...sonbHelper.java 58% 68% +10%
com/decathlon/i...ionService.java 84% 97% +13%
com/decathlon/i...serializer.java 0% 78% +78%
com/decathlon/i...ineAdapter.java 0% 81% +81%
com/decathlon/i...RunService.java 0% 100% +100%
com/decathlon/i...yRunDtoOut.java 0% 100% +100%
com/decathlon/i...yRunResult.java 0% 100% +100%
com/decathlon/i...oOutMapper.java 0% 100% +100%
com/decathlon/i...nEvaluator.java 0% 100% +100%
com/decathlon/i...JsltEngine.java 0% 100% +100%

Updated July 29, 2026 06:42 UTC

@foukou19 foukou19 changed the title feat(mapping): complete entity dynamic mapping dry-run workflow feat(api): complete entity dynamic mapping dry-run workflow Jul 21, 2026
Signed-off-by: foukou19 <ferial.oukoukas@decathlon.com>
Copilot AI review requested due to automatic review settings July 24, 2026 09:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a complete entity dynamic mapping dry-run flow to the API and refactors dynamic-mapping relations from a JSON object/map to an ordered list, enabling richer relation extraction (scalar/array/object payload shapes) and better validation/error reporting.

Changes:

  • Introduce POST /api/v1/entity-dynamic-mappings/dry-run with request/response DTOs and mappers, returning per-mapping dry-run results.
  • Refactor EntityDynamicMapping.relations from Map<String,String> to List<RelationMapping> across domain/API/persistence, including Flyway migration and deserialization support for both legacy and new API formats.
  • Add a JSLT-based MappingEnginePort implementation with expression evaluation fallback and improved validation/exception mapping (incl. 422 responses).

Reviewed changes

Copilot reviewed 47 out of 50 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/test/resources/db/test/R__4_insert_webhook_test_data.sql Adjust test seed data relations JSON shape to array ([]).
src/test/java/com/decathlon/idp_core/infrastructure/adapters/persistence/EntityDynamicMappingAdaptorTest.java Update persistence adapter tests for relations list.
src/test/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/JsltMappingEngineAdapterTest.java New unit tests for relation extraction across payload shapes.
src/test/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/JsltEntityMappingValidatorTest.java Update validator tests for new relations model + new exception type.
src/test/java/com/decathlon/idp_core/infrastructure/adapters/api/mapper/webhook/InboundWebhookMapperTest.java Update mapper test to use RelationMapping.
src/test/java/com/decathlon/idp_core/infrastructure/adapters/api/handler/ApiExceptionHandlerTest.java Update expected HTTP status codes (400 → 422) for mapping validation errors.
src/test/java/com/decathlon/idp_core/infrastructure/adapters/api/dto/in/EntityMappingDtoInDeserializationTest.java New tests ensuring relations can deserialize from object-map or array formats.
src/test/java/com/decathlon/idp_core/infrastructure/adapters/api/controller/InboundWebhookManagementControllerTest.java Update controller tests payload relations JSON to array.
src/test/java/com/decathlon/idp_core/infrastructure/adapters/api/controller/EntityDynamicMappingControllerTest.java Add dry-run endpoint tests + update relations JSON + 422 expectations.
src/test/java/com/decathlon/idp_core/domain/service/webhook/WebhookConnectorValidationServiceTest.java Update domain tests for relations list.
src/test/java/com/decathlon/idp_core/domain/service/webhook/WebhookConnectorServiceTest.java Update domain tests for relations list.
src/test/java/com/decathlon/idp_core/domain/service/webhook/EntityDynamicMappingValidationServiceTest.java Update mapping validation tests + helper conversion to RelationMapping.
src/test/java/com/decathlon/idp_core/domain/service/webhook/DynamicMappingServiceTest.java Update mapping merge tests for relations list.
src/test/java/com/decathlon/idp_core/domain/service/relation/RelationValidationServiceTest.java Add dry-run relation validation behavior test (skip DB existence checks).
src/test/java/com/decathlon/idp_core/domain/service/entity_dynamic_mapping/EntityDynamicMappingDryRunServiceTest.java New unit tests for dry-run service behavior and error paths.
src/main/resources/db/migration/V6_4__migrate_entity_dynamic_mapping_relations_to_array.sql New Flyway migration to convert relations JSON from object to array.
src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/mapper/EntityDynamicMappingPersistenceMapper.java Switch relations mapping to list (new MapStruct qualifiers).
src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/mapper/common/EntityDynamicMappingJsonbHelper.java Add JSONB (de)serialization helpers for relations list.
src/main/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/JsltMappingEngineAdapter.java New mapping engine adapter extracting entity + relations from payload via JSLT.
src/main/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/JsltExpressionEvaluator.java New evaluator with current-node/root fallback and dedicated failure exception.
src/main/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/JsltEntityMappingValidator.java Refactor validator to use ExpressionEngine abstraction + relation list validation.
src/main/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/JsltEngine.java New JSLT engine implementing expression validation/evaluation abstraction.
src/main/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/JsltConfiguration.java New Spring configuration for JSLT mapping components.
src/main/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/engine/ExpressionEngine.java New infra abstraction for expression engines (JSLT/JQ/etc.).
src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/mapper/entity_dynamic_mapping/EntityDynamicMappingMapper.java Map inbound/outbound relations via RelationMapping list DTOs.
src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/mapper/entity_dynamic_mapping/EntityDynamicMappingDryRunDtoOutMapper.java New mapper from domain dry-run result to API response DTO.
src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/mapper/entity_dynamic_mapping/EntityDynamicMappingDryRunDtoInMapper.java New mapper normalizing payload object/string to raw JSON string.
src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/handler/ApiExceptionHandler.java Map additional mapping/evaluation exceptions to HTTP 422.
src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/dto/out/entity_dynamic_mapping/RelationMappingDtoOut.java New outbound DTO for relation mapping definition.
src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/dto/out/entity_dynamic_mapping/EntityDynamicMappingDtoOut.java Update outbound DTO to expose relations as ordered list.
src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/dto/out/entity_dynamic_mapping/EntityDynamicMappingDryRunDtoOut.java New dry-run response DTO (snake_case).
src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/dto/in/RelationMappingsDeserializer.java New deserializer accepting relations as legacy map or new array format.
src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/dto/in/RelationMappingDtoIn.java New inbound DTO for relation mappings.
src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/dto/in/EntityMappingDtoIn.java Update inbound entity mapping DTO to relations list with custom deserializer.
src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/dto/in/EntityDynamicMappingDryRunDtoIn.java New dry-run request DTO allowing payload as string or object.
src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/controller/EntityDynamicMappingController.java Add /dry-run endpoint wiring DTO mappers + domain service.
src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/configuration/SwaggerDescription.java Add Swagger strings for new dry-run endpoint and payload description.
src/main/java/com/decathlon/idp_core/domain/service/relation/RelationValidationService.java Add dry-run relation validation method skipping DB existence checks.
src/main/java/com/decathlon/idp_core/domain/service/entity/EntityValidationService.java Add dry-run entity validation method (skip uniqueness + target existence).
src/main/java/com/decathlon/idp_core/domain/service/entity_dynamic_mapping/EntityDynamicMappingValidationService.java Update template relation-name validation for ordered relation list.
src/main/java/com/decathlon/idp_core/domain/service/entity_dynamic_mapping/EntityDynamicMappingService.java Rename injected validation service field and use it consistently.
src/main/java/com/decathlon/idp_core/domain/service/entity_dynamic_mapping/EntityDynamicMappingDryRunService.java New domain service executing mapping dry-run and validating result.
src/main/java/com/decathlon/idp_core/domain/port/MappingEnginePort.java New domain port for mapping engine operations.
src/main/java/com/decathlon/idp_core/domain/model/enums/ErrorType.java New enum classifying dry-run errors (skipped/jslt/validation).
src/main/java/com/decathlon/idp_core/domain/model/entity_mapping/RelationMapping.java New domain record for ordered relation mappings with multiple expressions.
src/main/java/com/decathlon/idp_core/domain/model/entity_mapping/EntityDynamicMapping.java Change relations type to List<RelationMapping> and normalize nulls.
src/main/java/com/decathlon/idp_core/domain/model/entity_mapping/DryRunResult.java New domain model representing dry-run outcomes.
src/main/java/com/decathlon/idp_core/domain/exception/entity_dynamic_mapping/ExpressionEvaluationFailedException.java New exception for expression evaluation failure on both current/root nodes.
src/main/java/com/decathlon/idp_core/domain/exception/entity_dynamic_mapping/EntityDynamicMappingJsltErrorException.java New exception category for 422 mapping/JSLT errors.
src/main/java/com/decathlon/idp_core/domain/constant/ValidationMessages.java Add dry-run validation/result messages.
Comments suppressed due to low confidence (1)

src/main/resources/db/migration/V6_4__migrate_entity_dynamic_mapping_relations_to_array.sql:26

  • The column comment documents the migrated JSON format using an 'expression' field, but the code serializes/deserializes RelationMapping with an 'expressions' array. Keeping the comment consistent helps avoid inserting the wrong JSON shape and ending up with null expressions.

Comment on lines +12 to +16
SELECT COALESCE(
jsonb_agg(jsonb_build_object('name', key, 'expression', value) ORDER BY key),
'[]'::jsonb
)
FROM jsonb_each_text(relations)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already fixed

Comment on lines +57 to +61
/// Converts JSONB array string to `List<RelationMapping>`.
///
/// Expected format: `[{"name": "owner", "expression": ".sender.login"}]`
///
/// Used when loading relations from database.
Comment on lines +1 to +19
package com.decathlon.idp_core.infrastructure.adapters.entity_mapping.jslt;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.fasterxml.jackson.databind.ObjectMapper;

/// Spring configuration for JSLT mapping adapter infrastructure.
/// Provides shared JSON serialization for payload parsing and expression evaluation.
@Configuration
public class JsltConfiguration {

/// Provides a shared ObjectMapper bean for mapping adapters.
/// Bean scope is singleton and safe for concurrent reuse.
@Bean
public ObjectMapper objectMapper() {
return new ObjectMapper();
}
}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already fixed with @ConditionalOnMissingBean(ObjectMapper.class)

Comment on lines +16 to +21
@Component
@RequiredArgsConstructor
public class EntityDynamicMappingDryRunDtoInMapper {

private final ObjectMapper objectMapper = new ObjectMapper();

Comment on lines +3 to +6
import java.util.Optional;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

Copilot AI review requested due to automatic review settings July 24, 2026 09:50
@foukou19
foukou19 force-pushed the feat/idp-core-entity-dynamic-mapping-dry-run branch from b2e78a6 to 3c808f8 Compare July 24, 2026 09:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 47 out of 50 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (7)

src/main/resources/db/migration/V6_4__migrate_entity_dynamic_mapping_relations_to_array.sql:15

  • The migration converts legacy relation objects into array items with an expression string field, but the Java model/persistence mapper expects RelationMapping with an expressions list. As-is, existing rows will deserialize incorrectly (or fail) after the migration.
    src/main/resources/db/migration/V6_4__migrate_entity_dynamic_mapping_relations_to_array.sql:6
  • The migration header comment documents the new relations format using {name, expression} but the codebase now models relations as {name, expressions:[...]}. Keeping this comment aligned will avoid confusion for future migrations/operations.
    src/main/resources/db/migration/V6_4__migrate_entity_dynamic_mapping_relations_to_array.sql:26
  • The column comment still describes the old {name, expression} format. After the migration (and with RelationMapping.expressions), the persisted JSON should document expressions as an array.
    src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/mapper/common/EntityDynamicMappingJsonbHelper.java:21
  • The class-level docs say relations are stored as {name, expression} but persistence now serializes/deserializes RelationMapping, whose JSON shape will be {name, expressions:[...]} (record component name). The docs should match the actual persisted format to prevent future mismigrations.
    src/main/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/JsltExpressionEvaluator.java:5
  • java.util.stream.Stream is imported but never used; unused imports are compilation errors in Java.
    src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/mapper/entity_dynamic_mapping/EntityDynamicMappingDryRunDtoInMapper.java:21
  • This Spring component creates its own ObjectMapper instance, which bypasses the application’s Jackson configuration (modules, features, naming, etc.) and makes behavior diverge from the rest of the API. Prefer constructor injection of the shared ObjectMapper bean.
@Component
@RequiredArgsConstructor
public class EntityDynamicMappingDryRunDtoInMapper {

  private final ObjectMapper objectMapper = new ObjectMapper();

src/main/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/JsltConfiguration.java:18

  • Defining a bare @Bean ObjectMapper here will disable Spring Boot’s Jackson auto-configuration and can subtly break JSON (de)serialization across the whole API (missing modules like JavaTimeModule, custom naming/features, etc.). Consider removing this bean and injecting the Boot-managed ObjectMapper, or naming/qualifying a dedicated mapper for JSLT only so it doesn’t replace the global one.
@Configuration
public class JsltConfiguration {

  /// Provides a shared ObjectMapper bean for mapping adapters.
  /// Bean scope is singleton and safe for concurrent reuse.
  @Bean
  public ObjectMapper objectMapper() {
    return new ObjectMapper();
  }

Comment on lines 41 to 48
if (mapping.relations() != null && !mapping.relations().isEmpty()) {
mapping.relations().forEach((key, expr) -> checkExpression(errors, "relations." + key, expr));
mapping.relations().forEach(relation -> {
if (relation.expressions() != null && !relation.expressions().isEmpty()) {
relation.expressions().forEach(
expr -> checkExpression(errors, "relations." + relation.name() + "[]", expr));
}
});
}
Copilot AI review requested due to automatic review settings July 24, 2026 09:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 47 out of 50 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (2)

src/main/resources/db/migration/V6_4__migrate_entity_dynamic_mapping_relations_to_array.sql:13

  • The migration converts the old map format to objects with an expression field (string), but the application now persists/deserializes relations as RelationMapping records with an expressions field (list). This mismatch will leave expressions null after migration and can break mapping validation/runtime.
    src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/mapper/entity_dynamic_mapping/EntityDynamicMappingDryRunDtoInMapper.java:21
  • This Spring component instantiates its own ObjectMapper, bypassing the application-configured Jackson ObjectMapper (modules, naming strategies, etc.) and defeating constructor injection despite @requiredargsconstructor. This can cause inconsistent serialization of the dry-run payload compared to the rest of the API.
@Component
@RequiredArgsConstructor
public class EntityDynamicMappingDryRunDtoInMapper {

  private final ObjectMapper objectMapper = new ObjectMapper();

Comment on lines +174 to +181
/// Returns node text value and fails when node is null or missing.
private String requireStringValue(JsonNode node, String fieldName) {
if (node == null || node.isNull() || node.isMissingNode()) {
throw new EntityDynamicMappingConfigurationException(
"Expression for '" + fieldName + "' returned null");
}
return node.asText();
}
Signed-off-by: foukou19 <ferial.oukoukas@decathlon.com>
Copilot AI review requested due to automatic review settings July 24, 2026 10:46
@foukou19
foukou19 force-pushed the feat/idp-core-entity-dynamic-mapping-dry-run branch from 3c808f8 to f741d07 Compare July 24, 2026 10:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 48 out of 51 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (5)

src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/mapper/entity_dynamic_mapping/EntityDynamicMappingDryRunDtoInMapper.java:20

  • This mapper always creates its own ObjectMapper, which ignores the application’s configured Jackson settings/modules and prevents Spring from injecting the shared mapper (despite @RequiredArgsConstructor). This can lead to inconsistent serialization (dates, naming, modules) between the API layer and dry-run payload normalization.
  private final ObjectMapper objectMapper = new ObjectMapper();

src/main/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/JsltConfiguration.java:18

  • Registering a bare new ObjectMapper() as a Spring bean overrides Spring Boot’s auto-configured ObjectMapper (and any custom Jackson modules/settings). That can unintentionally change JSON (de)serialization across the whole application.
  @Bean
  public ObjectMapper objectMapper() {
    return new ObjectMapper();
  }

src/main/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/JsltMappingEngineAdapter.java:179

  • requireStringValue returns node.asText() for any non-null node. For non-scalar results (objects/arrays) Jackson returns an empty string, which can silently produce blank identifiers/names instead of failing fast. This should reject non-scalar and blank results for required fields like entity identifier/name.
    src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/mapper/common/EntityDynamicMappingJsonbHelper.java:61
  • toRelationList deserializes directly into RelationMapping, which only supports an expressions field. However, the Javadoc here indicates a legacy/singular expression field, and the accompanying test claims legacy support. As-is, legacy rows/doc examples using expression would fail to deserialize.
    src/main/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/JsltExpressionEvaluator.java:5
  • java.util.stream.Stream is imported but never used, which may fail strict style/lint checks.

Comment on lines +40 to +42
if (node == null || node.isNull()) {
return List.of();
}
Copilot AI review requested due to automatic review settings July 24, 2026 14:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 49 out of 52 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (4)

src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/mapper/common/EntityDynamicMappingJsonbHelper.java:63

  • toRelationList currently relies on Jackson binding to RelationMapping, which expects an expressions array. However this file’s Javadoc (and the corresponding unit test name) refer to a legacy expression field. If any persisted JSON uses { "expression": "..." }, deserialization will fail or produce invalid RelationMappings. Consider supporting both keys (expressions and legacy expression) during read, and align the documented expected format with the actual schema/migration (expressions).
    src/test/java/com/decathlon/idp_core/infrastructure/adapters/persistence/mapper/common/EntityDynamicMappingJsonbHelperTest.java:23
  • This test claims to cover legacy V6.4 expression field deserialization, but the JSON uses the current expressions array. If legacy compatibility is intended, the fixture should use expression so the test actually exercises the fallback behavior.
    src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/mapper/entity_dynamic_mapping/EntityDynamicMappingDryRunDtoInMapper.java:20
  • EntityDynamicMappingDryRunDtoInMapper creates its own ObjectMapper instance. This can diverge from the application’s configured Jackson modules/features (and makes @RequiredArgsConstructor misleading). Prefer constructor-injecting the Spring-managed ObjectMapper to keep serialization consistent across the API.
@Component
@RequiredArgsConstructor
public class EntityDynamicMappingDryRunDtoInMapper {

  private final ObjectMapper objectMapper = new ObjectMapper();

src/main/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/JsltConfiguration.java:18

  • Defining a new ObjectMapper bean via return new ObjectMapper() can override Spring Boot’s auto-configured mapper and drop important customizations/modules (Java time, Kotlin, naming, etc.). Prefer building the mapper via Spring’s Jackson2ObjectMapperBuilder (or remove this bean entirely and inject the default mapper) to preserve the application-wide Jackson configuration.
  @Bean
  public ObjectMapper objectMapper() {
    return new ObjectMapper();
  }

Comment on lines +56 to +64
} catch (EntityDynamicMappingJsltErrorException
| EntityDynamicMappingConfigurationException e) {
throw e;
} catch (ExpressionEvaluationFailedException e) {
throw new EntityDynamicMappingJsltErrorException(e.getMessage());
} catch (Exception e) {
return List.of(DryRunEntityResult.failure(templateIdentifier, ErrorType.JSLT_ERROR,
"Unexpected transformation error: " + e.getMessage()));
}
@foukou19
foukou19 force-pushed the feat/idp-core-entity-dynamic-mapping-dry-run branch from 004bda7 to b3c6756 Compare July 24, 2026 15:29
Copilot AI review requested due to automatic review settings July 24, 2026 15:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 49 out of 52 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (4)

src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/mapper/common/EntityDynamicMappingJsonbHelper.java:21

  • The relation JSON format in this helper’s JavaDoc uses a singular expression field, but the persisted format (migration + RelationMapping record) uses expressions (array). Keeping the doc wrong will mislead future migrations/debugging and makes it look like legacy support exists when it doesn’t.
    src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/mapper/entity_dynamic_mapping/EntityDynamicMappingDryRunDtoInMapper.java:21
  • This mapper creates its own ObjectMapper instance, which bypasses the application’s Jackson configuration (modules, naming strategy, etc.) and violates the project’s constructor-injection pattern. It also makes @RequiredArgsConstructor misleading since there are no injected deps.
@Component
@RequiredArgsConstructor
public class EntityDynamicMappingDryRunDtoInMapper {

  private final ObjectMapper objectMapper = new ObjectMapper();

src/main/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/JsltConfiguration.java:18

  • JsltConfiguration declares a new global ObjectMapper bean. In Spring Boot, that will replace the auto-configured (customized) mapper and can break JSON handling elsewhere (missing modules, custom settings). If the goal is only to share a mapper, prefer injecting the existing Boot-provided ObjectMapper and remove this bean definition.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.fasterxml.jackson.databind.ObjectMapper;

/// Spring configuration for JSLT mapping adapter infrastructure.
/// Provides shared JSON serialization for payload parsing and expression evaluation.
@Configuration
public class JsltConfiguration {

  /// Provides a shared ObjectMapper bean for mapping adapters.
  /// Bean scope is singleton and safe for concurrent reuse.
  @Bean
  public ObjectMapper objectMapper() {
    return new ObjectMapper();
  }

src/test/java/com/decathlon/idp_core/infrastructure/adapters/persistence/mapper/common/EntityDynamicMappingJsonbHelperTest.java:27

  • This test claims to cover legacy single-field expression compatibility, but the JSON sample still uses the current expressions array. As written, it won’t detect regressions (or absence) of legacy support.

Comment on lines +62 to +73
@Named("jsonStringToRelationList")
public List<RelationMapping> toRelationList(String json) {
if (json == null || json.trim().isEmpty()) {
return List.of();
}
try {
return OBJECT_MAPPER.readValue(json, new TypeReference<List<RelationMapping>>() {
});
} catch (JsonProcessingException e) {
throw new IllegalArgumentException("Invalid JSON relation list configuration", e);
}
}
Comment on lines +23 to +26
-- Normalize NULL relations to empty array (defensive guard for any unexpected NULLs)
UPDATE entity_dynamic_mapping
SET relations = '[]'::jsonb
WHERE relations IS NULL;
Signed-off-by: foukou19 <ferial.oukoukas@decathlon.com>
Copilot AI review requested due to automatic review settings July 27, 2026 09:36
@foukou19
foukou19 force-pushed the feat/idp-core-entity-dynamic-mapping-dry-run branch from b3c6756 to e766205 Compare July 27, 2026 09:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 51 out of 54 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

src/main/resources/db/migration/V6_4__migrate_entity_dynamic_mapping_relations_to_array.sql:26

  • The migration only normalizes SQL NULL ("relations IS NULL"), but Postgres JSONB can also contain a JSON null literal (relations = 'null'::jsonb). Those rows will not be converted to an empty array and will remain inconsistent with the new array contract.
    src/main/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/JsltConfiguration.java:18
  • Defining an ObjectMapper bean here will replace Spring Boot’s auto-configured ObjectMapper for the entire application (Boot backs off when an ObjectMapper bean exists). That can inadvertently drop important Jackson modules/configuration used by the REST API (e.g., Java Time handling, naming strategies, security-related settings). The mapping adapter can just inject the existing application-wide ObjectMapper.
  @Bean
  public ObjectMapper objectMapper() {
    return new ObjectMapper();
  }

src/main/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/JsltExpressionEvaluator.java:6

  • java.util.stream.Stream is imported but not used. If the build runs with unused-import checks (Spotless/Checkstyle), this will fail CI.

Signed-off-by: foukou19 <ferial.oukoukas@decathlon.com>
Copilot AI review requested due to automatic review settings July 27, 2026 09:52

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 52 out of 55 changed files in this pull request and generated 4 comments.

Comments suppressed due to low confidence (5)

src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/mapper/entity_dynamic_mapping/EntityDynamicMappingDryRunDtoInMapper.java:20

  • This Spring @Component creates its own ObjectMapper instance, which bypasses the application’s Jackson configuration (modules, naming strategies, etc.) and makes testing harder (final field). Prefer constructor injection of the Spring-managed ObjectMapper bean.
  private final ObjectMapper objectMapper = new ObjectMapper();

src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/mapper/common/EntityDynamicMappingJsonbHelper.java:22

  • The class-level documentation describes relations JSON using a singular 'expression' field, but the actual persisted format and domain model use an 'expressions' array (see RelationMapping.expressions and migration V6_4). This mismatch can mislead future maintenance and debugging.
    src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/mapper/common/EntityDynamicMappingJsonbHelper.java:60
  • The method documentation for relation JSONB deserialization still references the old singular 'expression' field, but the expected format is now 'expressions' (array). Keeping this accurate is important because this helper is the canonical reference for the persistence JSON contract.
    src/test/java/com/decathlon/idp_core/infrastructure/adapters/persistence/mapper/common/EntityDynamicMappingJsonbHelperTest.java:20
  • This test’s display name says it validates legacy singular 'expression' field support, but the JSON fixture uses the current 'expressions' array field. As written, it doesn’t cover any legacy compatibility branch and is redundant with the next test.
    src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/mapper/common/EntityDynamicMappingJsonbHelper.java:79
  • The relation JSONB serialization JavaDoc still documents an output with a singular 'expression' field, but persistence now writes RelationMapping (name + expressions list) and the migration/comment describe an 'expressions' array. The doc should reflect the actual persisted JSON shape.

Comment on lines +34 to +37
@SuppressWarnings("unused")
@AssertTrue(message = PAYLOAD_DRY_RUN_MANDATORY)
public boolean isPayloadNotBlankWhenString() {
return !(payload instanceof String payloadString) || !payloadString.isBlank();

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already fixed

Comment on lines +122 to +126
@ApiResponse(responseCode = BAD_REQUEST_CODE, description = RESPONSE_ENTITY_DYNAMIC_MAPPING_DATA, content = {
@Content(schema = @Schema(implementation = ApiExceptionHandler.ErrorResponse.class))})
@ApiResponse(responseCode = NOT_FOUND_CODE, description = RESPONSE_ENTITY_DYNAMIC_MAPPING_NOT_FOUND_IDENTIFIER, content = {
@Content(schema = @Schema(implementation = ApiExceptionHandler.ErrorResponse.class))})
@PostMapping("/dry-run")

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already fixed
422 OK
404 = "Entity template not found"

Comment on lines +602 to +606
"400":
description: Invalid entity dynamic mapping data provided
content:
"*/*":
schema:

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already fixed
422 OK
404 = "Entity template not found"

Comment on lines +1510 to +1514
payload:
description: Sample JSON payload to test against the webhook mapping configuration
payload_not_blank_when_string:
type: boolean
required:
@foukou19 foukou19 changed the title feat(api): complete entity dynamic mapping dry-run workflow feat(api)!: complete entity dynamic mapping dry-run workflow Jul 27, 2026
Copilot AI review requested due to automatic review settings July 27, 2026 12:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 52 out of 55 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (7)

src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/dto/in/EntityDynamicMappingDryRunDtoIn.java:37

  • @AssertTrue method is being surfaced as a model property in the generated OpenAPI (payload_not_blank_when_string shows up in swagger.yaml). This leaks an internal validation guard into the public contract and can confuse clients.
  @SuppressWarnings("unused")
  @AssertTrue(message = PAYLOAD_DRY_RUN_MANDATORY)
  public boolean isPayloadNotBlankWhenString() {
    return !(payload instanceof String payloadString) || !payloadString.isBlank();

src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/mapper/entity_dynamic_mapping/EntityDynamicMappingDryRunDtoInMapper.java:22

  • EntityDynamicMappingDryRunDtoInMapper instantiates its own ObjectMapper (new ObjectMapper()), which bypasses the application-wide Jackson configuration/modules and also defeats constructor injection (Lombok won’t include initialized finals). This can lead to inconsistent serialization between dry-run and the rest of the API.
@Component
@RequiredArgsConstructor
public class EntityDynamicMappingDryRunDtoInMapper {

  private final ObjectMapper objectMapper = new ObjectMapper();

  public String toRawPayload(Object payload) {

src/main/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/JsltConfiguration.java:18

  • Defining a custom ObjectMapper bean via new ObjectMapper() will override Spring Boot’s auto-configured mapper (modules, naming strategies, date/time handling, etc.). Prefer building from the Boot Jackson2ObjectMapperBuilder so the mapper used by the JSLT adapter stays consistent with the rest of the application.
  /// Provides a shared ObjectMapper bean for mapping adapters.
  /// Bean scope is singleton and safe for concurrent reuse.
  @Bean
  public ObjectMapper objectMapper() {
    return new ObjectMapper();
  }

src/main/java/com/decathlon/idp_core/domain/service/entity_dynamic_mapping/EntityDynamicMappingDryRunService.java:64

  • ExpressionEvaluationFailedException is being wrapped into EntityDynamicMappingJsltErrorException, which prevents the dedicated @ExceptionHandler(ExpressionEvaluationFailedException) from ever running for the dry-run endpoint and drops the structured context (expression, reason) that the handler logs. Let it propagate so the API returns a consistent 422 with the correct handler/logging.
    try {
      return mapAndValidateEntity(mapping, rawPayload, templateIdentifier);
    } catch (EntityDynamicMappingJsltErrorException
        | EntityDynamicMappingConfigurationException e) {
      throw e;
    } catch (ExpressionEvaluationFailedException e) {
      throw new EntityDynamicMappingJsltErrorException(e.getMessage());
    } catch (Exception e) {
      return List.of(DryRunEntityResult.failure(templateIdentifier, ErrorType.JSLT_ERROR,
          "Unexpected transformation error: " + e.getMessage()));
    }

src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/mapper/common/EntityDynamicMappingJsonbHelper.java:21

  • The class-level documentation says relations are stored with an expression field, but the actual persisted format is expressions (array) (see RelationMapping#expressions and the Flyway V6_4 migration). Keeping this doc accurate is important for future maintenance/debugging of JSONB contents.
    src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/mapper/common/EntityDynamicMappingJsonbHelper.java:60
  • The relation JSON format examples still reference expression (singular), but the code serializes/deserializes RelationMapping which uses expressions (list). These examples should match the real JSONB payload to avoid misleading future migrations/debugging.
    src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/mapper/common/EntityDynamicMappingJsonbHelper.java:78
  • The output JSON format example says expression (singular), but RelationMapping is serialized with the expressions array field. Align the doc with the actual JSON produced by ObjectMapper.writeValueAsString(relations).

Copilot AI review requested due to automatic review settings July 27, 2026 13:41
@foukou19
foukou19 force-pushed the feat/idp-core-entity-dynamic-mapping-dry-run branch from 1570b41 to 8f55645 Compare July 27, 2026 13:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 52 out of 55 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

src/main/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/JsltMappingEngineAdapter.java:181

  • requireStringValue only checks for null/missing nodes, but allows blank values (e.g., when the expression evaluates to an object, asText() can become empty). This can produce entities with empty identifier/name and bypass dry-run validation since validateForDryRun doesn’t check Entity’s @NotBlank constraints. Treat blank results as a configuration error.
    src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/mapper/entity_dynamic_mapping/EntityDynamicMappingDryRunDtoInMapper.java:24
  • EntityDynamicMappingDryRunDtoInMapper always constructs its own ObjectMapper, ignoring the application’s configured Jackson ObjectMapper (modules, naming, etc.) and forcing tests to use reflection to replace a final field. Prefer constructor injection of the Spring-managed ObjectMapper.
@RequiredArgsConstructor
public class EntityDynamicMappingDryRunDtoInMapper {

  private final ObjectMapper objectMapper = new ObjectMapper();

  public String toRawPayload(Object payload) {
    if (payload instanceof String payloadString) {
      return payloadString;
    }

src/main/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/JsltConfiguration.java:18

  • JsltConfiguration defines a brand new ObjectMapper bean (new ObjectMapper()), which will override Spring Boot’s auto-configured mapper and may drop globally registered modules (e.g., JavaTimeModule) used by the rest of the API. The mapping adapters should instead reuse the existing Boot-managed ObjectMapper.
/// Spring configuration for JSLT mapping adapter infrastructure.
/// Provides shared JSON serialization for payload parsing and expression evaluation.
@Configuration
public class JsltConfiguration {

  /// Provides a shared ObjectMapper bean for mapping adapters.
  /// Bean scope is singleton and safe for concurrent reuse.
  @Bean
  public ObjectMapper objectMapper() {
    return new ObjectMapper();
  }

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 52 out of 55 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (7)

src/main/java/com/decathlon/idp_core/infrastructure/adapters/entity_mapping/jslt/JsltConfiguration.java:18

  • Defining a custom @Bean ObjectMapper here will replace Spring Boot’s auto-configured ObjectMapper (modules, naming, serialization settings), which can cause broad JSON (de)serialization regressions across the API. Prefer relying on the Boot-provided ObjectMapper via constructor injection (or, if you need isolation, inject it and use objectMapper.copy() locally) and remove this configuration class.
  /// Provides a shared ObjectMapper bean for mapping adapters.
  /// Bean scope is singleton and safe for concurrent reuse.
  @Bean
  public ObjectMapper objectMapper() {
    return new ObjectMapper();
  }

src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/mapper/entity_dynamic_mapping/EntityDynamicMappingDryRunDtoInMapper.java:20

  • EntityDynamicMappingDryRunDtoInMapper instantiates its own ObjectMapper and the field initializer prevents Spring from injecting the shared mapper. This also makes the unit tests rely on reflection to swap a final field. Prefer constructor injection of ObjectMapper (Spring Boot already provides one).
@RequiredArgsConstructor
public class EntityDynamicMappingDryRunDtoInMapper {

  private final ObjectMapper objectMapper = new ObjectMapper();

src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/dto/in/EntityDynamicMappingDryRunDtoIn.java:36

  • The @AssertTrue method introduces a synthetic payload_not_blank_when_string field in the generated OpenAPI schema (and the committed swagger.yaml). This is misleading for clients because it looks like a required request property. Consider moving this to a class-level custom constraint, or at least hide the method from OpenAPI (@Schema(hidden = true)) and Jackson (@JsonIgnore), then regenerate/update docs/src/static/swagger.yaml.
  /// Keeps syntactic validation equivalent to previous String-based contract.
  ///
  /// Null is handled by `@NotNull`; this guard prevents blank String payloads.
  @SuppressWarnings("unused")
  @AssertTrue(message = PAYLOAD_DRY_RUN_MANDATORY)
  public boolean isPayloadNotBlankWhenString() {
    return !(payload instanceof String payloadString) || !payloadString.isBlank();
  }

src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/mapper/common/EntityDynamicMappingJsonbHelper.java:22

  • The Javadoc examples for relations still use a singular expression field, but the new persisted shape is expressions: [ ... ] (see migration V6_4__... and RelationMapping.expressions). This makes the helper documentation misleading.
    src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/mapper/common/EntityDynamicMappingJsonbHelper.java:60
  • The documented expected relations JSON format uses expression, but RelationMapping actually expects expressions (list). Update this comment to match the persisted schema.
    src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/mapper/common/EntityDynamicMappingJsonbHelper.java:77
  • The documented output relations JSON format uses expression, but serialization produces expressions (list) via RelationMapping. Update the comment so it matches the actual JSONB written to Postgres.
    src/test/java/com/decathlon/idp_core/infrastructure/adapters/persistence/mapper/common/EntityDynamicMappingJsonbHelperTest.java:28
  • This test’s display name claims it verifies legacy expression field support, but the JSON uses expressions and therefore duplicates the next test. Either rename the test to match what it actually asserts, or add a real legacy fixture and implement compatibility handling.

@DisplayName("EntityDynamicMappingDryRunDtoInMapper Unit Tests")
class EntityDynamicMappingDryRunDtoInMapperTest {

private final EntityDynamicMappingDryRunDtoInMapper mapper = new EntityDynamicMappingDryRunDtoInMapper();

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already fixed

@foukou19
foukou19 marked this pull request as ready for review July 27, 2026 14:17
@foukou19
foukou19 force-pushed the feat/idp-core-entity-dynamic-mapping-dry-run branch from 8f55645 to 46e3e4a Compare July 27, 2026 14:20
Signed-off-by: foukou19 <ferial.oukoukas@decathlon.com>
@foukou19
foukou19 force-pushed the feat/idp-core-entity-dynamic-mapping-dry-run branch from 46e3e4a to 7eea5b7 Compare July 27, 2026 14:40
foukou19 added 2 commits July 28, 2026 18:32
…orkflow

Signed-off-by: foukou19 <ferial.oukoukas@decathlon.com>
…workflow

Signed-off-by: foukou19 <ferial.oukoukas@decathlon.com>
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
79.6% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants