Skip to content

Conversation

@Retoocs
Copy link
Contributor

@Retoocs Retoocs commented Dec 11, 2025

Description

  • Renamed user and userList field to actor and actorList field
  • Updated initialization mechanism of actor/actorList fields, so that it can handle also groups as values
  • Updated authorization mechanism of actorRef (renamed userRef), so it can handle group as value of actorList.
  • change of ActorField can be done just by actor id -> change myActorField value { loggedUser().stringId }

Implements NAE-2285

Dependencies

No new dependencies were introduced

Third party dependencies

No new dependencies were introduced

Blocking Pull requests

The build of this changes depends on PR: petriflow/petriflow#27.

How Has Been This Tested?

Manually and by existing tests

Test Configuration

Name Tested on
OS Ubuntu 24.04.1 LTS
Runtime Java 21
Dependency Manager Maven 3.6.3
Framework version Spring Boot 3.4.4
Run parameters
Other configuration

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • My changes have been checked, personally or remotely, with @...
  • I have commented my code, particularly in hard-to-understand areas
  • I have resolved all conflicts with the target branch of the PR
  • I have updated and synced my code with the target branch
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing tests pass locally with my changes:
    • Lint test
    • Unit tests
    • Integration tests
  • I have checked my contribution with code analysis tools:
  • I have made corresponding changes to the documentation:
    • Developer documentation
    • User Guides
    • Migration Guides

Summary by CodeRabbit

  • New Features

    • Actor model now accepts both users and groups — actor fields/lists can contain group entries and resolve accordingly.
  • Refactor

    • System-wide migration from user-centric to actor-centric terminology and flows (actor/actorList/actorRef), affecting permissions, task/case resolution, search, export and runtime behavior.
  • Documentation

    • Docs and examples updated to reflect actor/actorList/actorRef and group-aware permissions.
  • Tests

    • Tests updated/added to cover actor and group scenarios.

✏️ Tip: You can customize this high-level summary in your review settings.

- change user field types to actor field types in process files
- update initialization of ActorListField in ActionDelegate and DataService
- introduce new way of initialization of ActorField in ActionDelegate and DataService
- refactor attributes of elastic data fields
- update ElasticCaseMappingService according to refactored fields
- update Importer to work also with actor field types
- refactor ActorField and ActorListField (renamed user fields)
- apply polymorphism on actor field values (user field values)
- introduce GroupFieldValue
- add todos
- use actorRef instead of userRef in processes
- update process model validations
- remove unnecessary transactional annotations
- update process importer
- use actorRef keyword instead of userRef in the project
- update initialization of actorRef attributes in Case and Task
- update authorization implementation to handle groups
- fix authorization bug
- update elastic document attributes
- update DataSearchRequestTest
- update DataSearchRequestTest
- update permission queries for Elasticsearch
- update tests
- update permission queries for MongoDB
- update permission queries for Elasticsearch
- update tests
- update permission queries for MongoDB
- update documentation
- rename user and userList fields to actor and actorList
- update QueryDSLViewPermissionTest
- update TaskAuthorizationServiceTest
- update WorkflowAuthorizationServiceTest
@Retoocs Retoocs self-assigned this Dec 11, 2025
@coderabbitai
Copy link

coderabbitai bot commented Dec 11, 2025

Walkthrough

Replaces user-centric types and logic with actor-centric ones across the codebase: introduces Actor/ActorList field/value types and GroupFieldValue, updates mappings, search/permission/query flows, importer/validators, services/interfaces, XML resources, tests and docs; actor resolution falls back from user → group.

Changes

