Skip to content

feat(core): audit implementation#69

Open
RVANDO12 wants to merge 11 commits into
mainfrom
feat/audit/envers
Open

feat(core): audit implementation#69
RVANDO12 wants to merge 11 commits into
mainfrom
feat/audit/envers

Conversation

@RVANDO12

@RVANDO12 RVANDO12 commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

PR Description

📝 Summary of Changes

This Pull Request introduces comprehensive database version control and auditing mechanisms across core entity tables using Hibernate Envers and Spring Data Envers.

image

Key Architectures & Feature Additions:

  1. Automated Audit Table Interception: Added hibernate-envers to capture and persist historical snapshots into matching database target tables (*_aud) on all core entity transactions.
  2. Spring Data Abstraction Layer: Integrated spring-data-envers and updated repositories (JpaEntityRepository, etc.) to extend RevisionRepository. This unlocks access to the full timeline history natively without relying on complex handwritten native JOIN operations.
  3. Advanced Transaction Metadata Tracking: Implemented an EntityTrackingRevisionListener coupled with @ElementCollection mapping to dynamically log the precise list of elements modified inside a single transaction unit.
  4. Resilient Security Context Audit Parsing: * Configured authentication tracking to extract identity mappings (sub or id) across JWT, OAuth2, and OpenID scopes.
    • Hardened Security Boundaries: Added protective filtering for anonymous users (AnonymousAuthenticationToken) and missing context environments to avoid NullPointerExceptions (NPEs) when interacting with unauthenticated callers, background jobs, or malicious scanner traffic.
  5. Schema Control Rigor: Established standard migration frameworks using Flyway to manually align shadow audit layout definitions, mapping boolean metadata tracking tags (*_MOD), and deploying optimal query indexes to support scale performance.

Review

The reviewer must double-check these points :

  • Schema Migration scripts verified manually on startup.
  • Dynamic auditing intercepts mapping data context synchronously.
  • Security identity parsing successfully outputs user string context labels without generating NPE anomalies.
  • The reviewer has tested the feature
  • The reviewer has reviewed the implementation of the feature
  • The documentation has been updated
  • The feature implementation respects the Technical Doc / ADR previously produced
  • The Pull Request title has a ! after the type/scope to identify the breaking
    change in the release note and ensure we will release a major version.

How to test

🧪 Local Testing & Verification Report

The feature set has been thoroughly validated against local environments using target endpoint APIs. The results below verify successful timeline serialization, event capture types, and active identity mapping logging.

1. Create Operation (Revision 1)

Action: Submitting a POST request to register a brand new entity (web-api-audit).

curl -X 'POST' \
  'http://localhost:8084/api/v1/entities/web-service' \
  -H 'accept: */*' \
  -H 'Content-Type: application/json' \
  -d '{
  "identifier": "web-api-audit",
  "name": "web-api-audit",
  "properties": {
    "port": "8080",
    "applicationName": "audit",
    "baseUrl": "http://www.audit.fr",
    "environment": "PROD",
    "ownerEmail": "audit@lazar.com",
    "programmingLanguage": "JAVA",
    "protocol": "HTTP",
    "teamName": "lazar", 
    "version": "1.1.1"
  },
  "relations": []
}'

Audit Trail Output (GET /api/v1/audit/entities/web-service/web-api-audit):

