feat(backend): add JPA subclasses for inject expectation refacto (#5379)#6267
Conversation
|
🤖 [AI-generated] Hey @GaetanSantucci! 👋 Thanks a lot for opening PR #6267 — this is a substantial refactor and the contribution is really appreciated! 🙏 I just had a quick look and I think the description could be enhanced a little to help reviewers get through 129 changed files faster. I haven't changed anything in your description — just a gentle suggestion:
No rush at all — thanks again for contributing to OpenAEV! 🚀 |
7ec05e7 to
5687eeb
Compare
There was a problem hiding this comment.
Pull request overview
This PR refactors inject expectations by renaming the core JPA entity to BaseInjectExpectation, introducing JPA single-table inheritance with discriminator-based subclasses, and updating backend/frontend code to use a new InjectExpectationOutput DTO instead of exposing the JPA entity directly in REST responses.
Changes:
- Introduce
BaseInjectExpectationsingle-table inheritance with discriminator values and new concrete subclasses (detection/prevention/vulnerability/manual/challenge/article/document). - Add
InjectExpectationOutput+ mapper and update REST endpoints/mappers to return DTOs instead of the JPA entity. - Update TypeScript generated types and migrate frontend usage from
InjectExpectationtoInjectExpectationOutput.
Reviewed changes
Copilot reviewed 127 out of 129 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| openaev-model/src/main/java/io/openaev/helper/InjectModelHelper.java | Update enum reference to Base entity |
| openaev-model/src/main/java/io/openaev/helper/InjectExpectationHelper.java | Switch helper imports/Javadoc to Base entity |
| openaev-model/src/main/java/io/openaev/engine/model/injectexpectation/EsInjectExpectation.java | Update ES model enum imports |
| openaev-model/src/main/java/io/openaev/database/specification/InjectExpectationSpecification.java | Switch specs to Base entity generic |
| openaev-model/src/main/java/io/openaev/database/repository/InjectExpectationRepository.java | Repository generics + return types to Base entity |
| openaev-model/src/main/java/io/openaev/database/model/BaseInjectExpectation.java | Rename entity + add inheritance/discriminator + labels |
| openaev-model/src/main/java/io/openaev/database/model/TechnicalInjectExpectation.java | New abstract technical intermediate class |
| openaev-model/src/main/java/io/openaev/database/model/TableTopInjectExpectation.java | New abstract tabletop intermediate class |
| openaev-model/src/main/java/io/openaev/database/model/DetectionInjectExpectation.java | New discriminator leaf entity |
| openaev-model/src/main/java/io/openaev/database/model/PreventionInjectExpectation.java | New discriminator leaf entity |
| openaev-model/src/main/java/io/openaev/database/model/VulnerabilityInjectExpectation.java | New discriminator leaf entity |
| openaev-model/src/main/java/io/openaev/database/model/ManualInjectExpectation.java | New discriminator leaf entity |
| openaev-model/src/main/java/io/openaev/database/model/ChallengeInjectExpectation.java | New discriminator leaf entity |
| openaev-model/src/main/java/io/openaev/database/model/ArticleInjectExpectation.java | New discriminator leaf entity |
| openaev-model/src/main/java/io/openaev/database/model/DocumentInjectExpectation.java | New discriminator leaf entity |
| openaev-model/src/main/java/io/openaev/database/model/InjectExpectationTrace.java | Update relation type to Base entity |
| openaev-model/src/main/java/io/openaev/database/model/InjectTarget.java | Switch status fields to Base enums |
| openaev-model/src/main/java/io/openaev/database/model/Inject.java | Switch expectations collection + filtering to Base enums |
| openaev-model/src/main/java/io/openaev/database/model/Team.java | Switch expectations relation type + streams |
| openaev-model/src/main/java/io/openaev/database/model/TeamSimple.java | Switch expectations list type + streams |
| openaev-model/src/main/java/io/openaev/database/model/Payload.java | Update EXPECTATION_TYPE import source |
| openaev-front/src/utils/api-types.d.ts | Regenerate types to InjectExpectationOutput |
| openaev-front/src/admin/components/workspaces/custom_dashboards/widgets/WidgetUtils.tsx | Switch widget filters/series typing |
| openaev-front/src/admin/components/workspaces/custom_dashboards/widgets/configuration/histogram/WidgetSecurityCoverageSeriesSelection.tsx | Switch perspective typing |
| openaev-front/src/admin/components/simulations/simulation/validation/expectations/ExpectationUtils.ts | Update expectation predicates typing/null checks |
| openaev-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreOverTimeByTeamInPercentage.tsx | Switch chart data typing |
| openaev-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreOverTimeByTeam.tsx | Switch chart data typing |
| openaev-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreOverTimeByInjectorContract.tsx | Switch chart data typing |
| openaev-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreByTeamInPercentage.tsx | Switch chart aggregates typing |
| openaev-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreByTeam.tsx | Switch chart aggregates typing |
| openaev-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreByPlayer.tsx | Switch chart aggregates typing |
| openaev-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreByOrganization.tsx | Switch chart aggregates typing |
| openaev-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreByInject.tsx | Switch chart aggregates typing |
| openaev-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionByInjectorContract.tsx | Switch chart aggregates typing |
| openaev-front/src/admin/components/common/injects/InjectDistributionByType.tsx | Switch distribution typing |
| openaev-front/src/admin/components/common/injects/expectations/useExpectationExpirationTime.tsx | Switch hook param type |
| openaev-front/src/admin/components/common/injects/expectations/ExpectationPopover.tsx | Update casts to new output type |
| openaev-front/src/admin/components/common/injects/expectations/ExpectationFormCreate.tsx | Update casts to new output type |
| openaev-front/src/admin/components/common/injects/expectations/Expectation.ts | Store type migrated to InjectExpectationOutput |
| openaev-front/src/admin/components/atomic_testings/atomic_testing/target_result/TargetResultsDetail.tsx | Simplify active tab resolution |
| openaev-front/src/admin/components/atomic_testings/atomic_testing/target_result/InjectExpectationResultList.tsx | Update agent field typing |
| openaev-front/src/admin/components/ariane/AskArianePanel.tsx | Refactor ChatPanel props into object |
| openaev-front/src/actions/injects/inject-helper.d.ts | Helper API typing to InjectExpectationOutput |
| openaev-framework/src/main/java/io/openaev/model/inject/form/Expectation.java | Update type import to Base enums |
| openaev-framework/src/main/java/io/openaev/model/expectation/VulnerabilityExpectation.java | Update type signatures to Base enums |
| openaev-framework/src/main/java/io/openaev/model/expectation/PreventionExpectation.java | Update imports/type signatures |
| openaev-framework/src/main/java/io/openaev/model/expectation/ManualExpectation.java | Update static import to Base enums |
| openaev-framework/src/main/java/io/openaev/model/expectation/DetectionExpectation.java | Update type signatures to Base enums |
| openaev-framework/src/main/java/io/openaev/model/expectation/ChannelExpectation.java | Update type signatures to Base enums |
| openaev-framework/src/main/java/io/openaev/model/expectation/ChallengeExpectation.java | Update type signatures to Base enums |
| openaev-framework/src/main/java/io/openaev/model/Expectation.java | Update EXPECTATION_TYPE import |
| openaev-framework/src/main/java/io/openaev/expectation/ExpectationPropertiesConfig.java | Update EXPECTATION_TYPE import |
| openaev-framework/src/main/java/io/openaev/expectation/ExpectationBuilderService.java | Update static imports/types |
| openaev-api/src/main/java/io/openaev/api/expectations/dto/InjectExpectationOutput.java | New DTO for expectation output |
| openaev-api/src/main/java/io/openaev/api/expectations/mapper/InjectExpectationMapper.java | New mapper entity → DTO |
| openaev-api/src/main/java/io/openaev/rest/inject/output/InjectOutput.java | Change expectations field to DTO |
| openaev-api/src/main/java/io/openaev/utils/mapper/InjectMapper.java | Populate InjectOutput.expectations via mapper |
| openaev-api/src/main/java/io/openaev/rest/exercise/ExerciseExpectationApi.java | Return DTO list for expectations |
| openaev-api/src/main/java/io/openaev/rest/atomic_testing/AtomicTestingApi.java | Return DTO lists for target results |
| openaev-api/src/main/java/io/openaev/rest/challenge/response/ChallengeInformation.java | Expectation field becomes DTO |
| openaev-api/src/main/java/io/openaev/service/ChallengeService.java | Map expectation entity → DTO in response |
| openaev-api/src/main/java/io/openaev/utils/ResultUtils.java | Switch expectation clone type to Base entity |
| openaev-api/src/main/java/io/openaev/utils/InjectUtils.java | Switch expectation stream/generics |
| openaev-api/src/main/java/io/openaev/utils/InjectExpectationResultUtils.java | Switch generic signatures to Base entity |
| openaev-api/src/main/java/io/openaev/utils/inject_expectation_result/ExpectationResultBuilder.java | Switch signatures to Base entity |
| openaev-api/src/main/java/io/openaev/service/InjectImportService.java | Switch expectation ref type to Base entity |
| openaev-api/src/main/java/io/openaev/service/InjectExpectationTraceService.java | Switch expectation placeholder type to Base entity |
| openaev-api/src/main/java/io/openaev/service/ExerciseExpectationService.java | Return Base entity list from service |
| openaev-api/src/main/java/io/openaev/service/ChannelService.java | Switch expectation generics to Base entity |
| openaev-api/src/main/java/io/openaev/rest/payload/service/PayloadService.java | Switch expectation enum types to Base |
| openaev-api/src/main/java/io/openaev/rest/payload/output/PayloadOutput.java | Switch expectations enum type to Base |
| openaev-api/src/main/java/io/openaev/rest/payload/form/PayloadCreateInput.java | Switch EXPECTATION_TYPE import source |
| openaev-api/src/main/java/io/openaev/rest/payload/form/PayloadUpdateInput.java | Switch default expectations enum type |
| openaev-api/src/main/java/io/openaev/rest/payload/form/PayloadUpsertInput.java | Switch default expectations enum type |
| openaev-api/src/main/java/io/openaev/rest/injector_contract/InjectorContractContentUtils.java | Switch predefined expectations enum type |
| openaev-api/src/main/java/io/openaev/scheduler/jobs/InjectsExecutionJob.java | Switch status enum list type to Base |
| openaev-api/src/main/java/io/openaev/expectation/ExpectationType.java | Switch EXPECTATION_TYPE import source |
| openaev-api/src/main/java/io/openaev/collectors/expectations_expiration_manager/utils/ExpectationUtils.java | Switch signatures to Base entity |
| openaev-api/src/main/java/io/openaev/collectors/expectations_expiration_manager/service/ExpectationsExpirationManagerService.java | Switch paging/list types to Base entity |
| openaev-api/src/main/java/io/openaev/api/threat_arsenal/dto/CommonActionInput.java | Switch expectations enum type |
| openaev-api/src/main/java/io/openaev/api/threat_arsenal/dto/ThreatArsenalActionCreateInput.java | Switch EXPECTATION_TYPE import |
| openaev-api/src/main/java/io/openaev/api/threat_arsenal/dto/ThreatArsenalActionUpdateInput.java | Switch expectations enum type |
| openaev-api/src/main/java/io/openaev/api/threat_arsenal/dto/ThreatArsenalActionFullOutput.java | Switch expectations enum type |
| openaev-api/src/main/java/io/openaev/migration/V2_63__InjectExpectation_upgrade.java | Update static imports to Base enums |
| openaev-api/src/main/java/io/openaev/injectors/openaev/OpenAEVImplantExecutor.java | Update EXPECTATION_TYPE references |
| openaev-api/src/main/java/io/openaev/service/targets/search/HelperTargetSearchAdaptor.java | Switch merged expectations list type |
| openaev-api/src/main/java/io/openaev/rest/inject/service/InjectService.java | Switch extracted expectations stream type |
| openaev-api/src/main/java/io/openaev/rest/custom_dashboard/WidgetService.java | Switch status enum names source |
| openaev-api/src/main/java/io/openaev/service/ExpectationService.java | Switch static imports to Base enums |
| openaev-api/src/test/java/io/openaev/utils/helpers/InjectTestHelper.java | Switch helper save signature to Base entity |
| openaev-api/src/test/java/io/openaev/utils/fixtures/WidgetFixture.java | Switch widget fixture enum types |
| openaev-api/src/test/java/io/openaev/utils/fixtures/ThreatArsenalInputFixture.java | (Now empty) threat arsenal fixture |
| openaev-api/src/test/java/io/openaev/utils/fixtures/InjectFixture.java | Update expectation type in test content |
| openaev-api/src/test/java/io/openaev/utils/fixtures/InjectExpectationFixture.java | Switch fixture return type to Base entity |
| openaev-api/src/test/java/io/openaev/utils/fixtures/ExpectationResultsByTypeFixture.java | Switch status enum import source |
| openaev-api/src/test/java/io/openaev/utils/fixtures/ExpectationResultByTypeFixture.java | Switch status enum import source |
| openaev-api/src/test/java/io/openaev/utils/fixtures/ExpectationFixture.java | Switch expectation type to Base enums |
| openaev-api/src/test/java/io/openaev/utils/fixtures/composers/InjectExpectationComposer.java | Switch composer generic to Base entity |
| openaev-api/src/test/java/io/openaev/utils/fixtures/composers/InjectComposer.java | Switch expectations list type |
| openaev-api/src/test/java/io/openaev/service/stix/SecurityCoverageServiceTest.java | Switch enums/types to Base entity |
| openaev-api/src/test/java/io/openaev/service/stix/SecurityCoverageSendJobServiceTest.java | Switch enums/types to Base entity |
| openaev-api/src/test/java/io/openaev/service/InjectExpectationTraceServiceTest.java | Switch types to Base entity |
| openaev-api/src/test/java/io/openaev/service/InjectExpectationServiceTest.java | Switch test types to Base entity |
| openaev-api/src/test/java/io/openaev/service/ExerciseExpectationServiceTest.java | Switch service return types |
| openaev-api/src/test/java/io/openaev/service/ChannelServiceTest.java | Switch captured types to Base entity |
| openaev-api/src/test/java/io/openaev/service/ChallengeServiceTest.java | Switch created expectations to Base entity |
| openaev-api/src/test/java/io/openaev/rest/scenario/ScenarioSimulationApiTest.java | Stabilize ordering assertion on timestamps |
| openaev-api/src/test/java/io/openaev/rest/InjectExpectationTraceApiTest.java | Switch saved expectation type |
| openaev-api/src/test/java/io/openaev/rest/inject/service/InjectServiceTest.java | Switch expectation type in JSON content |
| openaev-api/src/test/java/io/openaev/rest/inject/InjectApiTest.java | Switch repository result type |
| openaev-api/src/test/java/io/openaev/rest/inject_expectation/ExpectationsExpirationManagerServiceTest.java | Switch expectation types in tests |
| openaev-api/src/test/java/io/openaev/rest/ExpectationApiTest.java | Switch expectation types + helper method params |
| openaev-api/src/test/java/io/openaev/rest/exercise/service/ExerciseServiceUnitTest.java | Switch status enum import source |
| openaev-api/src/test/java/io/openaev/rest/dashboard/DashboardApiTest.java | Switch enums/types to Base entity |
| openaev-api/src/test/java/io/openaev/rest/AtomicTestingApiTest.java | Switch types + update JSON assertions |
| openaev-api/src/test/java/io/openaev/injects/technical_inject/OpenAEVImplantExecutorTest.java | Switch expectation type provider + generics |
| openaev-api/src/test/java/io/openaev/injects/manual/ManualExecutorTest.java | Switch expectation type constant |
| openaev-api/src/test/java/io/openaev/injects/email/EmailExecutorTest.java | Switch expectation typing + comments |
| openaev-api/src/test/java/io/openaev/injects/atomic_testing/ResultUtilsTest.java | Switch expectation type constants |
| openaev-api/src/test/java/io/openaev/database/model/StepRepositoryTest.java | Switch expectation fixture types |
| openaev-api/src/test/java/io/openaev/api/threat_arsenal/ThreatArsenalApiTest.java | Switch expectations array type |
Comments suppressed due to low confidence (3)
openaev-api/src/test/java/io/openaev/utils/fixtures/ThreatArsenalInputFixture.java:2
- issue (blocking): This test fixture file is now empty (no package/class declaration), but it is still imported by multiple threat-arsenal tests. This will fail compilation; either restore the fixture implementation or delete it and update all callers.
openaev-model/src/main/java/io/openaev/database/model/BaseInjectExpectation.java:32 - issue (blocking): With SINGLE_TABLE inheritance, existing DB rows with
inject_expectation_type = 'TEXT'currently have no matching discriminator mapping (no leaf class for TEXT, and the root entity has no @DiscriminatorValue). Hibernate will typically fail with an "unknown discriminator value" when loading those rows. Map TEXT to the root entity (or add a dedicated TextInjectExpectation entity).
openaev-model/src/main/java/io/openaev/database/model/BaseInjectExpectation.java:105 - issue (blocking):
typeis mapped to the discriminator column but markedinsertable = false, updatable = false, so callingsetType(...)will NOT persist the expectation type. There are still production call sites that donew BaseInjectExpectation()+setType(...)/setDetection(...)(e.g. InjectExpectationUtils.expectationConverter), which would now persist the discriminator as the root value (after adding @DiscriminatorValue, likely TEXT) and later reload as the wrong subclass/type. To keep behavior stable, creation code needs to instantiate the correct leaf entity (DetectionInjectExpectation, PreventionInjectExpectation, etc.), or the inheritance discriminator must be moved to a different column.
ee3af78 to
4271962
Compare
Codecov Report❌ Patch coverage is ❌ Your patch check has failed because the patch coverage (0.00%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #6267 +/- ##
============================================
+ Coverage 44.33% 44.38% +0.05%
- Complexity 7472 7485 +13
============================================
Files 2313 2313
Lines 64052 64150 +98
Branches 8522 8543 +21
============================================
+ Hits 28396 28472 +76
- Misses 33847 33850 +3
- Partials 1809 1828 +19
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
f2e0bea to
b3e5ebf
Compare
| withExpectedMultiSelectableFlag( | ||
| this.expectationBuilderService.buildTextExpectation())); | ||
| case DOCUMENT -> | ||
| case TEXT, DOCUMENT -> |
There was a problem hiding this comment.
be careful here, when is type is text we should call buildTextExpectation rather than buildDocumentExpectation
| case Expectation ignored when expectation.type() == TEXT -> { | ||
| injectExpectation.setType(TEXT); | ||
| throw new IllegalStateException( | ||
| "TEXT expectation type is deprecated and no longer supported"); |
There was a problem hiding this comment.
Are Text and Document expectations deprecated as of this PR? If yes, should we do the same for document expectation ?
| List.of(MANUAL, CHALLENGE, ARTICLE); | ||
|
|
||
| private ExpectationUtils() {} | ||
|
|
There was a problem hiding this comment.
Please restore the documentation in this file
|
|
||
| // endregion | ||
|
|
||
| @Setter |
There was a problem hiding this comment.
Fields specific to leaf classes should be moved down to the leaf, not kept in the parent.
| @JsonProperty("inject_expectation_traces") | ||
| private List<InjectExpectationTrace> traces = new ArrayList<>(); | ||
|
|
||
| public String getSuccessLabel() { |
There was a problem hiding this comment.
this function should be defined and handled by the leaf class, wdyt ?
|
|
||
| @Entity | ||
| @DiscriminatorValue(BaseInjectExpectation.ExpectationTypeString.MANUAL) | ||
| public class ManualInjectExpectation extends TechnicalInjectExpectation { |
There was a problem hiding this comment.
ManualInjectExpectation inherits from TabletopInjectExpectation instead of TechnicalInjectExpectation
| } | ||
|
|
||
| @Override | ||
| public String getSuccessLabel() { |
There was a problem hiding this comment.
All TabletopInjectExpectation subclasses return the same values for getSuccessLabel and getFailureLabel — these should be moved up to the TabletopInjectExpectation class.
81cc7b5 to
27b7655
Compare
Signed-off-by: Antoine MAZEAS <antoine.mazeas@filigran.io>
…or inject expectation dto Signed-off-by: Marine LM <marine.lemezo@filigran.io>
…cation Signed-off-by: Marine LM <marine.lemezo@filigran.io>
Signed-off-by: Marine LM <marine.lemezo@filigran.io>
Signed-off-by: Marine LM <marine.lemezo@filigran.io>
Signed-off-by: Marine LM <marine.lemezo@filigran.io>
Signed-off-by: Marine LM <marine.lemezo@filigran.io>
Signed-off-by: Marine LM <marine.lemezo@filigran.io>
Signed-off-by: Marine LM <marine.lemezo@filigran.io>
5291b54 to
4a1bab7
Compare

Proposed changes
Testing Instructions
Related issues
Checklist