Cohort / File(s) Summary
Domain — actor data types
nae-object-library/src/main/java/.../dataset/ActorField.java, .../ActorListField.java, .../ActorFieldValue.java, .../ActorListFieldValue.java, .../GroupFieldValue.java, .../FieldType.java
Add Actor/ActorList types and ActorFieldValue/ActorListFieldValue; add GroupFieldValue; replace USER/USERLIST enum constants with ACTOR/ACTORLIST; constructors and public APIs updated.
Elastic domain — actor mapping
nae-object-library/src/main/java/.../elastic/domain/ActorField.java, .../ActorListField.java, .../ActorMappingData.java
New elastic ActorField/ActorListField and ActorMappingData for actor username/fullName/actorId mapping used by indexing/mapping.
Elastic domain — general refactor
nae-object-library/src/main/java/.../{BooleanField,ButtonField,CaseField,DataField,DateField,FileField,FilterField,I18nField,MapField,NumberField,StringCollectionField,TextField}.java
Migrate array-backed fields to List/Collection, tighten visibilities, update constructors and getValue implementations.
Elastic models — case & task
nae-object-library/src/main/java/.../ElasticCase.java, .../ElasticTask.java
Rename userRefs/users/viewUserRefs/viewUsers/negativeViewUsers → actorRefs/actors/viewActorRefs/viewActors/negativeViewActors; update constructors and update paths.
Petri net domain & transitions
nae-object-library/src/main/java/.../PetriNet.java, .../Transition.java
Rename userRefs → actorRefs; replace addUserRef/addUserPermission with actor equivalents and adapt copy/clone logic.
Services — mapping & permissions
application-engine/src/main/java/.../ElasticCaseMappingService.java, .../ElasticViewPermissionService.java
Replace UserField/UserListField transforms with ActorField/ActorListField transforms; add transformActorField/transformActorListField; build actor-centric permission queries, expand actor terms with group IDs.
Search & query services
application-engine/src/main/java/.../{CaseSearchService,TaskSearchService,MongoSearchService}.java
Replace view-user predicates with actor predicates; add getActorIdsOfUser helper (user + group ids) and new actor-query builders/public predicate methods.
Workflow/task/data/authorization services
application-engine/src/main/java/.../{TaskService,WorkflowService,DataService,AbstractAuthorizationService,TaskAuthorizationService,WorkflowAuthorizationService}.java
Rename resolveUserRef → resolveActorRef; integrate GroupService; add permission-merge helpers; implement makeActorFieldValue/makeActorListFieldValue that return UserFieldValue or GroupFieldValue.
Importer & validators
application-engine/src/main/java/.../{Importer,FieldFactory,DataValidator,DocumentValidator,IModelValidator,TransitionValidator}.java
Replace USER/USER_LIST → ACTOR/ACTOR_LIST in factory/parse flows; change Field typing to Field<?>; add deprecation warnings and parameterized logging; rename actor-ref methods.
Export & impersonation
application-engine/src/main/java/.../{ExportService,ImpersonationAuthorizationService}.java
Export reading updated to handle Actor/ActorList values (UserFieldValue or GroupFieldValue); impersonation search path switched to actorIdValue.
Controller / minor
application-engine/src/main/java/.../UserController.java
Only comment/identifier edits (userId → actorId) inside commented code; no functional changes.
Resources & Petri nets
application-engine/src/main/resources/petriNets/**, application-engine/src/test/resources/**
Mass XML updates: data types user→actor, userList→actorList and tags userRef/usersRef → actorRef/actorRef; update ids/titles and sample documents.
Tests
application-engine/src/test/groovy/**
Tests updated to actorList/actor types; many tests autowire GroupService; test names and assertions changed to actor/group semantics.
Docs
docs/roles/actorlist.md (new), docs/roles/permissions.md, docs/search/elastic_mapping.md, docs/_sidebar.md, (removed) docs/roles/userlist.md
Add ActorList/ActorRef documentation, replace user-list references with actor-list terminology and remove old userlist doc.
ActionDelegate (Groovy)
application-engine/src/main/groovy/.../ActionDelegate.groovy
Replace UserListField/UserListFieldValue with ActorListField/ActorListFieldValue and support GroupFieldValue fallback when resolving IDs to actors.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Client
    participant AuthSvc as AuthorizationService
    participant Index as Elastic/Mongo Index
    participant UserSvc as UserService
    participant GroupSvc as GroupService
    note right of AuthSvc: Request-time actor resolution + permission merge

    Client->>AuthSvc: Request permission-check / action
    AuthSvc->>UserSvc: getLoggedUser(userToken)
    UserSvc-->>AuthSvc: LoggedUser (id, groupIds)
    AuthSvc->>AuthSvc: build actorIdSet = {userId} ∪ groupIds
    loop for each actorId in actorIdSet
        AuthSvc->>Index: query permissions by actorId (actorIdValue)
        Index-->>AuthSvc: permission bits for actorId
    end
    AuthSvc->>AuthSvc: merge permission maps (preserve negatives)
    AuthSvc-->>Client: allow / deny decision
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Areas needing extra attention:
    • Actor resolution & group fallback: DataService.makeActorFieldValue / makeActorListFieldValue and IDataService interface change.
    • Permission merge logic and negative-permission preservation: AbstractAuthorizationService and all callers (Task/Workflow/TaskAuthorizationService).
    • Elastic mapping and new ActorMappingData interactions (ElasticCaseMappingService and nae-object-library changes).
    • Public API/interface renames: IDataService, ITaskService, IWorkflowService and implementing classes.
    • Importer broad refactor: Field<?> typing, transactional annotation removals, and extensive XML resource renames affecting compatibility.

Possibly related PRs

Pre-merge checks

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.83% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'NAE-2285 Group as a value of userlists' clearly summarizes the main objective of renaming user-centric fields to actor-centric ones and enabling groups as values in actor lists, which is the primary change throughout the changeset.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f4ec90f and 80f2493.

📒 Files selected for processing (1)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java (2 hunks)
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: Retoocs
Repo: netgrif/application-engine PR: 397
File: application-engine/src/main/resources/petriNets/engine-processes/org_group.xml:36-39
Timestamp: 2025-12-12T12:35:57.760Z
Learning: In the org_group.xml file (application-engine/src/main/resources/petriNets/engine-processes/org_group.xml), variable names in action blocks like userField and user_selection should be kept as-is even when the field type changes from "user" to "actor".
Learnt from: Retoocs
Repo: netgrif/application-engine PR: 397
File: application-engine/src/test/groovy/com/netgrif/application/engine/impersonation/ImpersonationServiceTest.groovy:18-20
Timestamp: 2025-12-12T12:40:25.863Z
Learning: In the actor refactoring, UserFieldValue is a subclass of ActorFieldValue, and ActorListFieldValue accepts ActorFieldValue instances. Therefore, passing UserFieldValue instances to ActorListFieldValue is valid through polymorphism.
📚 Learning: 2025-08-19T19:38:19.471Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 338
File: nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/FileFieldValue.java:40-51
Timestamp: 2025-08-19T19:38:19.471Z
Learning: In FileFieldValue.getPath() method in the NAE codebase, the deprecated method returns an empty string instead of throwing an exception because it's still used in tests across multiple projects. Tests will be refactored in later snapshots, making the gradual deprecation approach necessary for backward compatibility.

Applied to files:

  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java
📚 Learning: 2025-08-19T20:07:43.748Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 339
File: nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java:16-16
Timestamp: 2025-08-19T20:07:43.748Z
Learning: In CaseField.java, the separate caseValue field (List<String>) is intentionally maintained alongside fulltextValue for specific Elasticsearch query requirements, rather than being derived on-the-fly from fulltextValue.

Applied to files:

  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java
📚 Learning: 2025-11-14T10:22:01.634Z
Learnt from: Retoocs
Repo: netgrif/application-engine PR: 383
File: application-engine/src/main/java/com/netgrif/application/engine/startup/ApplicationRunnerOrderResolver.java:43-43
Timestamp: 2025-11-14T10:22:01.634Z
Learning: For the netgrif/application-engine repository, avoid flagging trivial or nitpick-level issues such as redundant null checks, minor code style improvements, or obvious simplifications that don't affect functionality or introduce bugs. Focus review comments on substantive issues like logic errors, security concerns, performance problems, or breaking changes.

Applied to files:

  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java
📚 Learning: 2025-12-12T12:35:57.760Z
Learnt from: Retoocs
Repo: netgrif/application-engine PR: 397
File: application-engine/src/main/resources/petriNets/engine-processes/org_group.xml:36-39
Timestamp: 2025-12-12T12:35:57.760Z
Learning: In the org_group.xml file (application-engine/src/main/resources/petriNets/engine-processes/org_group.xml), variable names in action blocks like userField and user_selection should be kept as-is even when the field type changes from "user" to "actor".

Applied to files:

  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java
🧬 Code graph analysis (1)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java (2)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java (1)
  • Data (11-34)
nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/FileField.java (1)
  • NoArgsConstructor (16-52)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
🔇 Additional comments (3)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java (3)

22-24: LGTM! Null handling is correct.

The ternary null check before List.of() properly prevents NullPointerException. When fileFieldValue is null, the bulk constructor receives null and returns early, leaving lists uninitialized so getValue() correctly returns null.


26-43: LGTM! Constructor robustly handles null input and null elements.

The bulk constructor now properly initializes all three lists (fileNameValue, fileExtensionValue, filePath) and skips null elements in the input (lines 34-36), keeping all lists synchronized. This addresses the previous filePath NPE concern and hardens against malformed input.

The lists use default capacity rather than pre-sizing with fileFieldValues.size(). This is reasonable since null elements are filtered out, so the final size may be smaller than the input size.


66-71: LGTM! Extension handling is correct.

The helper properly handles null or empty extensions by returning the filename alone (lines 67-68), avoiding the "filename.null" issue flagged in previous reviews.


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.

@Retoocs Retoocs changed the title Nae 2285 [NAE-2285] Group as a value of userlists Dec 11, 2025
@Retoocs Retoocs added the improvement A change that improves on an existing feature label Dec 11, 2025
@Retoocs Retoocs marked this pull request as ready for review December 12, 2025 10:50
Copy link

@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: 50

Caution

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

⚠️ Outside diff range comments (22)
application-engine/src/main/java/com/netgrif/application/engine/importer/service/IModelValidator.java (1)

10-19: Parameterized logging change is correct; consider avoiding per-call logger creation.

Using log.warn("Data attribute [{}] is deprecated.", attrName); is the right SLF4J pattern and preserves behavior. If this method is called frequently, consider hoisting the logger (e.g., a static final Logger in implementors, or a default Logger logger() accessor) to avoid repeated LoggerFactory.getLogger(...) calls.

application-engine/src/main/resources/petriNets/engine-processes/org_group.xml (1)

57-76: Undefined variables in action block will cause runtime failures.

The user_selection field contains critical bugs in its action handlers:

  1. Line 71: group is undefined when used on the right-hand side of the assignment. The code attempts to call groupService.addUser() while referencing group.stringId, but group hasn't been defined yet. You likely need to fetch or initialize the group before this call.

  2. Line 73: The variable user is undefined. Based on context, this should be userField.value:

    options.put(userField.value.getStringId(), new com.netgrif.application.engine.objects.petrinet.domain.I18nString(userField.value.getUsername()))

Apply this diff to fix both issues:

  <action trigger="set">
    selection: f.members,
    userField: f.user_selection,
    id: f.group_id;

-   def group = groupService.addUser(userField.value.id, group.stringId, userField.value.realmId)
+   def group = groupService.findById(id.value)
+   groupService.addUser(userField.value.id, group.stringId, userField.value.realmId)
    def options = selection.options
-   options.put(user.getStringId(), new com.netgrif.application.engine.objects.petrinet.domain.I18nString(user.getUsername()))
+   options.put(userField.value.getStringId(), new com.netgrif.application.engine.objects.petrinet.domain.I18nString(userField.value.getUsername()))
    change selection options { options }
  </action>
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FieldWithAllowedNetsField.java (1)

10-15: Consider avoiding @Data here (or at least avoid generating a public setter for allowedNets).
Even though allowedNets is protected (Line 15), Lombok @Data will generate setters/getters, which re-opens uncontrolled mutation from outside the class hierarchy.

If you want allowedNets to be immutable after construction, prefer @Getter and omit @Setter (or use @Setter(AccessLevel.PROTECTED)), and/or make the field final if feasible.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/PetriNet.java (1)

162-196: Copy constructor shares actorRefs map reference (mutations will leak across copies)
this.actorRefs = petriNet.getActorRefs(); means the “copy” and the source share the same actorRefs (and inner maps). If either instance calls addActorPermission, it can mutate the other unintentionally.

-        this.actorRefs = petriNet.getActorRefs();
+        this.actorRefs = petriNet.getActorRefs() == null
+                ? new HashMap<>()
+                : petriNet.getActorRefs().entrySet().stream()
+                    .collect(Collectors.toMap(
+                        Map.Entry::getKey,
+                        e -> e.getValue() == null ? null : new HashMap<>(e.getValue()),
+                        (x, y) -> y,
+                        HashMap::new
+                    ));

Also applies to: 187-187

nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/Transition.java (2)

92-106: Constructor init is fine, but don’t rely on it for actorRefs non-nullness.
Some serializers/deserializers can bypass constructors; addActorRef() should still tolerate actorRefs == null.


253-273: Copy-constructor can NPE if any actorRefs value map is null (allowed by current addActorRef).
new HashMap<>(e.getValue()) throws if e.getValue() is null; guard or normalize null to empty.

- this.setActorRefs(transition.actorRefs == null ? null : transition.actorRefs.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new HashMap<>(e.getValue()))));
+ this.setActorRefs(transition.actorRefs == null ? null :
+         transition.actorRefs.entrySet().stream().collect(Collectors.toMap(
+                 Map.Entry::getKey,
+                 e -> e.getValue() == null ? new HashMap<>() : new HashMap<>(e.getValue())
+         )));
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticCase.java (2)

82-108: Constructor: null-safety on new HashSet<>(...) + verify id source matches current ES/Mongo ID strategy

  • If useCase.getViewActorRefs()/getViewActors()/getNegativeViewActors() can return null, Lines 100/102/103 will throw NPE—prefer Optional.ofNullable(...).orElseGet(Collections::emptySet).
  • Line 83 still uses useCase.getStringId(). Based on prior ES migration learnings (stringId removed / id holds Mongo object id), please confirm this is still correct for this module and index, otherwise ES joins/searches can silently break. Based on learnings, stringId consolidation happened earlier.

110-127: update() assigns view sets by reference (possible aliasing); consider defensive copies for ES documents
Lines 119/121/122 assign sets directly; if the source ElasticCase instance is reused/mutated, this can leak state across indexed documents. Prefer new HashSet<>(...) (and same for roles/tags if they’re mutable).

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticTask.java (2)

109-125: update() doesn’t propagate actorRefs/actors and assigns sets by reference
If assignees/permissions can change, actorRefs/actors should likely be updated too (not only view* sets). Also, Lines 119–124 assign collections directly—consider defensive copies to avoid shared mutable state in the indexed representation.


80-107: Constructor uses inconsistent identifiers: both id and taskId incorrectly set from task.getStringId()

Lines 81–84 set id and taskId to the same value via task.getStringId(). Per prior refactoring, stringId should no longer exist and id should contain the MongoDB object ID directly. Additionally, taskId should be task.getTaskId() to maintain the semantic distinction between document identifier and business task identifier used throughout queue and index lifecycles. This mismatch will cause tracking and lifecycle bugs downstream. Also add null-safety checks on lines 99, 101, 102 (new HashSet<>(...)).

application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/FieldTest.groovy (1)

182-187: Rename helper methods to reflect Actor terminology (avoids confusion in future edits).
assertUserField() / assertUserList() now validate ActorField / ActorListField, but the method names still encode the old type. Consider renaming to assertActorField() / assertActorList() (and update call sites in testImport).

Also applies to: 205-210

application-engine/src/test/resources/pdf_test_3.xml (1)

157-163: Test fixture IDs look accidentally generated ([object Object]_0)—consider normalizing.
Even though the change to type="actor" is consistent, the IDs in this area appear UI-serialized and reduce test readability/maintainability. If feasible, replace them with stable IDs (and update matching <dataRef> entries).

application-engine/src/test/resources/pdf_test_1.xml (1)

109-117: Update inline comment to match new type (actor).
The block is now type="actor" but still labeled <!-- USER -->, which is confusing when scanning fixtures. Consider renaming the comment to <!-- ACTOR --> (keeping <id>user</id> is fine if you need compatibility).

docs/search/elastic_mapping.md (1)

1-167: Fix markdownlint MD047: add a trailing newline at EOF.

application-engine/src/test/groovy/com/netgrif/application/engine/auth/WorkflowAuthorizationServiceTest.groovy (1)

225-255: Misleading dataset field ids (pos_user_list / neg_user_list) now carry actorList.
If the XML dataset ids are intentionally kept for backwards compatibility, fine; otherwise consider renaming in the PetriNet resources too (and adapting tests) to avoid future confusion when debugging permissions.

Also applies to: 257-282

application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskAuthorizationService.java (1)

53-70: Guard and source-of-truth mismatch: actorRefs vs actors can yield incorrect null permissions.
You short-circuit on task.getActorRefs() but then read from task.getActors(). If these diverge, authorization becomes inconsistent. Also task.getActors() could be null → potential NPE depending on findUserPermissions(Map, user) implementation upstream.

@@
     public Boolean userHasUserListPermission(AbstractUser user, Task task, RolePermission... permissions) {
-        if (task.getActorRefs() == null || task.getActorRefs().isEmpty()) {
+        if (task.getActors() == null || task.getActors().isEmpty()) {
             return null;
         }
 
         Map<String, Boolean> userPermissions = findUserPermissions(task, user);
         if (userPermissions == null) {
             return null;
         }
@@
     private Map<String, Boolean> findUserPermissions(Task task, AbstractUser user) {
-        return findUserPermissions(task.getActors(), user);
+        if (task.getActors() == null || task.getActors().isEmpty()) {
+            return null;
+        }
+        return findUserPermissions(task.getActors(), user);
     }

Also applies to: 165-168

application-engine/src/main/resources/petriNets/engine-processes/impersonation_config.xml (2)

80-101: impersonated switched to actor but runtime logic still assumes a user (username + userService lookup).
If a group can be selected, impersonated.value.username may be null and userService.findById(...) may fail or return wrong semantics. Either constrain the field to user-only selection or add explicit guarding/error handling for non-user actors.

Also applies to: 150-216


12-19: Update validation naming/messaging for actor semantics (and decide policy for group owners).
validateUser now effectively validates actor ownership; if config_owner can contain groups, decide whether group members/admins can manipulate configs and reflect that in logic + error message.

Also applies to: 145-146

application-engine/src/test/resources/data_test.xml (1)

104-110: Update fixture comments/titles to actor terminology (currently still “USER” / “Empty user list”). Not functional, but reduces migration confusion and keeps resources aligned with actor-centric docs.

Also applies to: 138-143

docs/roles/permissions.md (1)

292-351: Address markdownlint violations (language fences + tabs) and a grammar typo (“whose”).
Static analysis reports MD040 + MD010 in the newly added “Actor list / Actor reference” section; also “who’s ID” should be “whose ID”.

@@
-In NAE, actor list is a type of data field, that is used for managing access of a set of actors (who's ID is in the
+In NAE, actor list is a type of data field, that is used for managing access of a set of actors (whose ID is in the
@@
-```
+```xml
 <document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://petriflow.com/petriflow.schema.xsd">
-	...
-	<data type="actorList">
-		<id>actor_list_1</id>
-		<title>Actor list 1</title>
-	</data>
-	...
+    ...
+    <data type="actorList">
+        <id>actor_list_1</id>
+        <title>Actor list 1</title>
+    </data>
+    ...
 </document>

@@
-Permission documentation can be found here. Actor list can be referenced as follows:
+Permission documentation can be found here. Actor list can be referenced as follows:
@@
- +xml
@@
- +xml


</blockquote></details>
<details>
<summary>docs/_media/roles/actorRef_net.xml (1)</summary><blockquote>

`41-58`: **Rename remaining “user” titles to “actor” for consistency with `actorRef`/`actorList`.**  
E.g., “Assign to user ref” / “Remove from user ref” (Line 45-50) and “User list 1/2” (Line 53-58).

</blockquote></details>
<details>
<summary>application-engine/src/test/groovy/com/netgrif/application/engine/permissions/QueryDSLViewPermissionTest.groovy (1)</summary><blockquote>

`78-93`: **Close `FileInputStream`s in `init()` (resource leak).**  
`new FileInputStream(...)` (Line 81, 85) isn’t closed; switch to `withCloseable {}` or `Files.newInputStream(...)`.  


```diff
 @BeforeEach
 void init() {
     testHelper.truncateDbs()
-    ImportPetriNetEventOutcome net = petriNetService.importPetriNet(new FileInputStream("src/test/resources/view_permission_test.xml"), VersionType.MAJOR, superCreator.getLoggedSuper())
+    def net = new File("src/test/resources/view_permission_test.xml").newInputStream().withCloseable { is ->
+        petriNetService.importPetriNet(is, VersionType.MAJOR, superCreator.getLoggedSuper())
+    }
     assert net.getNet() != null
     this.net = net.getNet()
 
-    ImportPetriNetEventOutcome netWithUserRefs = petriNetService.importPetriNet(new FileInputStream("src/test/resources/view_permission_with_userRefs_test.xml"), VersionType.MAJOR, superCreator.getLoggedSuper())
+    def netWithUserRefs = new File("src/test/resources/view_permission_with_userRefs_test.xml").newInputStream().withCloseable { is ->
+        petriNetService.importPetriNet(is, VersionType.MAJOR, superCreator.getLoggedSuper())
+    }
     assert netWithUserRefs.getNet() != null
     this.netWithUserRefs = netWithUserRefs.getNet()
@@
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0ba6fe9 and d8f536e.

📒 Files selected for processing (107)
  • application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy (2 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/auth/web/UserController.java (2 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java (11 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticViewPermissionService.java (3 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/export/service/ExportService.java (1 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/impersonation/service/ImpersonationAuthorizationService.java (1 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/importer/service/DataValidator.java (2 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/importer/service/DocumentValidator.java (1 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/importer/service/FieldFactory.java (3 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/importer/service/IModelValidator.java (1 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/importer/service/Importer.java (11 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/importer/service/TransitionValidator.java (1 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/pdf/generator/service/fieldbuilder/TextFieldBuilder.java (2 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/AbstractAuthorizationService.java (2 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/CaseSearchService.java (5 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java (7 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MongoSearchService.java (3 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskAuthorizationService.java (3 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskSearchService.java (7 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java (6 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowAuthorizationService.java (3 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java (3 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/IDataService.java (1 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskService.java (1 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/IWorkflowService.java (1 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/web/responsebodies/Task.java (1 hunks)
  • application-engine/src/main/resources/petriNets/engine-processes/impersonation_config.xml (10 hunks)
  • application-engine/src/main/resources/petriNets/engine-processes/org_group.xml (2 hunks)
  • application-engine/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy (5 hunks)
  • application-engine/src/test/groovy/com/netgrif/application/engine/auth/WorkflowAuthorizationServiceTest.groovy (6 hunks)
  • application-engine/src/test/groovy/com/netgrif/application/engine/elastic/DataSearchRequestTest.groovy (6 hunks)
  • application-engine/src/test/groovy/com/netgrif/application/engine/filters/FilterImportExportTest.groovy (1 hunks)
  • application-engine/src/test/groovy/com/netgrif/application/engine/impersonation/ImpersonationServiceTest.groovy (2 hunks)
  • application-engine/src/test/groovy/com/netgrif/application/engine/importer/ActorListTest.groovy (2 hunks)
  • application-engine/src/test/groovy/com/netgrif/application/engine/permissions/ElasticSearchViewPermissionTest.groovy (7 hunks)
  • application-engine/src/test/groovy/com/netgrif/application/engine/permissions/QueryDSLViewPermissionTest.groovy (6 hunks)
  • application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/FieldTest.groovy (3 hunks)
  • application-engine/src/test/groovy/com/netgrif/application/engine/workflow/TaskControllerTest.groovy (1 hunks)
  • application-engine/src/test/groovy/com/netgrif/application/engine/workflow/UserRefsTest.groovy (2 hunks)
  • application-engine/src/test/resources/actor_list.xml (3 hunks)
  • application-engine/src/test/resources/all_data.xml (2 hunks)
  • application-engine/src/test/resources/all_data_pdf.xml (1 hunks)
  • application-engine/src/test/resources/data_test.xml (2 hunks)
  • application-engine/src/test/resources/initial_behavior.xml (1 hunks)
  • application-engine/src/test/resources/mapping_test.xml (1 hunks)
  • application-engine/src/test/resources/org_group.xml (2 hunks)
  • application-engine/src/test/resources/pdf_run_action.xml (1 hunks)
  • application-engine/src/test/resources/pdf_test_1.xml (1 hunks)
  • application-engine/src/test/resources/pdf_test_3.xml (1 hunks)
  • application-engine/src/test/resources/petriNets/FM_v0_2.xml (5 hunks)
  • application-engine/src/test/resources/petriNets/all_data.xml (1 hunks)
  • application-engine/src/test/resources/petriNets/all_data_refs.xml (1 hunks)
  • application-engine/src/test/resources/petriNets/dynamic_init.xml (1 hunks)
  • application-engine/src/test/resources/petriNets/impersonation_test.xml (2 hunks)
  • application-engine/src/test/resources/petriNets/test_model_immediate_data.xml (1 hunks)
  • application-engine/src/test/resources/poistenie.xml (1 hunks)
  • application-engine/src/test/resources/poistenie_rozsirene.xml (1 hunks)
  • application-engine/src/test/resources/poistenie_transaction.xml (1 hunks)
  • application-engine/src/test/resources/poistenie_triggers.xml (1 hunks)
  • application-engine/src/test/resources/predefinedPermissions/role_permissions_anonymous_role_shadowed_userref.xml (2 hunks)
  • application-engine/src/test/resources/predefinedPermissions/role_permissions_anonymous_role_shadowed_usersref.xml (2 hunks)
  • application-engine/src/test/resources/predefinedPermissions/role_permissions_default_role_shadowed_userref.xml (2 hunks)
  • application-engine/src/test/resources/predefinedPermissions/role_permissions_default_role_shadowed_usersref.xml (2 hunks)
  • application-engine/src/test/resources/prikladFM.xml (5 hunks)
  • application-engine/src/test/resources/prikladFM_import.xml (1 hunks)
  • application-engine/src/test/resources/prikladFM_test.xml (1 hunks)
  • application-engine/src/test/resources/role_all_data.xml (1 hunks)
  • application-engine/src/test/resources/set_data_test.xml (1 hunks)
  • application-engine/src/test/resources/task_authorization_service_test_with_userRefs.xml (2 hunks)
  • application-engine/src/test/resources/userrefs_test.xml (3 hunks)
  • application-engine/src/test/resources/view_permission_with_userRefs_test.xml (3 hunks)
  • application-engine/src/test/resources/workflow_authorization_service_test_with_userRefs.xml (2 hunks)
  • application-engine/src/test/resources/zaverecna_praca.xml (2 hunks)
  • docs/_media/roles/actorRef_net.xml (6 hunks)
  • docs/_sidebar.md (1 hunks)
  • docs/roles/actorlist.md (1 hunks)
  • docs/roles/permissions.md (8 hunks)
  • docs/roles/userlist.md (0 hunks)
  • docs/search/elastic_mapping.md (2 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorListField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorMappingData.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/BooleanField.java (2 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java (2 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DateField.java (2 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticCase.java (3 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticTask.java (3 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FieldWithAllowedNetsField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java (2 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FilterField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/MapField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/NumberField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/StringCollectionField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/TextField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserField.java (0 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserListField.java (0 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/PetriNet.java (4 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/Transition.java (4 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorFieldValue.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorListField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorListFieldValue.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/FieldType.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/GroupFieldValue.java (1 hunks)
⛔ Files not processed due to max files limit (27)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserField.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserFieldValue.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserListFieldValue.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/localised/LocalisedFieldFactory.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/localised/LocalisedUserField.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/localised/LocalisedUserListField.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Task.java
  • nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/ActorField.java
  • nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/ActorListField.java
  • nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/BooleanField.java
  • nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/ButtonField.java
  • nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/CaseField.java
  • nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/DateField.java
  • nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/ElasticCase.java
  • nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/ElasticTask.java
  • nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/FileField.java
  • nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/FilterField.java
  • nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/I18nField.java
  • nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/MapField.java
  • nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/NumberField.java
  • nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/StringCollectionField.java
  • nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/TextField.java
  • nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/UserField.java
  • nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/UserListField.java
  • nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/workflow/domain/Case.java
  • nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/workflow/domain/Task.java
💤 Files with no reviewable changes (3)
  • docs/roles/userlist.md
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserField.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserListField.java
🧰 Additional context used
🧠 Learnings (14)
📚 Learning: 2025-08-19T20:07:43.748Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 339
File: nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java:16-16
Timestamp: 2025-08-19T20:07:43.748Z
Learning: In CaseField.java, the separate caseValue field (List<String>) is intentionally maintained alongside fulltextValue for specific Elasticsearch query requirements, rather than being derived on-the-fly from fulltextValue.

Applied to files:

  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/StringCollectionField.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/TextField.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/MapField.java
  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java
📚 Learning: 2025-06-23T13:30:13.096Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 318
File: nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/menu/MenuItemConstants.java:60-62
Timestamp: 2025-06-23T13:30:13.096Z
Learning: In MenuItemConstants enum in nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/menu/MenuItemConstants.java, the field `attributeId` will be renamed to `value` to make it more generic and appropriate for both dataset attribute identifiers and technical constants like PATH_SEPARATOR.

Applied to files:

  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/IDataService.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/FieldType.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java
📚 Learning: 2025-08-22T12:49:43.219Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 343
File: nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/FieldType.java:39-47
Timestamp: 2025-08-22T12:49:43.219Z
Learning: In FieldType enum, both fromString() and fromName() methods should coexist as they serve different purposes. The fromName() method is specifically needed for other libraries, while fromString() serves existing use cases.

Applied to files:

  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/FieldType.java
📚 Learning: 2025-08-20T07:27:02.660Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 339
File: application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticTaskQueueManager.java:38-45
Timestamp: 2025-08-20T07:27:02.660Z
Learning: When reviewing ElasticTaskQueueManager changes, task.getTask().getId() returns the document identifier while task.getTaskId() returns the business task identifier. The queue operations should use consistent identifiers throughout the lifecycle (scheduling, processing, cleanup).

Applied to files:

  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskService.java
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskSearchService.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticTask.java
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java
📚 Learning: 2025-09-05T10:21:54.893Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 350
File: application-engine/src/test/groovy/com/netgrif/application/engine/export/service/ExportServiceTest.groovy:135-135
Timestamp: 2025-09-05T10:21:54.893Z
Learning: In ExportServiceTest.groovy, writing to src/test/resources is intentional to simulate production behavior where the working tree is mutated during file exports. This mirrors how the system works in production.

Applied to files:

  • application-engine/src/test/groovy/com/netgrif/application/engine/filters/FilterImportExportTest.groovy
  • application-engine/src/test/groovy/com/netgrif/application/engine/auth/WorkflowAuthorizationServiceTest.groovy
  • application-engine/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy
📚 Learning: 2025-09-29T10:31:31.469Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 362
File: application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/ProcessRoleController.java:43-45
Timestamp: 2025-09-29T10:31:31.469Z
Learning: In the Netgrif application engine, when Authentication objects reach controller endpoints, auth.getPrincipal() always returns a LoggedUser instance and is never null, so defensive casting checks are not necessary in controller methods.

Applied to files:

  • application-engine/src/main/java/com/netgrif/application/engine/auth/web/UserController.java
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MongoSearchService.java
  • application-engine/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy
📚 Learning: 2025-07-31T08:05:21.587Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 329
File: nae-user-ce/src/main/java/com/netgrif/application/engine/auth/service/RealmServiceImpl.java:39-39
Timestamp: 2025-07-31T08:05:21.587Z
Learning: In the Netgrif Application Engine, the domain Realm class (com.netgrif.application.engine.objects.auth.domain.Realm) is abstract and cannot be instantiated. The concrete implementation is in the adapter package (com.netgrif.application.engine.adapter.spring.auth.domain.Realm) which extends the abstract domain class. Services must instantiate the concrete adapter class and cast it when saving to repositories that accept the abstract domain type.

Applied to files:

  • application-engine/src/test/groovy/com/netgrif/application/engine/permissions/QueryDSLViewPermissionTest.groovy
  • application-engine/src/test/groovy/com/netgrif/application/engine/auth/WorkflowAuthorizationServiceTest.groovy
  • application-engine/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy
📚 Learning: 2025-09-05T10:17:28.577Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 350
File: application-engine/src/test/groovy/com/netgrif/application/engine/export/service/ExportServiceTest.groovy:82-82
Timestamp: 2025-09-05T10:17:28.577Z
Learning: In the application-engine test suite, testHelper.truncateDbs() follows a two-phase approach: first it clears the databases, then it executes superCreator to create the admin user. This means Optional.get() is safe when retrieving the admin user after truncateDbs() because the admin user is guaranteed to exist.

Applied to files:

  • application-engine/src/test/groovy/com/netgrif/application/engine/permissions/QueryDSLViewPermissionTest.groovy
📚 Learning: 2025-08-19T20:13:40.087Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 339
File: nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java:16-16
Timestamp: 2025-08-19T20:13:40.087Z
Learning: In CaseField.java, fulltextValue is mapped as a keyword field type in Elasticsearch (for exact matches, filtering, aggregations), while the separate caseValue field serves different Elasticsearch query requirements, allowing the system to support multiple query patterns on the same data through different field mappings.

Applied to files:

  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/MapField.java
  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java
📚 Learning: 2025-07-31T23:40:46.499Z
Learnt from: tuplle
Repo: netgrif/application-engine PR: 334
File: application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java:204-214
Timestamp: 2025-07-31T23:40:46.499Z
Learning: In the PetriNetService.importPetriNet method, existingNet.getVersion() cannot be null because all existing nets in the system were deployed through processes that ensure every net always has a version assigned.

Applied to files:

  • application-engine/src/main/java/com/netgrif/application/engine/importer/service/Importer.java
  • application-engine/src/test/groovy/com/netgrif/application/engine/importer/ActorListTest.groovy
📚 Learning: 2025-09-29T10:31:57.325Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 362
File: application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java:513-529
Timestamp: 2025-09-29T10:31:57.325Z
Learning: PetriNet.getStringId() returns a simple ObjectId string representation (_id.toString()), not a composite Netgrif ID format, so new ObjectId(petriNetId) works correctly when petriNetId comes from PetriNet.getStringId().

Applied to files:

  • application-engine/src/main/java/com/netgrif/application/engine/importer/service/Importer.java
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/CaseSearchService.java
📚 Learning: 2025-08-19T19:38:19.471Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 338
File: nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/FileFieldValue.java:40-51
Timestamp: 2025-08-19T19:38:19.471Z
Learning: In FileFieldValue.getPath() method in the NAE codebase, the deprecated method returns an empty string instead of throwing an exception because it's still used in tests across multiple projects. Tests will be refactored in later snapshots, making the gradual deprecation approach necessary for backward compatibility.

Applied to files:

  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java
📚 Learning: 2025-10-20T11:44:44.907Z
Learnt from: machacjozef
Repo: netgrif/application-engine PR: 367
File: application-engine/src/main/resources/application.yaml:24-24
Timestamp: 2025-10-20T11:44:44.907Z
Learning: In the netgrif/application-engine project, the correction of the Elasticsearch task index name from "_taks" to "_task" in application.yaml was approved by maintainer machacjozef, indicating that any data migration concerns for this typo fix are handled separately or not applicable to their deployment scenario.

Applied to files:

  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskSearchService.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticTask.java
📚 Learning: 2025-08-19T20:07:15.621Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 339
File: application-engine/src/test/groovy/com/netgrif/application/engine/filters/FilterImportExportTest.groovy:341-341
Timestamp: 2025-08-19T20:07:15.621Z
Learning: In the Elasticsearch migration, the stringId property was removed from ElasticCase and ElasticTask, with the id property now containing the MongoDB case/task object ID directly. This consolidation eliminates redundancy and simplifies the data model.

Applied to files:

  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticCase.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticTask.java
  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java
🧬 Code graph analysis (14)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorFieldValue.java (2)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/GroupFieldValue.java (1)
  • Getter (8-45)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserFieldValue.java (1)
  • Getter (10-54)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/StringCollectionField.java (5)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java (1)
  • Data (11-34)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/TextField.java (1)
  • Data (9-24)
nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/StringCollectionField.java (1)
  • Data (14-40)
nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/BooleanField.java (1)
  • NoArgsConstructor (11-32)
nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/NumberField.java (1)
  • NoArgsConstructor (11-29)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/GroupFieldValue.java (2)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorFieldValue.java (1)
  • Getter (10-26)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserFieldValue.java (1)
  • Getter (10-54)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorField.java (2)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorListField.java (1)
  • Data (9-17)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java (1)
  • Data (11-34)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/TextField.java (3)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java (1)
  • Data (11-34)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java (1)
  • Data (10-31)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/MapField.java (1)
  • Data (10-46)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java (4)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorField.java (1)
  • Data (15-77)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java (1)
  • Data (13-70)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/StringCollectionField.java (1)
  • Data (10-21)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/TextField.java (1)
  • Data (9-24)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorListField.java (2)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorFieldValue.java (1)
  • Getter (10-26)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorField.java (1)
  • Setter (10-41)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorListField.java (4)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorField.java (1)
  • Data (15-77)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java (1)
  • Data (11-34)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/localised/LocalisedUserField.java (1)
  • Data (10-20)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/localised/LocalisedUserListField.java (1)
  • Data (10-20)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FilterField.java (2)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FieldWithAllowedNetsField.java (1)
  • Data (10-26)
nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/FilterField.java (1)
  • NoArgsConstructor (12-39)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java (2)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java (1)
  • Data (11-34)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/TextField.java (1)
  • Data (9-24)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java (4)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java (1)
  • Data (11-27)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java (1)
  • Data (11-34)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/MapField.java (1)
  • Data (10-46)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/TextField.java (1)
  • Data (9-24)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/MapField.java (1)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nStringUtils.java (1)
  • I18nStringUtils (8-18)
application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java (1)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nStringUtils.java (1)
  • I18nStringUtils (8-18)
application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java (2)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/auth/domain/ActorTransformer.java (1)
  • ActorTransformer (10-131)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorListFieldValue.java (1)
  • ActorListFieldValue (9-39)
🪛 GitHub Actions: Pull Request
application-engine/src/main/java/com/netgrif/application/engine/importer/service/Importer.java

[error] 254-254: cannot find symbol: class CaseActorRef


[error] 747-747: cannot find symbol: class ActorRef

🪛 LanguageTool
docs/roles/permissions.md

[style] ~371-~371: Consider a more concise word here.
Context: ...d a permission from at least one source in order to be allowed to perform an operation. A g...

(IN_ORDER_TO_PREMIUM)

docs/roles/actorlist.md

[style] ~88-~88: You have already used this phrasing in nearby sentences. Consider replacing it to add variety to your writing.
Context: ...ission only for a set of actors, and we want to change the content of this set runtime,...

(REP_WANT_TO_VB)

🪛 markdownlint-cli2 (0.18.1)
docs/roles/permissions.md

298-298: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


300-300: Hard tabs
Column: 1

(MD010, no-hard-tabs)


301-301: Hard tabs
Column: 1

(MD010, no-hard-tabs)


302-302: Hard tabs
Column: 1

(MD010, no-hard-tabs)


303-303: Hard tabs
Column: 1

(MD010, no-hard-tabs)


304-304: Hard tabs
Column: 1

(MD010, no-hard-tabs)


305-305: Hard tabs
Column: 1

(MD010, no-hard-tabs)


314-314: Link fragments should be valid
Expected: #permissions; Actual: #Permissions

(MD051, link-fragments)


314-314: Link text should be descriptive

(MD059, descriptive-link-text)


318-318: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


320-320: Hard tabs
Column: 1

(MD010, no-hard-tabs)


321-321: Hard tabs
Column: 1

(MD010, no-hard-tabs)


322-322: Hard tabs
Column: 1

(MD010, no-hard-tabs)


323-323: Hard tabs
Column: 1

(MD010, no-hard-tabs)


324-324: Hard tabs
Column: 1

(MD010, no-hard-tabs)


325-325: Hard tabs
Column: 1

(MD010, no-hard-tabs)


326-326: Hard tabs
Column: 1

(MD010, no-hard-tabs)


327-327: Hard tabs
Column: 1

(MD010, no-hard-tabs)


328-328: Hard tabs
Column: 1

(MD010, no-hard-tabs)


334-334: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


336-336: Hard tabs
Column: 1

(MD010, no-hard-tabs)


337-337: Hard tabs
Column: 1

(MD010, no-hard-tabs)


338-338: Hard tabs
Column: 1

(MD010, no-hard-tabs)


339-339: Hard tabs
Column: 1

(MD010, no-hard-tabs)


340-340: Hard tabs
Column: 1

(MD010, no-hard-tabs)


341-341: Hard tabs
Column: 1

(MD010, no-hard-tabs)


342-342: Hard tabs
Column: 1

(MD010, no-hard-tabs)


343-343: Hard tabs
Column: 1

(MD010, no-hard-tabs)


344-344: Hard tabs
Column: 1

(MD010, no-hard-tabs)


345-345: Hard tabs
Column: 1

(MD010, no-hard-tabs)


370-370: Trailing spaces
Expected: 0 or 2; Actual: 1

(MD009, no-trailing-spaces)


395-395: Hard tabs
Column: 1

(MD010, no-hard-tabs)


396-396: Hard tabs
Column: 1

(MD010, no-hard-tabs)


397-397: Hard tabs
Column: 1

(MD010, no-hard-tabs)


398-398: Hard tabs
Column: 1

(MD010, no-hard-tabs)


399-399: Hard tabs
Column: 1

(MD010, no-hard-tabs)


400-400: Hard tabs
Column: 1

(MD010, no-hard-tabs)


401-401: Hard tabs
Column: 1

(MD010, no-hard-tabs)


402-402: Hard tabs
Column: 1

(MD010, no-hard-tabs)


445-445: Hard tabs
Column: 1

(MD010, no-hard-tabs)


446-446: Hard tabs
Column: 1

(MD010, no-hard-tabs)


447-447: Hard tabs
Column: 1

(MD010, no-hard-tabs)


448-448: Hard tabs
Column: 1

(MD010, no-hard-tabs)


449-449: Hard tabs
Column: 1

(MD010, no-hard-tabs)


450-450: Hard tabs
Column: 1

(MD010, no-hard-tabs)


451-451: Hard tabs
Column: 1

(MD010, no-hard-tabs)

docs/_sidebar.md

13-13: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)

docs/roles/actorlist.md

21-21: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

docs/search/elastic_mapping.md

167-167: Files should end with a single newline character

(MD047, single-trailing-newline)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed

Copy link

@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: 11

Caution

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

⚠️ Outside diff range comments (1)
application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java (1)

36-83: Avoid NPE when netField is null (migration/partial dataset scenarios).
If useCase.getField(fieldId) (Line 37) is ever null, the fallback path calls transformOtherFields(caseField, netField) and transformOtherFields dereferences netField.getClass() (Line 298).

 protected Optional<DataField> transformDataField(String fieldId, Case useCase) {
     Field<?> netField = useCase.getField(fieldId);
     com.netgrif.application.engine.objects.workflow.domain.DataField caseField = useCase.getDataField(fieldId);

     if (caseField.getValue() == null) {
         return Optional.empty();
+    } else if (netField == null) {
+        log.warn("No net field found for id {}. Skipping indexation...", fieldId);
+        return Optional.empty();
     } else if (netField instanceof EnumerationMapField) {
         return this.transformEnumerationMapField(caseField, (EnumerationMapField) netField);
     }
     ...
 }

Also applies to: 296-300

♻️ Duplicate comments (14)
application-engine/src/main/java/com/netgrif/application/engine/importer/service/DataValidator.java (1)

4-5: Enum == checks for deprecated DataType.USER/USER_LIST look correct and null-safe.
This also addresses the prior feedback to avoid null + .equals() boilerplate.

Also applies to: 18-19

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/TextField.java (1)

20-23: TextField(List<String>) still aliases the input list and allows textValue == null.
This is the same concern previously raised: this.textValue = values means external mutations can affect the field instance, and values == null leaves textValue null (different from DataField.fulltextValue which is always non-null). If this is intentional, consider documenting it (or annotating textValue/values as nullable) to prevent accidental misuse.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/Transition.java (1)

137-146: Good addition of actorFieldId null check; past review concerns on defensive copying remain.

The terminology update and the new null check for actorFieldId (lines 138-140) are solid improvements. However, the past review comment about null-safety for actorRefs/permissions and defensive copying of the permission map still applies and should be addressed to prevent potential NPEs and unintended mutation of internal state.

docs/roles/permissions.md (2)

371-371: Simplify awkward phrasing for conciseness.

Line 371 uses "in order to be allowed" which is more verbose than necessary. Replace with the more concise "to be allowed" per static analysis feedback.

- An actor must be granted a permission from at least one source in order to be allowed to perform an operation.
+ An actor must be granted a permission from at least one source to be allowed to perform an operation.

97-102: Rename example IDs from other to clarify they are actor list IDs, not individual actor IDs.

The examples still use <id>other</id> which readers may misinterpret as an actor (user/group) ID rather than an actor list field ID. Rename these to something like actor_list_1 to prevent confusion and align with the actual use case.

  <actorRef>
-     <id>other</id>
+     <id>actor_list_1</id>
      <caseLogic>
          <view>false</view>
      </caseLogic>
  </actorRef>

Apply similar changes to all three actorRef examples in the "Predefined role will be added" section (lines 95–116 area) and "Predefined role will not be added" section (lines 193–215 area).

Also applies to: 195-200, 207-214

docs/roles/actorlist.md (2)

108-109: Swap media link labels and targets to match correctly.

The link labels and targets are swapped: "ActorRef Petri Net" should point to the XML file (actorRef_net.xml), and "ActorRef Functions" should point to the Groovy file (actorRef_functions.groovy).

- [ActorRef Petri Net](../_media/roles/actorRef_functions.groovy)
+ [ActorRef Petri Net](../_media/roles/actorRef_net.xml)
 
- [ActorRef Functions](../_media/roles/actorRef_net.xml)
+ [ActorRef Functions](../_media/roles/actorRef_functions.groovy)

94-94: Fix grammar: "mean" → "means".

Line 94 contains a subject-verb agreement error. Change "false mean disable" to "false means disable".

- 3. Into *logic* property of actorRef we define the permissions with boolean values - true means enable, false mean
+ 3. Into *logic* property of actorRef we define the permissions with boolean values - true means enable, false means
nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/PetriNet.java (1)

233-233: Still missing defensive copy when storing new permission map.

The null/empty guard added at lines 227-229 addresses part of the previous review concern, but line 233 still stores the caller's permissions map directly. This allows external mutation after the call, which can lead to unexpected behavior.

Apply this diff to fix the defensive copy issue:

-            this.actorRefs.put(actorFieldId, permissions);
+            this.actorRefs.put(actorFieldId, new HashMap<>(permissions));
application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticViewPermissionService.java (1)

93-99: Helper name still says “User” but it builds actor IDs.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorField.java (1)

30-50: Critical: usernameValue size mismatch will throw IndexOutOfBounds for groups.

buildFieldValue(int idx) indexes usernameValue for every idx, but the constructor only appends usernames for non-null usernames. Add null placeholders to keep all lists aligned.

 for (ActorMappingData mappingData : mappingDataList) {
     this.fullNameValue.add(mappingData.fullName());
     this.actorIdValue.add(mappingData.actorId());
     this.actorRealmIdValue.add(mappingData.actorRealmId());
     if (mappingData.username() == null) {
+        this.usernameValue.add(null);
         this.fulltextValue.add(mappingData.fullName());
     } else {
         this.usernameValue.add(mappingData.username());
-        super.fulltextValue.add(String.format("%s %s", mappingData.fullName(), mappingData.username()));
+        this.fulltextValue.add(String.format("%s %s", mappingData.fullName(), mappingData.username()));
     }
 }

Also applies to: 63-74

application-engine/src/main/java/com/netgrif/application/engine/pdf/generator/service/fieldbuilder/TextFieldBuilder.java (1)

59-66: Consider null-safety in ACTORLIST join (actorValues / getFullName may be null).

application-engine/src/main/java/com/netgrif/application/engine/export/service/ExportService.java (1)

276-284: CSV export inconsistency: ACTOR exports display values, ACTORLIST exports IDs. Pick one stable contract.

If consumers expect stable identifiers, prefer exporting ActorFieldValue.getId() for ACTOR too (and keep display name in a separate column if needed).

 case ACTOR:
-    if (fieldData instanceof UserFieldValue) {
-        fieldValue = ((UserFieldValue) fieldData).getUsername();
-    } else if (fieldData instanceof GroupFieldValue) {
-        fieldValue = ((GroupFieldValue) fieldData).getName();
-    } else {
-        fieldValue = "";
-    }
+    fieldValue = (fieldData instanceof ActorFieldValue afv) ? afv.getId() : "";
     break;
Netgrif Application Engine CSV export: for actor fields, should exports contain stable identifiers (id) or display values (username/group name)?
nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorFieldValue.java (1)

12-30: Add @Override on hashCode() for correctness signaling / static analysis.

-    public int hashCode() {
+    @Override
+    public int hashCode() {
         return Objects.hashCode(this.id);
     }
nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorListField.java (1)

20-27: Defensively copy roles in the Set constructor to avoid external mutation.
Right now this.roles = roles == null ? new HashSet<>() : roles; (Line 26) aliases the caller’s mutable set.

 public ActorListField(Set<String> roles) {
     super();
-    this.roles = roles == null ? new HashSet<>() : roles;
+    this.roles = roles == null ? new HashSet<>() : new HashSet<>(roles);
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d8f536e and 5fccd48.

📒 Files selected for processing (19)
  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java (11 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticViewPermissionService.java (3 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/export/service/ExportService.java (1 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/importer/service/DataValidator.java (2 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/pdf/generator/service/fieldbuilder/TextFieldBuilder.java (2 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/AbstractAuthorizationService.java (2 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MongoSearchService.java (3 hunks)
  • docs/roles/actorlist.md (1 hunks)
  • docs/roles/permissions.md (10 hunks)
  • docs/search/elastic_mapping.md (2 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java (2 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/TextField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/PetriNet.java (4 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/Transition.java (4 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorFieldValue.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorListField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserFieldValue.java (3 hunks)
🧰 Additional context used
🧠 Learnings (11)
📓 Common learnings
Learnt from: Retoocs
Repo: netgrif/application-engine PR: 397
File: application-engine/src/main/resources/petriNets/engine-processes/org_group.xml:36-39
Timestamp: 2025-12-12T12:35:57.760Z
Learning: In the org_group.xml file (application-engine/src/main/resources/petriNets/engine-processes/org_group.xml), variable names in action blocks like userField and user_selection should be kept as-is even when the field type changes from "user" to "actor".
Learnt from: Retoocs
Repo: netgrif/application-engine PR: 397
File: application-engine/src/test/groovy/com/netgrif/application/engine/impersonation/ImpersonationServiceTest.groovy:18-20
Timestamp: 2025-12-12T12:40:25.863Z
Learning: In the actor refactoring, UserFieldValue is a subclass of ActorFieldValue, and ActorListFieldValue accepts ActorFieldValue instances. Therefore, passing UserFieldValue instances to ActorListFieldValue is valid through polymorphism.
📚 Learning: 2025-12-12T12:40:25.863Z
Learnt from: Retoocs
Repo: netgrif/application-engine PR: 397
File: application-engine/src/test/groovy/com/netgrif/application/engine/impersonation/ImpersonationServiceTest.groovy:18-20
Timestamp: 2025-12-12T12:40:25.863Z
Learning: In the actor refactoring, UserFieldValue is a subclass of ActorFieldValue, and ActorListFieldValue accepts ActorFieldValue instances. Therefore, passing UserFieldValue instances to ActorListFieldValue is valid through polymorphism.

Applied to files:

  • docs/search/elastic_mapping.md
  • application-engine/src/main/java/com/netgrif/application/engine/pdf/generator/service/fieldbuilder/TextFieldBuilder.java
  • application-engine/src/main/java/com/netgrif/application/engine/export/service/ExportService.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorField.java
  • docs/roles/actorlist.md
  • docs/roles/permissions.md
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorListField.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserFieldValue.java
  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorFieldValue.java
📚 Learning: 2025-12-12T12:35:57.760Z
Learnt from: Retoocs
Repo: netgrif/application-engine PR: 397
File: application-engine/src/main/resources/petriNets/engine-processes/org_group.xml:36-39
Timestamp: 2025-12-12T12:35:57.760Z
Learning: In the org_group.xml file (application-engine/src/main/resources/petriNets/engine-processes/org_group.xml), variable names in action blocks like userField and user_selection should be kept as-is even when the field type changes from "user" to "actor".

Applied to files:

  • docs/search/elastic_mapping.md
  • application-engine/src/main/java/com/netgrif/application/engine/pdf/generator/service/fieldbuilder/TextFieldBuilder.java
  • application-engine/src/main/java/com/netgrif/application/engine/export/service/ExportService.java
  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticViewPermissionService.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorField.java
  • docs/roles/actorlist.md
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/PetriNet.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/TextField.java
  • docs/roles/permissions.md
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorListField.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/Transition.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserFieldValue.java
  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java
📚 Learning: 2025-12-12T13:39:52.238Z
Learnt from: Retoocs
Repo: netgrif/application-engine PR: 397
File: application-engine/src/main/java/com/netgrif/application/engine/workflow/service/CaseSearchService.java:98-104
Timestamp: 2025-12-12T13:39:52.238Z
Learning: In application-engine/src/main/java/com/netgrif/application/engine/workflow/service/CaseSearchService.java, the permission constraint logic in buildQuery() intentionally applies negative actor constraints globally: ((roleConstraint AND NOT negRoleConstraint) OR actorConstraint) AND NOT negActorConstraint. This means users in negativeViewActors are excluded even if they have positive role permissions, which is the intended authorization behavior.

Applied to files:

  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MongoSearchService.java
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/AbstractAuthorizationService.java
  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticViewPermissionService.java
  • docs/roles/permissions.md
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/Transition.java
📚 Learning: 2025-09-29T10:31:31.469Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 362
File: application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/ProcessRoleController.java:43-45
Timestamp: 2025-09-29T10:31:31.469Z
Learning: In the Netgrif application engine, when Authentication objects reach controller endpoints, auth.getPrincipal() always returns a LoggedUser instance and is never null, so defensive casting checks are not necessary in controller methods.

Applied to files:

  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MongoSearchService.java
📚 Learning: 2025-10-20T11:44:44.907Z
Learnt from: machacjozef
Repo: netgrif/application-engine PR: 367
File: application-engine/src/main/resources/application.yaml:24-24
Timestamp: 2025-10-20T11:44:44.907Z
Learning: In the netgrif/application-engine project, the correction of the Elasticsearch task index name from "_taks" to "_task" in application.yaml was approved by maintainer machacjozef, indicating that any data migration concerns for this typo fix are handled separately or not applicable to their deployment scenario.

Applied to files:

  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/PetriNet.java
  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java
📚 Learning: 2025-08-19T19:38:19.471Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 338
File: nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/FileFieldValue.java:40-51
Timestamp: 2025-08-19T19:38:19.471Z
Learning: In FileFieldValue.getPath() method in the NAE codebase, the deprecated method returns an empty string instead of throwing an exception because it's still used in tests across multiple projects. Tests will be refactored in later snapshots, making the gradual deprecation approach necessary for backward compatibility.

Applied to files:

  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java
📚 Learning: 2025-08-19T20:07:43.748Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 339
File: nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java:16-16
Timestamp: 2025-08-19T20:07:43.748Z
Learning: In CaseField.java, the separate caseValue field (List<String>) is intentionally maintained alongside fulltextValue for specific Elasticsearch query requirements, rather than being derived on-the-fly from fulltextValue.

Applied to files:

  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/TextField.java
  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java
📚 Learning: 2025-06-23T13:30:13.096Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 318
File: nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/menu/MenuItemConstants.java:60-62
Timestamp: 2025-06-23T13:30:13.096Z
Learning: In MenuItemConstants enum in nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/menu/MenuItemConstants.java, the field `attributeId` will be renamed to `value` to make it more generic and appropriate for both dataset attribute identifiers and technical constants like PATH_SEPARATOR.

Applied to files:

  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java
📚 Learning: 2025-08-19T20:07:15.621Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 339
File: application-engine/src/test/groovy/com/netgrif/application/engine/filters/FilterImportExportTest.groovy:341-341
Timestamp: 2025-08-19T20:07:15.621Z
Learning: In the Elasticsearch migration, the stringId property was removed from ElasticCase and ElasticTask, with the id property now containing the MongoDB case/task object ID directly. This consolidation eliminates redundancy and simplifies the data model.

Applied to files:

  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java
📚 Learning: 2025-08-19T20:13:40.087Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 339
File: nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java:16-16
Timestamp: 2025-08-19T20:13:40.087Z
Learning: In CaseField.java, fulltextValue is mapped as a keyword field type in Elasticsearch (for exact matches, filtering, aggregations), while the separate caseValue field serves different Elasticsearch query requirements, allowing the system to support multiple query patterns on the same data through different field mappings.

Applied to files:

  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java
🧬 Code graph analysis (4)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/TextField.java (3)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java (1)
  • Data (11-34)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java (1)
  • Data (10-31)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/MapField.java (1)
  • Data (10-46)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorListField.java (5)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorFieldValue.java (1)
  • Getter (12-31)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserFieldValue.java (1)
  • Getter (8-49)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java (1)
  • Getter (24-325)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/GroupFieldValue.java (1)
  • Getter (8-45)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorField.java (1)
  • Setter (10-41)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserFieldValue.java (2)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorFieldValue.java (1)
  • Getter (12-31)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/GroupFieldValue.java (1)
  • Getter (8-45)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorFieldValue.java (2)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserFieldValue.java (1)
  • Getter (8-49)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/GroupFieldValue.java (1)
  • Getter (8-45)
🪛 LanguageTool
docs/roles/actorlist.md

[style] ~88-~88: You have already used this phrasing in nearby sentences. Consider replacing it to add variety to your writing.
Context: ...ission only for a set of actors, and we want to change the content of this set runtime,...

(REP_WANT_TO_VB)

docs/roles/permissions.md

[style] ~371-~371: Consider a more concise word here.
Context: ...d a permission from at least one source in order to be allowed to perform an operation. A g...

(IN_ORDER_TO_PREMIUM)

🪛 markdownlint-cli2 (0.18.1)
docs/search/elastic_mapping.md

167-167: Files should end with a single newline character

(MD047, single-trailing-newline)

docs/roles/actorlist.md

21-21: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (18)
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
🔇 Additional comments (15)
application-engine/src/main/java/com/netgrif/application/engine/importer/service/DataValidator.java (1)

22-25: Good switch to parameterized logging (avoids eager string building).

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/TextField.java (1)

16-18: Null-safe TextField(String) constructor is now explicit and predictable.
Good change: avoids List.of(null) throwing and standardizes “no value” to an empty list.

docs/search/elastic_mapping.md (2)

115-117: Approved: typo fixed and fulltextValue properly updated for actor-centric terminology.

The typo "date formated" has been corrected to "date formatted", and the description now correctly references both actor and actorList field types in the fulltextValue row. The documentation is now consistent with the PR's actor-centric terminology changes.


160-167: Approved: new ActorField section comprehensively documents actor field mappings.

The new section properly documents the Elasticsearch mappings for ActorField and ActorListField types, with clear descriptions of each mapped attribute (usernameValue, fullNameValue, actorIdValue, actorRealmIdValue). This aligns well with the actor-based refactoring throughout the PR.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/Transition.java (3)

43-43: LGTM: Field renamed to actor-based terminology.

The field rename from userRefs to actorRefs correctly reflects the new actor-based permission model.


96-96: LGTM: Constructor initialization updated.

The initialization of actorRefs in the constructor is correct and consistent with other field initializations.


264-264: LGTM: Copy constructor properly creates defensive copies.

The copy constructor correctly clones actorRefs with defensive copies of the nested permission maps, preventing unintended sharing of mutable state between instances.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java (2)

13-13: Good encapsulation improvement.

Making buttonValue protected prevents external direct access and ensures mutations go through the explicit setter.


27-27: LGTM: Style consistency.

Using this.buttonValue explicitly is a minor style improvement with no functional impact.

application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MongoSearchService.java (1)

252-255: isEmpty() change is correct and clearer.

application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticViewPermissionService.java (1)

35-46: Query composition matches intended “negative actors exclude globally” behavior. Based on learnings, the final structure still enforces global negative-actor exclusion even when roles match.

application-engine/src/main/java/com/netgrif/application/engine/export/service/ExportService.java (2)

291-295: ACTORLIST exporting IDs is a good, stable choice.


288-290: Remove toString() and use DateUtils.dateTimeFormatter for consistent DATETIME export formatting.

DATETIME fields are always LocalDateTime (strictly typed in DateTimeField extends Field<LocalDateTime>). The issue is not format variability by type, but rather that the export uses LocalDateTime.toString() (ISO format: 2024-01-15T14:30:00) instead of the consistent formatter defined in DateUtils.dateTimeFormatter (pattern: yyyy-MM-dd HH:mm). Use DateUtils.toString((LocalDateTime) fieldData) instead. Note: DATE case has the same issue—it also uses native toString() instead of the DateUtils formatter.

Likely an incorrect or invalid review comment.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserFieldValue.java (1)

10-48: Inheritance + buildMappingData() addition are consistent with the actor model. Based on learnings, this supports polymorphic use in actor lists.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java (1)

26-53: List-based multi-file handling and extension formatting look good.
filePath is now initialized/populated consistently (Line 30-39) and nameWithExtension avoids "*.null" (Line 63-68).

Also applies to: 63-68

- fix possible casting exception
- fix mutating referenced collection
- fix NPE in AbstractAuthorizationService
- optimize for loop in AbstractAuthorizationService
- fix NPE in ButtonField and value duplicates
Copy link

@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: 4

Caution

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

⚠️ Outside diff range comments (1)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java (1)

55-68: Trailing-dot filenames lose the dot on reconstruction (edge case).

The combination of extractFileExtensionFromName and nameWithExtension slightly alters filenames that end with a dot, e.g. "report.":

  • extractFileExtensionFromName("report.") produces name = "report", extension = "".
  • nameWithExtension("report", "") then returns "report" (dot dropped).

If you want exact round-tripping even for this edge case, you can treat a trailing dot as “no extension”:

private FileNameAndExtension extractFileExtensionFromName(String filename) {
     int index = filename.lastIndexOf('.');
-    if (index > 0) {
+    if (index > 0 && index < filename.length() - 1) {
         return new FileNameAndExtension(filename.substring(0, index), filename.substring(index + 1));
     }
     return new FileNameAndExtension(filename, null);
 }

nameWithExtension can then stay as-is and will reconstruct the original filename correctly for both “no extension” and “trailing dot” cases.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 03a9561 and fcb5ed3.

📒 Files selected for processing (4)
  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java (11 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/AbstractAuthorizationService.java (2 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java (2 hunks)
🧰 Additional context used
🧠 Learnings (10)
📓 Common learnings
Learnt from: Retoocs
Repo: netgrif/application-engine PR: 397
File: application-engine/src/main/resources/petriNets/engine-processes/org_group.xml:36-39
Timestamp: 2025-12-12T12:35:57.760Z
Learning: In the org_group.xml file (application-engine/src/main/resources/petriNets/engine-processes/org_group.xml), variable names in action blocks like userField and user_selection should be kept as-is even when the field type changes from "user" to "actor".
Learnt from: Retoocs
Repo: netgrif/application-engine PR: 397
File: application-engine/src/test/groovy/com/netgrif/application/engine/impersonation/ImpersonationServiceTest.groovy:18-20
Timestamp: 2025-12-12T12:40:25.863Z
Learning: In the actor refactoring, UserFieldValue is a subclass of ActorFieldValue, and ActorListFieldValue accepts ActorFieldValue instances. Therefore, passing UserFieldValue instances to ActorListFieldValue is valid through polymorphism.
📚 Learning: 2025-06-23T13:30:13.096Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 318
File: nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/menu/MenuItemConstants.java:60-62
Timestamp: 2025-06-23T13:30:13.096Z
Learning: In MenuItemConstants enum in nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/menu/MenuItemConstants.java, the field `attributeId` will be renamed to `value` to make it more generic and appropriate for both dataset attribute identifiers and technical constants like PATH_SEPARATOR.

Applied to files:

  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java
📚 Learning: 2025-12-12T13:39:52.238Z
Learnt from: Retoocs
Repo: netgrif/application-engine PR: 397
File: application-engine/src/main/java/com/netgrif/application/engine/workflow/service/CaseSearchService.java:98-104
Timestamp: 2025-12-12T13:39:52.238Z
Learning: In application-engine/src/main/java/com/netgrif/application/engine/workflow/service/CaseSearchService.java, the permission constraint logic in buildQuery() intentionally applies negative actor constraints globally: ((roleConstraint AND NOT negRoleConstraint) OR actorConstraint) AND NOT negActorConstraint. This means users in negativeViewActors are excluded even if they have positive role permissions, which is the intended authorization behavior.

Applied to files:

  • application-engine/src/main/java/com/netgrif/application/engine/workflow/service/AbstractAuthorizationService.java
📚 Learning: 2025-08-19T19:38:19.471Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 338
File: nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/FileFieldValue.java:40-51
Timestamp: 2025-08-19T19:38:19.471Z
Learning: In FileFieldValue.getPath() method in the NAE codebase, the deprecated method returns an empty string instead of throwing an exception because it's still used in tests across multiple projects. Tests will be refactored in later snapshots, making the gradual deprecation approach necessary for backward compatibility.

Applied to files:

  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java
📚 Learning: 2025-08-19T20:07:43.748Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 339
File: nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java:16-16
Timestamp: 2025-08-19T20:07:43.748Z
Learning: In CaseField.java, the separate caseValue field (List<String>) is intentionally maintained alongside fulltextValue for specific Elasticsearch query requirements, rather than being derived on-the-fly from fulltextValue.

Applied to files:

  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java
  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java
📚 Learning: 2025-12-12T12:35:57.760Z
Learnt from: Retoocs
Repo: netgrif/application-engine PR: 397
File: application-engine/src/main/resources/petriNets/engine-processes/org_group.xml:36-39
Timestamp: 2025-12-12T12:35:57.760Z
Learning: In the org_group.xml file (application-engine/src/main/resources/petriNets/engine-processes/org_group.xml), variable names in action blocks like userField and user_selection should be kept as-is even when the field type changes from "user" to "actor".

Applied to files:

  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java
📚 Learning: 2025-08-19T20:07:15.621Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 339
File: application-engine/src/test/groovy/com/netgrif/application/engine/filters/FilterImportExportTest.groovy:341-341
Timestamp: 2025-08-19T20:07:15.621Z
Learning: In the Elasticsearch migration, the stringId property was removed from ElasticCase and ElasticTask, with the id property now containing the MongoDB case/task object ID directly. This consolidation eliminates redundancy and simplifies the data model.

Applied to files:

  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java
📚 Learning: 2025-08-19T20:13:40.087Z
Learnt from: renczesstefan
Repo: netgrif/application-engine PR: 339
File: nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java:16-16
Timestamp: 2025-08-19T20:13:40.087Z
Learning: In CaseField.java, fulltextValue is mapped as a keyword field type in Elasticsearch (for exact matches, filtering, aggregations), while the separate caseValue field serves different Elasticsearch query requirements, allowing the system to support multiple query patterns on the same data through different field mappings.

Applied to files:

  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java
📚 Learning: 2025-10-20T11:44:44.907Z
Learnt from: machacjozef
Repo: netgrif/application-engine PR: 367
File: application-engine/src/main/resources/application.yaml:24-24
Timestamp: 2025-10-20T11:44:44.907Z
Learning: In the netgrif/application-engine project, the correction of the Elasticsearch task index name from "_taks" to "_task" in application.yaml was approved by maintainer machacjozef, indicating that any data migration concerns for this typo fix are handled separately or not applicable to their deployment scenario.

Applied to files:

  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java
📚 Learning: 2025-12-12T12:40:25.863Z
Learnt from: Retoocs
Repo: netgrif/application-engine PR: 397
File: application-engine/src/test/groovy/com/netgrif/application/engine/impersonation/ImpersonationServiceTest.groovy:18-20
Timestamp: 2025-12-12T12:40:25.863Z
Learning: In the actor refactoring, UserFieldValue is a subclass of ActorFieldValue, and ActorListFieldValue accepts ActorFieldValue instances. Therefore, passing UserFieldValue instances to ActorListFieldValue is valid through polymorphism.

Applied to files:

  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java
🧬 Code graph analysis (2)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java (2)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java (1)
  • Data (11-34)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/MapField.java (1)
  • Data (10-46)
application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java (1)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nStringUtils.java (1)
  • I18nStringUtils (8-18)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
🔇 Additional comments (13)
application-engine/src/main/java/com/netgrif/application/engine/workflow/service/AbstractAuthorizationService.java (2)

47-75: LGTM! Well-structured permission resolution logic.

The implementation correctly addresses all previous review concerns:

  • Defensive copy prevents mutation of docPermissions backing maps
  • Early returns for null checks and empty intersections improve readability
  • Iterating over intersection keys directly is more efficient than scanning the entire map

77-84: LGTM!

The null guard at lines 78-80 properly handles the case where docPermissions might contain null permission maps.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java (2)

13-13: LGTM! Encapsulation improved.

Changing buttonValue from public to protected properly encapsulates the field and forces callers to use the accessor methods.


20-24: LGTM! Synchronization and null safety properly implemented.

The setter correctly clears fulltextValue before updating (preventing duplicate accumulation) and handles null values gracefully. This addresses the critical issues raised in previous reviews.

application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java (8)

37-37: LGTM! Generic type improves flexibility.

Using Field<?> enables polymorphic handling of various field types through instanceof checks, which aligns well with the actor-centric refactoring.


52-53: LGTM! Actor-centric routing aligns with refactoring objectives.

The routing of ActorField and ActorListField to their respective transform methods is correct and consistent with the broader user→actor refactoring described in the PR objectives.

Also applies to: 68-69


89-89: LGTM! More idiomatic Optional handling.

Using isEmpty() instead of !isPresent() improves readability and follows modern Java best practices.

Also applies to: 152-152


111-121: LGTM! Simplified field transformations.

The transformCaseFieldField and transformFilterFieldField methods are correctly updated to construct their elastic domain objects with appropriate parameters.


123-129: LGTM! Unsafe cast issue resolved with stream conversion.

The pattern matching and stream-based conversion properly handles any Collection<?> type and converts it to List<String> safely. This addresses the unsafe cast concern raised in previous reviews.


214-229: Actor transform methods kept as-is per maintainer decision.

The unsafe casts in transformActorField (Line 216) and transformActorListField (Line 224) were previously flagged. Based on learnings, the polymorphism between UserFieldValue and ActorFieldValue supports these casts, and the maintainer explicitly chose to keep the current implementation.


234-234: LGTM! Modern pattern matching improves readability.

The use of pattern matching (instanceof LocalDate date) is a clean, modern approach that eliminates the need for explicit casting.


292-295: LGTM! FileListField transformation updated correctly.

The method properly extracts file name-path data using getNamesPaths() and constructs the elastic FileField appropriately.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java (1)

22-24: Null-safe single-value constructor semantics look good, but confirm expected behaviour.

FileField(FileFieldValue) now treats a null value as “no files” by delegating to this(null) instead of throwing a NullPointerException. This is a reasonable default and removes the earlier NPE risk from List.of(fileFieldValue), but it subtly changes the contract.

Please confirm that all call sites expect new FileField(null) to result in an empty field rather than a hard failure; if some callers rely on a strict non-null contract, it might be safer to enforce it with a clear exception instead.

- add nullcheck in AbstractAuthorizationService
@machacjozef machacjozef changed the base branch from release/7.0.0-rev9 to release/7.0.0-rev10 December 15, 2025 14:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

improvement A change that improves on an existing feature Large Medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants