Skip to content

Modify actions pool which update last modification date#982

Open
Meklo wants to merge 6 commits intomainfrom
marcellinh/update-last-modification-date
Open

Modify actions pool which update last modification date#982
Meklo wants to merge 6 commits intomainfrom
marcellinh/update-last-modification-date

Conversation

@Meklo
Copy link
Copy Markdown
Contributor

@Meklo Meklo commented Apr 28, 2026

PR Summary

Add lastModificationDate update for following actions :

  • Update network vizualization parameters
  • Update a root network associated case
  • Delete a root network
  • Recreate a study network from a case or root network
  • Restore a deleted node
  • Update the node aliases
  • Create a dynamic simulation event
  • Update a dynamic simulation event
  • Delete a dynamic simulation event
  • Launch any type of computation

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 28, 2026

📝 Walkthrough

Walkthrough

Multiple mutating controller endpoints now accept a userId header and forward it to StudyService; the service emits notificationService.emitElementUpdated(studyUuid, userId) alongside existing notifications across many mutation and computation flows (root network deletion/update, network recreation, load-flow/security runs, dynamic simulation events, node restore, and node-alias updates). Tests updated to assert the extra notification.

Changes

Service + Controller + Tests

Layer / File(s) Summary
Data Shape / Signatures
src/main/java/org/gridsuite/study/server/controller/StudyController.java, src/main/java/org/gridsuite/study/server/service/StudyService.java
Controller endpoints deleteRootNetwork, restoreNodes, setNodeAliases now accept @RequestHeader(HEADER_USER_ID) String userId; corresponding StudyService methods extended to include String userId parameter.
Core Implementation
src/main/java/org/gridsuite/study/server/service/StudyService.java
Added notificationService.emitElementUpdated(studyUuid, userId) in many mutation/computation flows: deleteRootNetworks, updateRootNetworkRequest, internal recreateNetwork, load-flow rerun/requests, security/sensitivity/short-circuit/voltage init/state estimation/PCC min runs, dynamic simulation runs, and dynamic simulation event CRUD (now emitted from finally blocks); updateNodeAliases now emits this and removed emitSpreadsheetNodeAliasesChanged.
Wiring / Controller
src/main/java/org/gridsuite/study/server/controller/StudyController.java
Controller reads HEADER_USER_ID and forwards userId to service calls; HTTP responses unchanged.
Tests
src/test/java/org/gridsuite/study/server/rootnetworks/RootNetworkTest.java, src/test/java/org/gridsuite/study/server/NetworkModificationTreeTest.java, src/test/java/org/gridsuite/study/server/studycontroller/StudyTest.java
Tests updated to include USER_ID header/argument where applicable and to assert checkElementUpdatedMessageSent(studyUuid, userId) after existing notifications.
Manifest
pom.xml
Touched (reported in manifests).

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client
    participant Controller as StudyController
    participant Service as StudyService
    participant Repo as Repository
    participant Notification as NotificationService

    Client->>Controller: HTTP mutating request (Header: userId)
    Controller->>Service: method(..., userId)
    activate Service
    Service->>Repo: persist/update/delete
    Repo-->>Service: result
    Service->>Notification: emitStudyChanged(...details)
    Service->>Notification: emitElementUpdated(studyUuid, userId)
    deactivate Service
    Service-->>Controller: 200 OK
    Controller-->>Client: 200 OK
Loading

Suggested reviewers

  • SlimaneAmar
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Modify actions pool which update last modification date' directly describes the main objective of the PR: adding lastModificationDate updates to various actions.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description clearly states the intent to update lastModificationDate for specific actions, which aligns with the changeset that adds userId tracking and emitElementUpdated notifications across multiple service operations.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/java/org/gridsuite/study/server/service/StudyService.java (1)

3000-3008: ⚠️ Potential issue | 🟠 Major

Don’t update lastModificationDate when event CRUD fails.

emitElementUpdated(studyUuid, userId) is in finally, so it fires even if saveEvent(...)/deleteEvents(...) throws and no change was applied. That will mark the study as modified on failed requests.

Suggested fix
     try {
         dynamicSimulationEventService.saveEvent(nodeUuid, event);
+        notificationService.emitElementUpdated(studyUuid, userId);
     } finally {
         notificationService.emitEndEventCrudNotification(studyUuid, nodeUuid, childrenUuids);
-        notificationService.emitElementUpdated(studyUuid, userId);
     }

Apply the same move in updateDynamicSimulationEvent(...) and deleteDynamicSimulationEvents(...).

Also applies to: 3013-3021, 3026-3034

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/org/gridsuite/study/server/service/StudyService.java` around
lines 3000 - 3008, The code currently calls
notificationService.emitElementUpdated(studyUuid, userId) inside the finally
block so it runs even when
dynamicSimulationEventService.saveEvent/updateEvent/deleteEvents throws; move
the emitElementUpdated call so it only runs on successful completion (i.e.,
after saveEvent/updateEvent/deleteEvents returns without exception) while
keeping emitEndEventCrudNotification in the finally block; apply this change in
createDynamicSimulationEvent, updateDynamicSimulationEvent and
deleteDynamicSimulationEvents, referencing
notificationService.emitElementUpdated,
notificationService.emitEndEventCrudNotification and the
dynamicSimulationEventService methods (saveEvent/updateEvent/deleteEvents).
🧹 Nitpick comments (1)
src/test/java/org/gridsuite/study/server/rootnetworks/RootNetworkTest.java (1)

838-838: Add coverage for the new last-modified side effect.

Line 838 updates the new userId parameter, but this test still only checks ordering. A small assertion that the delete flow emits the generic element-updated notification would keep the PR’s actual behavior covered.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/test/java/org/gridsuite/study/server/rootnetworks/RootNetworkTest.java`
at line 838, The test calls studyService.deleteRootNetworks(studyEntity.getId(),
List.of(result.get(1).rootNetworkUuid()), USER_ID) but only asserts ordering;
add an assertion to verify the new last-modified/user-id side effect by
asserting that the delete flow emitted the generic element-updated notification
(e.g., check the notifier/mock was called with an ElementUpdated event for the
affected study or root network and that the payload includes the updated
lastModified/lastModifiedBy or USER_ID); locate the verification near the
existing assertions after the delete call and use the same notifier/mock used
elsewhere in this test class to assert the expected event was emitted.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/main/java/org/gridsuite/study/server/service/StudyService.java`:
- Around line 3000-3008: The code currently calls
notificationService.emitElementUpdated(studyUuid, userId) inside the finally
block so it runs even when
dynamicSimulationEventService.saveEvent/updateEvent/deleteEvents throws; move
the emitElementUpdated call so it only runs on successful completion (i.e.,
after saveEvent/updateEvent/deleteEvents returns without exception) while
keeping emitEndEventCrudNotification in the finally block; apply this change in
createDynamicSimulationEvent, updateDynamicSimulationEvent and
deleteDynamicSimulationEvents, referencing
notificationService.emitElementUpdated,
notificationService.emitEndEventCrudNotification and the
dynamicSimulationEventService methods (saveEvent/updateEvent/deleteEvents).

---

Nitpick comments:
In `@src/test/java/org/gridsuite/study/server/rootnetworks/RootNetworkTest.java`:
- Line 838: The test calls studyService.deleteRootNetworks(studyEntity.getId(),
List.of(result.get(1).rootNetworkUuid()), USER_ID) but only asserts ordering;
add an assertion to verify the new last-modified/user-id side effect by
asserting that the delete flow emitted the generic element-updated notification
(e.g., check the notifier/mock was called with an ElementUpdated event for the
affected study or root network and that the payload includes the updated
lastModified/lastModifiedBy or USER_ID); locate the verification near the
existing assertions after the delete call and use the same notifier/mock used
elsewhere in this test class to assert the expected event was emitted.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 05ff2696-7603-4477-8b29-29e9846d20ec

📥 Commits

Reviewing files that changed from the base of the PR and between b9a0aa4 and 59e60db.

📒 Files selected for processing (3)
  • src/main/java/org/gridsuite/study/server/controller/StudyController.java
  • src/main/java/org/gridsuite/study/server/service/StudyService.java
  • src/test/java/org/gridsuite/study/server/rootnetworks/RootNetworkTest.java

Copy link
Copy Markdown
Contributor

@AbdelHedhili AbdelHedhili left a comment

Choose a reason for hiding this comment

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

Can you add / modify the tests to check for the newly emitted msg

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/java/org/gridsuite/study/server/service/StudyService.java (1)

3000-3036: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

emitElementUpdated fires on failure when placed inside the finally block.

All three dynamic simulation event methods (createDynamicSimulationEvent, updateDynamicSimulationEvent, deleteDynamicSimulationEvents) put emitElementUpdated inside the finally block. When saveEvent/deleteEvents throws an exception, Spring's @Transactional rolls back the DB change, but the emitElementUpdated notification is still dispatched — telling consumers that the lastModificationDate was updated even though nothing was actually persisted.

The established pattern everywhere else in this class (e.g., createNetworkModification line 1750, deleteNetworkModifications line 2124, stashNetworkModifications line 2141) places emitElementUpdated after the try-finally block so it is only reached on success.

🐛 Proposed fix – move `emitElementUpdated` outside the `finally` blocks
     try {
         dynamicSimulationEventService.saveEvent(nodeUuid, event);
     } finally {
         notificationService.emitEndEventCrudNotification(studyUuid, nodeUuid, childrenUuids);
-        notificationService.emitElementUpdated(studyUuid, userId);
     }
+    notificationService.emitElementUpdated(studyUuid, userId);
     postProcessEventCrud(studyUuid, nodeUuid);
 }

Apply the same change to updateDynamicSimulationEvent (line 3019–3020) and deleteDynamicSimulationEvents (line 3032–3033).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/org/gridsuite/study/server/service/StudyService.java` around
lines 3000 - 3036, Three methods (createDynamicSimulationEvent,
updateDynamicSimulationEvent, deleteDynamicSimulationEvents) call
notificationService.emitElementUpdated from inside the finally block so the
"element updated" notification fires even on transaction rollback; move the
emitElementUpdated(studyUuid, userId) call out of each finally block and place
it after the try-finally (so only executed on success), keeping
notificationService.emitEndEventCrudNotification(studyUuid, nodeUuid,
childrenUuids) inside the finally and leaving postProcessEventCrud(studyUuid,
nodeUuid) in its current position.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/main/java/org/gridsuite/study/server/service/StudyService.java`:
- Around line 3000-3036: Three methods (createDynamicSimulationEvent,
updateDynamicSimulationEvent, deleteDynamicSimulationEvents) call
notificationService.emitElementUpdated from inside the finally block so the
"element updated" notification fires even on transaction rollback; move the
emitElementUpdated(studyUuid, userId) call out of each finally block and place
it after the try-finally (so only executed on success), keeping
notificationService.emitEndEventCrudNotification(studyUuid, nodeUuid,
childrenUuids) inside the finally and leaving postProcessEventCrud(studyUuid,
nodeUuid) in its current position.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ab75fd57-bccb-43ef-8a82-448ec0c1cc8c

📥 Commits

Reviewing files that changed from the base of the PR and between 59e60db and 09b98a8.

📒 Files selected for processing (1)
  • src/main/java/org/gridsuite/study/server/service/StudyService.java

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/java/org/gridsuite/study/server/service/StudyService.java (1)

1013-1032: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Avoid double emitElementUpdated on non-security rerun path.

On Line 1031, rerunLoadflow(...) emits emitElementUpdated(...), but on the non-security branch it already goes through handleLoadflowRequest(...), which emits again on Line 1084. This causes duplicate notifications for a single action.

Suggested fix
@@ public void rerunLoadflow(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, UUID loadflowResultUuid, Boolean withRatioTapChangers, String userId) {
-        notificationService.emitElementUpdated(studyEntity.getId(), userId);

Also applies to: 1072-1085

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/org/gridsuite/study/server/service/StudyService.java` around
lines 1013 - 1032, The method rerunLoadflow currently calls
notificationService.emitElementUpdated(...) unconditionally but the non-security
path already triggers the same notification inside handleLoadflowRequest(...),
causing duplicate notifications; remove the redundant emitElementUpdated call
from rerunLoadflow (or conditionally call it only for the security branch) so
that emitElementUpdated is only invoked once per action — update rerunLoadflow
accordingly and ensure behavior for both branches (security branch uses
invalidateNodeTree/buildNode then emits, non-security branch relies on
handleLoadflowRequest to emit).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/java/org/gridsuite/study/server/service/StudyService.java`:
- Around line 3010-3014: The emitElementUpdated call must not run on failures;
remove or move notificationService.emitElementUpdated(studyUuid, userId) out of
the finally block and invoke it only after the CRUD operation completes
successfully (i.e. after dynamicSimulationEventService.saveEvent / update /
delete returns without throwing), while keeping
notificationService.emitEndEventCrudNotification(studyUuid, nodeUuid,
childrenUuids) in the finally block; apply the same change for the other event
CRUD blocks that call dynamicSimulationEventService (the create/update/delete
branches referenced) so emitElementUpdated is only called on success.

---

Outside diff comments:
In `@src/main/java/org/gridsuite/study/server/service/StudyService.java`:
- Around line 1013-1032: The method rerunLoadflow currently calls
notificationService.emitElementUpdated(...) unconditionally but the non-security
path already triggers the same notification inside handleLoadflowRequest(...),
causing duplicate notifications; remove the redundant emitElementUpdated call
from rerunLoadflow (or conditionally call it only for the security branch) so
that emitElementUpdated is only invoked once per action — update rerunLoadflow
accordingly and ensure behavior for both branches (security branch uses
invalidateNodeTree/buildNode then emits, non-security branch relies on
handleLoadflowRequest to emit).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c017758e-196b-42a3-b5f8-c32bcf60f2ca

📥 Commits

Reviewing files that changed from the base of the PR and between 09b98a8 and 75c01d9.

📒 Files selected for processing (3)
  • src/main/java/org/gridsuite/study/server/service/StudyService.java
  • src/test/java/org/gridsuite/study/server/NetworkModificationTreeTest.java
  • src/test/java/org/gridsuite/study/server/studycontroller/StudyTest.java

Comment thread src/main/java/org/gridsuite/study/server/service/StudyService.java
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented May 5, 2026

@Meklo Meklo requested a review from AbdelHedhili May 5, 2026 13:50
@Meklo
Copy link
Copy Markdown
Contributor Author

Meklo commented May 5, 2026

My bad, I think initially it didn't require test changes and I forgot to add them as the scope grew
I also added the launching of computations to the pool following the green flag of a PO

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