[
  {
    "modified_by": "local-developer",
    "revision_date": "2026-06-22T06:09:35.637Z",
    "revision_number": 4,
    "revision_type": "CREATED",
    "snapshot": {
      "id": "a0f8f1ce-b131-4a59-8d89-406232ca2135",
      "identifier": "web-api-audit",
      "name": "web-api-audit",
      "properties": [
        {
          "id": "d01a3ddf-fdae-48d0-9027-09cdda8f121c",
          "name": "applicationName",
          "value": "audit"
        },
        {
          "id": "977a9290-fd8a-47f8-8bef-5506483f9107",
          "name": "port",
          "value": "8080"
        },
        {
          "id": "652d106f-a15c-493e-bd11-3ef23d0e29c1",
          "name": "environment",
          "value": "PROD"
        },
        {
          "id": "4e79545c-1b2d-41d3-a52c-c0e9f597a86a",
          "name": "ownerEmail",
          "value": "audit@lazar.com"
        },
        {
          "id": "9716175f-e6c7-4f96-8ceb-48740aaf498d",
          "name": "programmingLanguage",
          "value": "JAVA"
        },
        {
          "id": "fc6b7538-3a47-4d4f-b4cd-98c4e5069fe3",
          "name": "baseUrl",
          "value": "http://www.audit.fr"
        },
        {
          "id": "a69e2f85-1ebe-4c8a-a371-f3d9639be050",
          "name": "teamName",
          "value": "lazar"
        },
        {
          "id": "13b7f63d-4108-4570-9387-9d08ece20cd7",
          "name": "version",
          "value": "1.1.1"
        },
        {
          "id": "9344c5bc-d94c-4f25-adea-bf6b906bd46e",
          "name": "protocol",
          "value": "HTTP"
        }
      ],
      "relations": [],
      "template_identifier": "web-service"
    }
  }
]

Verification Status: ✅ Passthrough Successful. revision_number: 1 created with revision_type: "CREATED". Context operator identity local-developer extracted properly.

  1. Update Operation (Revision 2)
    Action: Submitting a PUT request modifying structural parameter fields (e.g. updating baseUrl and port).
curl -X 'PUT' \
  'http://localhost:8084/api/v1/entities/web-service/web-api-audit' \
  -H 'accept: */*' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "web-api-audit",
  "properties": {
    "port": "8084",
    "applicationName": "audit",
    "baseUrl": "http://www.audit.com",
    "environment": "PROD",
    "ownerEmail": "audit@lazar.com",
    "programmingLanguage": "JAVA",
    "protocol": "HTTP",
    "teamName": "lazar", 
    "version": "1.1.1"
  },
  "relations": []
}'

Audit Trail Output:

[
  {
    "modified_by": "local-developer",
    "revision_date": "2026-06-22T06:17:50.502Z",
    "revision_number": 5,
    "revision_type": "UPDATED",
    "snapshot": {
      "id": "a0f8f1ce-b131-4a59-8d89-406232ca2135",
      "identifier": "web-api-audit",
      "name": "web-api-audit",
      "properties": [
        {
          "id": "0c4b4099-1fdd-4779-8508-34696bcda5e5",
          "name": "environment",
          "value": "PROD"
        },
        {
          "id": "a458eb16-4cb6-493c-aae0-01605abce081",
          "name": "version",
          "value": "1.1.1"
        },
        {
          "id": "dd6990a3-9dcf-4582-86ae-e76681405023",
          "name": "protocol",
          "value": "HTTP"
        },
        {
          "id": "e6f3d681-26d1-4118-a3b8-082f8b476fb6",
          "name": "programmingLanguage",
          "value": "JAVA"
        },
        {
          "id": "702f6e49-8d40-4a45-890b-84ad5055a490",
          "name": "applicationName",
          "value": "audit"
        },
        {
          "id": "17d86f4b-eca6-4c68-80cc-aa0b05b69ff4",
          "name": "port",
          "value": "8084"
        },
        {
          "id": "dccab136-9068-4b3b-ae56-9482f9860eee",
          "name": "teamName",
          "value": "lazar"
        },
        {
          "id": "175e6033-ea91-4ecc-a700-d84cc7b585b9",
          "name": "baseUrl",
          "value": "http://www.audit.com"
        },
        {
          "id": "44d6de3f-7e49-42f2-ae2a-66059549fc64",
          "name": "ownerEmail",
          "value": "audit@lazar.com"
        }
      ],
      "relations": [],
      "template_identifier": "web-service"
    }
  },
  {
    "modified_by": "local-developer",
    "revision_date": "2026-06-22T06:09:35.637Z",
    "revision_number": 4,
    "revision_type": "CREATED",
    "snapshot": {
      "id": "a0f8f1ce-b131-4a59-8d89-406232ca2135",
      "identifier": "web-api-audit",
      "name": "web-api-audit",
      "properties": [
        {
          "id": "d01a3ddf-fdae-48d0-9027-09cdda8f121c",
          "name": "applicationName",
          "value": "audit"
        },
        {
          "id": "977a9290-fd8a-47f8-8bef-5506483f9107",
          "name": "port",
          "value": "8080"
        },
        {
          "id": "652d106f-a15c-493e-bd11-3ef23d0e29c1",
          "name": "environment",
          "value": "PROD"
        },
        {
          "id": "4e79545c-1b2d-41d3-a52c-c0e9f597a86a",
          "name": "ownerEmail",
          "value": "audit@lazar.com"
        },
        {
          "id": "9716175f-e6c7-4f96-8ceb-48740aaf498d",
          "name": "programmingLanguage",
          "value": "JAVA"
        },
        {
          "id": "fc6b7538-3a47-4d4f-b4cd-98c4e5069fe3",
          "name": "baseUrl",
          "value": "http://www.audit.fr"
        },
        {
          "id": "a69e2f85-1ebe-4c8a-a371-f3d9639be050",
          "name": "teamName",
          "value": "lazar"
        },
        {
          "id": "13b7f63d-4108-4570-9387-9d08ece20cd7",
          "name": "version",
          "value": "1.1.1"
        },
        {
          "id": "9344c5bc-d94c-4f25-adea-bf6b906bd46e",
          "name": "protocol",
          "value": "HTTP"
        }
      ],
      "relations": [],
      "template_identifier": "web-service"
    }
  }
]

Verification Status: ✅ Passthrough Successful. System append logs a separate record with revision_number: 2 tagged as UPDATED.

  1. Delete Operation (Revision 3)
    Action: Issuing a DELETE command targeting the runtime asset item tracker.
curl -X 'DELETE' \
  'http://localhost:8084/api/v1/entities/web-service/web-api-audit' \
  -H 'accept: */*'
  

Audit Trail Output:

[
  {
    "modified_by": "local-developer",
    "revision_date": "2026-06-22T06:41:49.346Z",
    "revision_number": 9,
    "revision_type": "DELETED",
    "snapshot": {
      "id": "8d2c9812-b272-445d-9a67-11ee55ef0220",
      "identifier": "web-api-audit",
      "name": "web-api-audit",
      "properties": [
        {
          "id": "9fa8cc88-fee7-4a3e-ac50-fec7060ad1ce",
          "name": "ownerEmail",
          "value": "audit@lazar.com"
        },
        {
          "id": "5d916cbb-1d6e-4973-9c13-8fb62858c109",
          "name": "port",
          "value": "8084"
        },
        {
          "id": "33101c6f-7447-4044-998f-4c38e275be0b",
          "name": "applicationName",
          "value": "audit"
        },
        {
          "id": "045509c2-1350-4ab7-87ec-76e6b74b1749",
          "name": "baseUrl",
          "value": "http://www.audit.com"
        },
        {
          "id": "bafbb337-6dec-4a65-b831-1bd5c1902c8f",
          "name": "environment",
          "value": "PROD"
        },
        {
          "id": "30d37907-0129-46c5-a219-421fddd700d4",
          "name": "protocol",
          "value": "HTTP"
        },
        {
          "id": "596fbac8-ec4a-48ec-8458-8c29b8dfdf4d",
          "name": "version",
          "value": "1.1.1"
        },
        {
          "id": "69ea298e-7d5c-4b9c-8386-c6c2a081aff5",
          "name": "programmingLanguage",
          "value": "JAVA"
        },
        {
          "id": "66a6e3bf-0521-44a7-b3f4-6a43bbcaf347",
          "name": "teamName",
          "value": "lazar"
        }
      ],
      "relations": [],
      "template_identifier": "web-service"
    }
  },
  {
    "modified_by": "local-developer",
    "revision_date": "2026-06-22T06:40:58.279Z",
    "revision_number": 8,
    "revision_type": "UPDATED",
    "snapshot": {
      "id": "8d2c9812-b272-445d-9a67-11ee55ef0220",
      "identifier": "web-api-audit",
      "name": "web-api-audit",
      "properties": [
      ...
]

Verification Status: ✅ Passthrough Successful. Final chronological list accurately outputs DELETED state logic (revision_number: 3) with structural string identifiers reset gracefully to null, while maintaining the immutable historical data snapshots from earlier transactions.

Breaking changes (if any)

N/A

@RVANDO12 RVANDO12 force-pushed the feat/audit/envers branch 2 times, most recently from db2e766 to acac340 Compare June 11, 2026 10:48
@github-code-quality

github-code-quality Bot commented Jun 11, 2026

Copy link
Copy Markdown

Code Coverage Overview

Languages: Java

Java / code-coverage/jacoco

The overall coverage in the branch is 90%. Coverage data for the branch is not yet available.

Show a code coverage summary of the most covered files.
File 0f0c069 +/-
com/decathlon/i...rDslParser.java 99%
com/decathlon/i...ionService.java 99%
com/decathlon/i...ityService.java 96%
com/decathlon/i...MapperImpl.java 90%
com/decathlon/i...MapperImpl.java 88%
com/decathlon/i...ionHandler.java 87%
com/decathlon/i...ionService.java 87%
com/decathlon/i...oOutMapper.java 86%
com/decathlon/i...cification.java 81%
com/decathlon/i...ionService.java 77%

Updated June 22, 2026 11:22 UTC
Code Coverage is in Public Preview. Learn more and provide us with your feedback.

@RVANDO12 RVANDO12 force-pushed the feat/audit/envers branch from b7be593 to 3a4e46a Compare June 11, 2026 13:01
Comment thread docs/src/static/swagger.yaml
Comment thread src/main/resources/db/migration/V4_1__create_envers_audit_schema.sql Outdated
Comment thread docs/src/concepts/audit.md

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

This PR introduces entity audit/history capabilities to IDP-Core using Hibernate Envers, exposing a new REST endpoint to retrieve revision history, and adding supporting schema, security identity extraction, tests, and documentation.

Changes:

  • Add Envers audit schema via Flyway and enable Envers delete snapshot storage.
  • Add audit retrieval flow (domain port/service + persistence adapter + REST controller + DTOs/mapper).
  • Add identity extraction abstraction (UserIdentityProvider) plus local mock security support, and update tests/docs accordingly.

Reviewed changes

Copilot reviewed 43 out of 45 changed files in this pull request and generated 14 comments.

Show a summary per file
File Description
src/test/resources/integration_test/json/audit/v1/getAudit_200_history_update.json Test JSON payload for audit update scenario
src/test/resources/integration_test/json/audit/v1/getAudit_200_history_create.json Test JSON payload for audit create scenario
src/test/resources/db/test/R__2_Insert_entities_test_data.sql Adjust test entity seed data ordering/content
src/test/resources/db/test/R__1_Insert_test_data.sql Add audited template seed data for tests
src/test/java/com/decathlon/idp_core/infrastructure/adapters/persistence/model/audit/CustomRevisionListenerTest.java Unit tests for Envers revision listener behavior
src/test/java/com/decathlon/idp_core/infrastructure/adapters/api/controller/EntityTemplateControllerTest.java Update expected template counts due to new seed template
src/test/java/com/decathlon/idp_core/infrastructure/adapters/api/controller/AuditControllerTest.java New integration tests for audit endpoint
src/test/java/com/decathlon/idp_core/infrastructure/adapters/api/auth/UnifiedUserProviderTest.java Unit tests for unified identity extraction
src/test/java/com/decathlon/idp_core/infrastructure/adapters/api/auth/mock/MockSecurityConfigurationTest.java Tests for mock security configuration/filter
src/test/java/com/decathlon/idp_core/AbstractIntegrationTest.java Test configuration tweaks for integration tests
src/main/resources/db/migration/V4_1__create_envers_audit_schema.sql New Flyway migration creating Envers audit tables
src/main/resources/application.yml Enable Envers delete snapshot storage
src/main/resources/application-local.yml Local security/mock-security configuration updates
src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/repository/JpaRelationRepository.java Add revision repository support
src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/repository/JpaEntityTemplateRepository.java Add revision repository support
src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/repository/JpaEntityRepository.java Add revision repository support
src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/PostgresEntityAuditAdapter.java New persistence adapter to query audit history
src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/model/entity/RelationJpaEntity.java Enable auditing on relation entity
src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/model/entity/PropertyRulesJpaEntity.java Enable auditing on property rules entity
src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/model/entity/PropertyJpaEntity.java Enable auditing on property entity
src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/model/entity/EntityJpaEntity.java Enable auditing on entity entity
src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/model/entity_template/RelationDefinitionJpaEntity.java Enable auditing on relation definition entity
src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/model/entity_template/PropertyDefinitionJpaEntity.java Enable auditing on property definition entity
src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/model/entity_template/EntityTemplateJpaEntity.java Enable auditing on entity template entity
src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/model/audit/UserIdentityProviderHolder.java Bridge Envers listener to Spring identity provider
src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/model/audit/CustomRevisionListener.java Custom Envers revision listener implementation
src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/model/audit/CustomRevisionEntity.java Custom Envers revision entity mapping
src/main/java/com/decathlon/idp_core/infrastructure/adapters/persistence/model/audit/CustomRevinfoRecord.java Embeddable record for per-transaction changed-entity metadata
src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/mapper/entity/EntityAuditDtoOutMapper.java Map domain audit model to API DTO
src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/dto/out/entity/audit/EntitySnapshotDtoOut.java New audit snapshot DTO
src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/dto/out/entity/audit/EntityAuditDtoOut.java New audit response DTO
src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/controller/AuditController.java New REST endpoint to retrieve audit history
src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/configuration/SwaggerDescription.java Swagger constants for audit endpoint
src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/configuration/SecurityConfiguration.java Conditional load when mock security is disabled
src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/auth/UserIdentityProvider.java New abstraction for identity lookup
src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/auth/UnifiedUserProvider.java Implementation of identity extraction from SecurityContext
src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/auth/mock/MockSecurityConfiguration.java Local mock JWT security filter chain
src/main/java/com/decathlon/idp_core/infrastructure/adapters/api/auth/mock/exception/MockSecurityConfigurationException.java Specific exception for mock security setup failures
src/main/java/com/decathlon/idp_core/domain/service/entity/EntityAuditService.java Domain service to retrieve audit history
src/main/java/com/decathlon/idp_core/domain/port/audit/EntityAuditPort.java Domain port for audit retrieval
src/main/java/com/decathlon/idp_core/domain/model/entity/EntityAuditInfo.java Domain audit model record
pom.xml Add Envers dependencies
docs/src/static/swagger.yaml Document new audit endpoint + schemas
docs/src/concepts/index.md Link audit concept page from concepts index
docs/src/concepts/audit.md New audit feature documentation

Comment thread docs/src/concepts/audit.md Outdated
Comment thread src/test/java/com/decathlon/idp_core/AbstractIntegrationTest.java Outdated
Comment thread src/main/java/com/decathlon/idp_core/domain/model/entity/EntityAuditInfo.java Dismissed
@sonarqubecloud

Copy link
Copy Markdown

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.

5 participants