feat(core): audit implementation#69
Open
RVANDO12 wants to merge 11 commits into
Open
Conversation
db2e766 to
acac340
Compare
Code Coverage OverviewLanguages: Java Java / code-coverage/jacocoThe 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.
Updated |
b7be593 to
3a4e46a
Compare
etiennej70
reviewed
Jun 16, 2026
Contributor
There was a problem hiding this comment.
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 |
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



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.
Key Architectures & Feature Additions:
hibernate-enversto capture and persist historical snapshots into matching database target tables (*_aud) on all core entity transactions.spring-data-enversand updated repositories (JpaEntityRepository, etc.) to extendRevisionRepository. This unlocks access to the full timeline history natively without relying on complex handwritten native JOIN operations.EntityTrackingRevisionListenercoupled with@ElementCollectionmapping to dynamically log the precise list of elements modified inside a single transaction unit.suborid) across JWT, OAuth2, and OpenID scopes.AnonymousAuthenticationToken) and missing context environments to avoid NullPointerExceptions (NPEs) when interacting with unauthenticated callers, background jobs, or malicious scanner traffic.*_MOD), and deploying optimal query indexes to support scale performance.Review
The reviewer must double-check these points :
!after the type/scope to identify the breakingchange 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
POSTrequest to register a brand new entity (web-api-audit).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.
Action: Submitting a PUT request modifying structural parameter fields (e.g. updating baseUrl and port).
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.
Action: Issuing a DELETE command targeting the runtime asset item tracker.
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