RED-8615: Revert and change the current behaviour of manualChanges

This commit is contained in:
Kilian Schuettler 2024-02-28 09:32:45 +01:00
parent 9c33404490
commit b196544131
39 changed files with 1092 additions and 330 deletions

View File

@ -16,6 +16,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.iqser.red.service.persistence.management.v1.processor.model.ManualChangesQueryOptions;
import com.iqser.red.service.persistence.management.v1.processor.service.AccessControlService; import com.iqser.red.service.persistence.management.v1.processor.service.AccessControlService;
import com.iqser.red.service.persistence.management.v1.processor.service.CommentService; import com.iqser.red.service.persistence.management.v1.processor.service.CommentService;
import com.iqser.red.service.persistence.management.v1.processor.service.DossierManagementService; import com.iqser.red.service.persistence.management.v1.processor.service.DossierManagementService;
@ -99,12 +100,12 @@ public class ManualRedactionController implements ManualRedactionResource {
accessControlService.verifyUserIsReviewerOrApprover(dossierId, fileId); accessControlService.verifyUserIsReviewerOrApprover(dossierId, fileId);
auditPersistenceService.audit(AuditRequest.builder() auditPersistenceService.audit(AuditRequest.builder()
.userId(KeycloakSecurity.getUserId()) .userId(KeycloakSecurity.getUserId())
.objectId(fileId) .objectId(fileId)
.category(AuditCategory.DOCUMENT.name()) .category(AuditCategory.DOCUMENT.name())
.message("Comment was removed.") .message("Comment was removed.")
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, annotationId)) .details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, annotationId))
.build()); .build());
commentService.deleteComment(fileId, List.of(Long.valueOf(commentId))); commentService.deleteComment(fileId, List.of(Long.valueOf(commentId)));
} }
@ -114,11 +115,12 @@ public class ManualRedactionController implements ManualRedactionResource {
@PreAuthorize("hasAuthority('" + READ_MANUAL_REDACTIONS + "')") @PreAuthorize("hasAuthority('" + READ_MANUAL_REDACTIONS + "')")
public ManualRedactions getManualRedactions(@PathVariable(DOSSIER_ID) String dossierId, public ManualRedactions getManualRedactions(@PathVariable(DOSSIER_ID) String dossierId,
@PathVariable(FILE_ID) String fileId, @PathVariable(FILE_ID) String fileId,
@RequestParam(value = "unprocessed", required = false, defaultValue = FALSE) boolean unprocessed) { @RequestParam(value = "unprocessed", required = false, defaultValue = FALSE) boolean unprocessed,
@RequestParam(value = "includeDictChanges", required = false, defaultValue = TRUE) boolean includeDictChanges) {
accessControlService.checkDossierExistenceAndViewPermissionsToDossier(dossierId); accessControlService.checkDossierExistenceAndViewPermissionsToDossier(dossierId);
accessControlService.validateFileResourceExistence(fileId); accessControlService.validateFileResourceExistence(fileId);
return manualRedactionService.getManualRedactions(fileId, unprocessed); return manualRedactionService.getManualRedactions(fileId, ManualChangesQueryOptions.builder().includeOnlyUnprocessed(unprocessed).includeDictChanges(includeDictChanges).build());
} }
@ -149,12 +151,12 @@ public class ManualRedactionController implements ManualRedactionResource {
var response = commentService.addComment(fileId, annotationId, CommentRequest.builder().user(KeycloakSecurity.getUserId()).text(addCommentRequest.getText()).build()); var response = commentService.addComment(fileId, annotationId, CommentRequest.builder().user(KeycloakSecurity.getUserId()).text(addCommentRequest.getText()).build());
auditPersistenceService.audit(AuditRequest.builder() auditPersistenceService.audit(AuditRequest.builder()
.userId(KeycloakSecurity.getUserId()) .userId(KeycloakSecurity.getUserId())
.objectId(fileId) .objectId(fileId)
.category(AuditCategory.DOCUMENT.name()) .category(AuditCategory.DOCUMENT.name())
.message("Comment was added.") .message("Comment was added.")
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, annotationId)) .details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, annotationId))
.build()); .build());
return new CommentResponse(String.valueOf(response.getId())); return new CommentResponse(String.valueOf(response.getId()));
} }
@ -169,7 +171,8 @@ public class ManualRedactionController implements ManualRedactionResource {
var dossier = dossierManagementService.getDossierById(dossierId, false, false); var dossier = dossierManagementService.getDossierById(dossierId, false, false);
accessControlService.checkAccessPermissionsToDossier(dossierId); accessControlService.checkAccessPermissionsToDossier(dossierId);
accessControlService.verifyFileIsNotApproved(dossierId, fileId); accessControlService.verifyFileIsNotApproved(dossierId, fileId);
if (addRedactionRequests.stream().anyMatch(AddRedactionRequestModel::isAddToAllDossiers)) { if (addRedactionRequests.stream()
.anyMatch(AddRedactionRequestModel::isAddToAllDossiers)) {
accessControlService.verifyUserIsApprover(dossierId); accessControlService.verifyUserIsApprover(dossierId);
} else { } else {
accessControlService.verifyUserIsMemberOrApprover(dossierId); accessControlService.verifyUserIsMemberOrApprover(dossierId);
@ -179,12 +182,12 @@ public class ManualRedactionController implements ManualRedactionResource {
List<ManualAddResponse> responseList = manualRedactionService.addAddRedaction(dossierId, fileId, requests); List<ManualAddResponse> responseList = manualRedactionService.addAddRedaction(dossierId, fileId, requests);
responseList.forEach(response -> auditPersistenceService.audit(AuditRequest.builder() responseList.forEach(response -> auditPersistenceService.audit(AuditRequest.builder()
.userId(KeycloakSecurity.getUserId()) .userId(KeycloakSecurity.getUserId())
.objectId(fileId) .objectId(fileId)
.category(AuditCategory.DOCUMENT.name()) .category(AuditCategory.DOCUMENT.name())
.message("Manual redaction was added.") .message("Manual redaction was added.")
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, response.getAnnotationId())) .details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, response.getAnnotationId()))
.build())); .build()));
return responseList; return responseList;
} }
@ -199,22 +202,27 @@ public class ManualRedactionController implements ManualRedactionResource {
var dossier = dossierManagementService.getDossierById(dossierId, false, false); var dossier = dossierManagementService.getDossierById(dossierId, false, false);
accessControlService.checkAccessPermissionsToDossier(dossierId); accessControlService.checkAccessPermissionsToDossier(dossierId);
accessControlService.verifyFileIsNotApproved(dossierId, fileId); accessControlService.verifyFileIsNotApproved(dossierId, fileId);
if (removeRedactionRequests.stream().anyMatch(RemoveRedactionRequestModel::isRemoveFromAllDossiers)) { if (removeRedactionRequests.stream()
.anyMatch(RemoveRedactionRequestModel::isRemoveFromAllDossiers)) {
accessControlService.verifyUserIsApprover(dossierId); accessControlService.verifyUserIsApprover(dossierId);
} else { } else {
accessControlService.verifyUserIsMemberOrApprover(dossierId); accessControlService.verifyUserIsMemberOrApprover(dossierId);
} }
List<RemoveRedactionRequest> requests = manualRedactionMapper.toRemoveRedactionRequestList(dossierId, fileId, dossier.getDossierTemplateId(), removeRedactionRequests, includeUnprocessed); List<RemoveRedactionRequest> requests = manualRedactionMapper.toRemoveRedactionRequestList(dossierId,
fileId,
dossier.getDossierTemplateId(),
removeRedactionRequests,
includeUnprocessed);
List<ManualAddResponse> responseList = manualRedactionService.addRemoveRedaction(dossierId, fileId, requests); List<ManualAddResponse> responseList = manualRedactionService.addRemoveRedaction(dossierId, fileId, requests);
responseList.forEach(response -> auditPersistenceService.audit(AuditRequest.builder() responseList.forEach(response -> auditPersistenceService.audit(AuditRequest.builder()
.userId(KeycloakSecurity.getUserId()) .userId(KeycloakSecurity.getUserId())
.objectId(fileId) .objectId(fileId)
.category(AuditCategory.DOCUMENT.name()) .category(AuditCategory.DOCUMENT.name())
.message("Redaction was manually removed") .message("Redaction was manually removed")
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, response.getAnnotationId())) .details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, response.getAnnotationId()))
.build())); .build()));
return responseList; return responseList;
} }
@ -233,12 +241,12 @@ public class ManualRedactionController implements ManualRedactionResource {
List<ManualAddResponse> responseList = manualRedactionService.addForceRedaction(dossierId, fileId, requests); List<ManualAddResponse> responseList = manualRedactionService.addForceRedaction(dossierId, fileId, requests);
responseList.forEach(response -> auditPersistenceService.audit(AuditRequest.builder() responseList.forEach(response -> auditPersistenceService.audit(AuditRequest.builder()
.userId(KeycloakSecurity.getUserId()) .userId(KeycloakSecurity.getUserId())
.objectId(fileId) .objectId(fileId)
.category(AuditCategory.DOCUMENT.name()) .category(AuditCategory.DOCUMENT.name())
.message("Skipped redaction was forced to be redacted") .message("Skipped redaction was forced to be redacted")
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, response.getAnnotationId())) .details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, response.getAnnotationId()))
.build())); .build()));
return responseList; return responseList;
} }
@ -258,12 +266,12 @@ public class ManualRedactionController implements ManualRedactionResource {
List<ManualAddResponse> responseList = manualRedactionService.addLegalBasisChange(dossierId, fileId, requests); List<ManualAddResponse> responseList = manualRedactionService.addLegalBasisChange(dossierId, fileId, requests);
responseList.forEach(response -> auditPersistenceService.audit(AuditRequest.builder() responseList.forEach(response -> auditPersistenceService.audit(AuditRequest.builder()
.userId(KeycloakSecurity.getUserId()) .userId(KeycloakSecurity.getUserId())
.objectId(fileId) .objectId(fileId)
.category(AuditCategory.DOCUMENT.name()) .category(AuditCategory.DOCUMENT.name())
.message("Legal basis reason was changed") .message("Legal basis reason was changed")
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, response.getAnnotationId())) .details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, response.getAnnotationId()))
.build())); .build()));
return responseList; return responseList;
} }
@ -280,17 +288,21 @@ public class ManualRedactionController implements ManualRedactionResource {
accessControlService.verifyFileIsNotApproved(dossierId, fileId); accessControlService.verifyFileIsNotApproved(dossierId, fileId);
accessControlService.verifyUserIsMemberOrApprover(dossierId); accessControlService.verifyUserIsMemberOrApprover(dossierId);
List<RecategorizationRequest> requests = manualRedactionMapper.toRecategorizationRequestList(dossierId, fileId, dossier.getDossierTemplateId(), recategorizationRequests, includeUnprocessed); List<RecategorizationRequest> requests = manualRedactionMapper.toRecategorizationRequestList(dossierId,
fileId,
dossier.getDossierTemplateId(),
recategorizationRequests,
includeUnprocessed);
List<ManualAddResponse> responseList = manualRedactionService.addRecategorization(dossierId, fileId, requests); List<ManualAddResponse> responseList = manualRedactionService.addRecategorization(dossierId, fileId, requests);
responseList.forEach(response -> auditPersistenceService.audit(AuditRequest.builder() responseList.forEach(response -> auditPersistenceService.audit(AuditRequest.builder()
.userId(KeycloakSecurity.getUserId()) .userId(KeycloakSecurity.getUserId())
.objectId(fileId) .objectId(fileId)
.category(AuditCategory.DOCUMENT.name()) .category(AuditCategory.DOCUMENT.name())
.message("Entity was recategorized.") .message("Entity was recategorized.")
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, response.getAnnotationId())) .details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, response.getAnnotationId()))
.build())); .build()));
return responseList; return responseList;
} }
@ -310,12 +322,12 @@ public class ManualRedactionController implements ManualRedactionResource {
List<ManualAddResponse> responseList = manualRedactionService.addResizeRedaction(dossierId, fileId, requests, includeUnprocessed); List<ManualAddResponse> responseList = manualRedactionService.addResizeRedaction(dossierId, fileId, requests, includeUnprocessed);
responseList.forEach(response -> auditPersistenceService.audit(AuditRequest.builder() responseList.forEach(response -> auditPersistenceService.audit(AuditRequest.builder()
.userId(KeycloakSecurity.getUserId()) .userId(KeycloakSecurity.getUserId())
.objectId(fileId) .objectId(fileId)
.category(AuditCategory.DOCUMENT.name()) .category(AuditCategory.DOCUMENT.name())
.message("Skipped redaction was resized to be redacted") .message("Skipped redaction was resized to be redacted")
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, response.getAnnotationId())) .details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, response.getAnnotationId()))
.build())); .build()));
return responseList; return responseList;
} }

View File

@ -46,6 +46,7 @@ public interface ManualRedactionResource {
String COMMENT_ID_PATH_VARIABLE = "/{" + COMMENT_ID + "}"; String COMMENT_ID_PATH_VARIABLE = "/{" + COMMENT_ID + "}";
String FALSE = "false"; String FALSE = "false";
String TRUE = "true";
@ResponseStatus(value = HttpStatus.NO_CONTENT) @ResponseStatus(value = HttpStatus.NO_CONTENT)
@ -59,7 +60,11 @@ public interface ManualRedactionResource {
@ResponseStatus(value = HttpStatus.OK) @ResponseStatus(value = HttpStatus.OK)
@PostMapping(value = MANUAL_REDACTION_REST_PATH + "/comment/add" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + ANNOTATION_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @PostMapping(value = MANUAL_REDACTION_REST_PATH
+ "/comment/add"
+ DOSSIER_ID_PATH_PARAM
+ FILE_ID_PATH_VARIABLE
+ ANNOTATION_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Adds a comment to a redaction/redaction request", description = "None") @Operation(summary = "Adds a comment to a redaction/redaction request", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Dossier or file not found"), @ApiResponse(responseCode = "403", description = "Forbidden")}) @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Dossier or file not found"), @ApiResponse(responseCode = "403", description = "Forbidden")})
CommentResponse addComment(@PathVariable(DOSSIER_ID) String dossierId, CommentResponse addComment(@PathVariable(DOSSIER_ID) String dossierId,
@ -79,7 +84,10 @@ public interface ManualRedactionResource {
@ResponseStatus(value = HttpStatus.OK) @ResponseStatus(value = HttpStatus.OK)
@PostMapping(value = MANUAL_REDACTION_REST_PATH + "/bulk/redaction/add" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @PostMapping(value = MANUAL_REDACTION_REST_PATH
+ "/bulk/redaction/add"
+ DOSSIER_ID_PATH_PARAM
+ FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Adds a manual redaction", description = "None") @Operation(summary = "Adds a manual redaction", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Dossier or file not found"), @ApiResponse(responseCode = "403", description = "Forbidden")}) @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Dossier or file not found"), @ApiResponse(responseCode = "403", description = "Forbidden")})
List<ManualAddResponse> addRedactionBulk(@PathVariable(DOSSIER_ID) String dossierId, List<ManualAddResponse> addRedactionBulk(@PathVariable(DOSSIER_ID) String dossierId,
@ -88,7 +96,10 @@ public interface ManualRedactionResource {
@ResponseStatus(value = HttpStatus.OK) @ResponseStatus(value = HttpStatus.OK)
@PostMapping(value = MANUAL_REDACTION_REST_PATH + "/bulk/redaction/remove" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @PostMapping(value = MANUAL_REDACTION_REST_PATH
+ "/bulk/redaction/remove"
+ DOSSIER_ID_PATH_PARAM
+ FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Removes the redactions list", description = "None") @Operation(summary = "Removes the redactions list", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Dossier or file not found"), @ApiResponse(responseCode = "403", description = "Forbidden")}) @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Dossier or file not found"), @ApiResponse(responseCode = "403", description = "Forbidden")})
List<ManualAddResponse> removeRedactionBulk(@PathVariable(DOSSIER_ID) String dossierId, List<ManualAddResponse> removeRedactionBulk(@PathVariable(DOSSIER_ID) String dossierId,
@ -98,7 +109,10 @@ public interface ManualRedactionResource {
@ResponseStatus(value = HttpStatus.OK) @ResponseStatus(value = HttpStatus.OK)
@PostMapping(value = MANUAL_REDACTION_REST_PATH + "/bulk/redaction/force" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @PostMapping(value = MANUAL_REDACTION_REST_PATH
+ "/bulk/redaction/force"
+ DOSSIER_ID_PATH_PARAM
+ FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Forces the redactions list", description = "None") @Operation(summary = "Forces the redactions list", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Dossier or file not found"), @ApiResponse(responseCode = "403", description = "Forbidden")}) @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Dossier or file not found"), @ApiResponse(responseCode = "403", description = "Forbidden")})
List<ManualAddResponse> forceRedactionBulk(@PathVariable(DOSSIER_ID) String dossierId, List<ManualAddResponse> forceRedactionBulk(@PathVariable(DOSSIER_ID) String dossierId,
@ -107,7 +121,10 @@ public interface ManualRedactionResource {
@ResponseStatus(value = HttpStatus.OK) @ResponseStatus(value = HttpStatus.OK)
@PostMapping(value = MANUAL_REDACTION_REST_PATH + "/bulk/redaction/legalBasisChange" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @PostMapping(value = MANUAL_REDACTION_REST_PATH
+ "/bulk/redaction/legalBasisChange"
+ DOSSIER_ID_PATH_PARAM
+ FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Changes the legal basis reasons list", description = "None") @Operation(summary = "Changes the legal basis reasons list", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Dossier or file not found"), @ApiResponse(responseCode = "403", description = "Forbidden")}) @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Dossier or file not found"), @ApiResponse(responseCode = "403", description = "Forbidden")})
List<ManualAddResponse> legalBasisChangeBulk(@PathVariable(DOSSIER_ID) String dossierId, List<ManualAddResponse> legalBasisChangeBulk(@PathVariable(DOSSIER_ID) String dossierId,
@ -116,7 +133,10 @@ public interface ManualRedactionResource {
@ResponseStatus(value = HttpStatus.OK) @ResponseStatus(value = HttpStatus.OK)
@PostMapping(value = MANUAL_REDACTION_REST_PATH + "/bulk/redaction/recategorize" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @PostMapping(value = MANUAL_REDACTION_REST_PATH
+ "/bulk/redaction/recategorize"
+ DOSSIER_ID_PATH_PARAM
+ FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Recategorizes the list of redaction log entries", description = "None") @Operation(summary = "Recategorizes the list of redaction log entries", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Dossier or file not found"), @ApiResponse(responseCode = "403", description = "Forbidden")}) @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Dossier or file not found"), @ApiResponse(responseCode = "403", description = "Forbidden")})
List<ManualAddResponse> recategorizeBulk(@PathVariable(DOSSIER_ID) String dossierId, List<ManualAddResponse> recategorizeBulk(@PathVariable(DOSSIER_ID) String dossierId,
@ -126,7 +146,10 @@ public interface ManualRedactionResource {
@ResponseStatus(value = HttpStatus.OK) @ResponseStatus(value = HttpStatus.OK)
@PostMapping(value = MANUAL_REDACTION_REST_PATH + "/bulk/redaction/resize" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @PostMapping(value = MANUAL_REDACTION_REST_PATH
+ "/bulk/redaction/resize"
+ DOSSIER_ID_PATH_PARAM
+ FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Resizes the redactions list", description = "None") @Operation(summary = "Resizes the redactions list", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Dossier or file not found"), @ApiResponse(responseCode = "403", description = "Forbidden")}) @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Dossier or file not found"), @ApiResponse(responseCode = "403", description = "Forbidden")})
List<ManualAddResponse> resizeRedactionBulk(@PathVariable(DOSSIER_ID) String dossierId, List<ManualAddResponse> resizeRedactionBulk(@PathVariable(DOSSIER_ID) String dossierId,
@ -137,15 +160,24 @@ public interface ManualRedactionResource {
@ResponseStatus(value = HttpStatus.OK) @ResponseStatus(value = HttpStatus.OK)
@GetMapping(value = MANUAL_REDACTION_REST_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) @GetMapping(value = MANUAL_REDACTION_REST_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Returns the manual redactions", description = "If the unprocessed flag is true then only the unprocessed manual redactions are returned. If the flag is false" + "all manual redactions are returned. Default value for the flag is false.") @Operation(summary = "Returns the manual redactions", description = """
If the unprocessed flag is true then only the unprocessed manual redactions are returned. If the flag is false\
all manual redactions are returned. Default value for the flag is false.\
If the includeDictChanges flag is false, only local manual redactions will be returned, otherwise all are returned. Default value for the flag is true.
""")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Dossier or file not found")}) @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Dossier or file not found")})
ManualRedactions getManualRedactions(@PathVariable(DOSSIER_ID) String dossierId, ManualRedactions getManualRedactions(@PathVariable(DOSSIER_ID) String dossierId,
@PathVariable(FILE_ID) String fileId, @PathVariable(FILE_ID) String fileId,
@RequestParam(value = "unprocessed", required = false, defaultValue = FALSE) boolean unprocessed); @RequestParam(value = "unprocessed", required = false, defaultValue = FALSE) boolean unprocessed,
@RequestParam(value = "includeDictChanges", required = false, defaultValue = TRUE) boolean includeDictChanges);
@ResponseStatus(value = HttpStatus.OK) @ResponseStatus(value = HttpStatus.OK)
@GetMapping(value = MANUAL_REDACTION_REST_PATH + "/comments" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + ANNOTATION_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) @GetMapping(value = MANUAL_REDACTION_REST_PATH
+ "/comments"
+ DOSSIER_ID_PATH_PARAM
+ FILE_ID_PATH_VARIABLE
+ ANNOTATION_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Returns the comments for a specific annotation in a specific file", description = "None") @Operation(summary = "Returns the comments for a specific annotation in a specific file", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Dossier or file not found")}) @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Dossier or file not found")})
AnnotationComments getComments(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, @PathVariable(ANNOTATION_ID) String annotationId); AnnotationComments getComments(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, @PathVariable(ANNOTATION_ID) String annotationId);

View File

@ -5,6 +5,7 @@ import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.
import com.iqser.red.service.persistence.management.v1.processor.entity.migration.SaasMigrationStatusEntity; import com.iqser.red.service.persistence.management.v1.processor.entity.migration.SaasMigrationStatusEntity;
import com.iqser.red.service.persistence.management.v1.processor.exception.InternalServerErrorException; import com.iqser.red.service.persistence.management.v1.processor.exception.InternalServerErrorException;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.model.ManualChangesQueryOptions;
import com.iqser.red.service.persistence.management.v1.processor.service.DossierService; import com.iqser.red.service.persistence.management.v1.processor.service.DossierService;
import com.iqser.red.service.persistence.management.v1.processor.service.IndexingService; import com.iqser.red.service.persistence.management.v1.processor.service.IndexingService;
import com.iqser.red.service.persistence.management.v1.processor.service.job.AutomaticAnalysisJob; import com.iqser.red.service.persistence.management.v1.processor.service.job.AutomaticAnalysisJob;
@ -163,7 +164,7 @@ public class SaasMigrationService implements TenantSyncService {
.dossierTemplateId(dossierTemplateId) .dossierTemplateId(dossierTemplateId)
.dossierId(dossierId) .dossierId(dossierId)
.fileId(fileId) .fileId(fileId)
.manualRedactions(manualRedactionProviderService.getManualRedactions(fileId)) .manualRedactions(manualRedactionProviderService.getManualRedactions(fileId, ManualChangesQueryOptions.allWithoutDeleted()))
.build()); .build());
log.info("Layout Parsing finished for saas migration for tenant {} dossier {} and file {}", TenantContext.getTenantId(), dossierId, fileId); log.info("Layout Parsing finished for saas migration for tenant {} dossier {} and file {}", TenantContext.getTenantId(), dossierId, fileId);
} catch (Exception e) { } catch (Exception e) {

View File

@ -0,0 +1,101 @@
package com.iqser.red.service.persistence.management.v1.processor.migration.migrations;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileEntity;
import com.iqser.red.service.persistence.management.v1.processor.migration.Migration;
import com.iqser.red.service.persistence.management.v1.processor.model.ManualChangesQueryOptions;
import com.iqser.red.service.persistence.management.v1.processor.service.FileManagementStorageService;
import com.iqser.red.service.persistence.management.v1.processor.service.manualredactions.ManualRedactionService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.FileStatusPersistenceService;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLog;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogEntry;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.ManualChange;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.ManualRedactionType;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ManualRedactions;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.BaseAnnotation;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualLegalBasisChange;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualRecategorization;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualResizeRedaction;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileType;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Setter
@Service
public class ManualRedactionTypeRenameMigration15 extends Migration {
@Autowired
private FileStatusPersistenceService fileStatusPersistenceService;
@Autowired
private FileManagementStorageService fileManagementStorageService;
@Autowired
private ManualRedactionService manualRedactionService;
public ManualRedactionTypeRenameMigration15() {
super(NAME, VERSION);
}
private static final String NAME = "Migrate ManualRedactionType names in EntityLog";
private static final long VERSION = 15;
@Override
/*
* Migrates the ManualRedactionType ADD_LOCALLY -> ADD, FORCE_REDACT -> FORCE, FORCE_HINT -> FORCE, REMOVE_LOCALLY -> REMOVE.
*/
protected void migrate() {
log.info("Migrating ManualRedactionType names");
Set<Class<? extends BaseAnnotation>> excludedClasses = Set.of(ManualResizeRedaction.class, ManualRecategorization.class, ManualLegalBasisChange.class);
ManualChangesQueryOptions options = ManualChangesQueryOptions.builder().includeDictChanges(false).excludedClasses(excludedClasses).build();
var files = fileStatusPersistenceService.getAllFiles();
for (FileEntity file : files) {
ManualRedactions manualChanges = manualRedactionService.getManualRedactions(file.getId(), options);
if (manualChanges.isEmpty()) {
continue;
}
if (!fileManagementStorageService.objectExists(file.getDossierId(), file.getId(), FileType.ENTITY_LOG)) {
continue;
}
log.info("Migrating ManualRedactionType names for fileId {}", file.getId());
EntityLog entityLog = fileManagementStorageService.getEntityLog(file.getDossierId(), file.getId());
for (EntityLogEntry entityLogEntry : entityLog.getEntityLogEntry()) {
for (ManualChange manualChange : entityLogEntry.getManualChanges()) {
if (manualChange.getManualRedactionType().equals(ManualRedactionType.ADD_LOCALLY)) {
manualChange.setManualRedactionType(ManualRedactionType.ADD);
}
if (manualChange.getManualRedactionType().equals(ManualRedactionType.FORCE_REDACT)) {
manualChange.setManualRedactionType(ManualRedactionType.FORCE);
}
if (manualChange.getManualRedactionType().equals(ManualRedactionType.FORCE_HINT)) {
manualChange.setManualRedactionType(ManualRedactionType.FORCE);
}
if (manualChange.getManualRedactionType().equals(ManualRedactionType.REMOVE_LOCALLY)) {
manualChange.setManualRedactionType(ManualRedactionType.REMOVE);
}
}
}
fileManagementStorageService.storeJSONObject(file.getDossierId(), file.getId(), FileType.ENTITY_LOG, entityLog);
}
}
}

View File

@ -0,0 +1,51 @@
package com.iqser.red.service.persistence.management.v1.processor.model;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.BaseAnnotation;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualRedactionEntry;
import lombok.Builder;
import lombok.Getter;
@Getter
@Builder
@SuppressWarnings("checkstyle:all") // explicit initialization of false. IMO it improves readability here.
public class ManualChangesQueryOptions {
@Builder.Default
private boolean includeOnlyUnprocessed = false;
@Builder.Default
private boolean includeDictChanges = true;
@Builder.Default
private boolean includeDeletions = false;
@Builder.Default
private Set<Class<? extends BaseAnnotation>> excludedClasses = Collections.emptySet();
public static ManualChangesQueryOptions allWithoutDeleted() {
return ManualChangesQueryOptions.builder().includeDeletions(false).includeDictChanges(true).includeOnlyUnprocessed(false).build();
}
public static ManualChangesQueryOptions all() {
return ManualChangesQueryOptions.builder().includeDeletions(true).includeDictChanges(true).includeOnlyUnprocessed(false).build();
}
public static ManualChangesQueryOptions unprocessedOnly() {
return ManualChangesQueryOptions.builder().includeDeletions(false).includeDictChanges(true).includeOnlyUnprocessed(true).build();
}
public static ManualChangesQueryOptions localChangesOnly() {
return ManualChangesQueryOptions.builder().includeDeletions(false).includeDictChanges(false).includeOnlyUnprocessed(false).build();
}
}

View File

@ -157,11 +157,10 @@ public class AnalysisFlagsCalculationService {
return !entryType.equals(EntryType.HINT) && // return !entryType.equals(EntryType.HINT) && //
!entryType.equals(EntryType.RECOMMENDATION) && // !entryType.equals(EntryType.RECOMMENDATION) && //
StringUtils.isNotEmpty(entry.getReason()) && // StringUtils.isNotEmpty(entry.getReason()) && //
(manualChange.getManualRedactionType().equals(ManualRedactionType.ADD_LOCALLY) || // (manualChange.getManualRedactionType().equals(ManualRedactionType.ADD) || //
manualChange.getManualRedactionType().equals(ManualRedactionType.RECATEGORIZE) || // manualChange.getManualRedactionType().equals(ManualRedactionType.RECATEGORIZE) || //
manualChange.getManualRedactionType().equals(ManualRedactionType.REMOVE_LOCALLY) || // manualChange.getManualRedactionType().equals(ManualRedactionType.REMOVE) || //
manualChange.getManualRedactionType().equals(ManualRedactionType.FORCE_REDACT) || // manualChange.getManualRedactionType().equals(ManualRedactionType.FORCE) || //
manualChange.getManualRedactionType().equals(ManualRedactionType.FORCE_HINT) || //
manualChange.getManualRedactionType().equals(ManualRedactionType.LEGAL_BASIS_CHANGE) || // manualChange.getManualRedactionType().equals(ManualRedactionType.LEGAL_BASIS_CHANGE) || //
manualChange.getManualRedactionType().equals(ManualRedactionType.RESIZE)) && // manualChange.getManualRedactionType().equals(ManualRedactionType.RESIZE)) && //
manualChange.getProcessedDate() != null && // manualChange.getProcessedDate() != null && //

View File

@ -4,7 +4,7 @@ import static com.iqser.red.service.persistence.management.v1.processor.utils.Ty
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -13,7 +13,6 @@ import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -24,6 +23,7 @@ import com.iqser.red.service.persistence.management.v1.processor.configuration.M
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.TypeEntity; import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.TypeEntity;
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierEntity; import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierEntity;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.service.manualredactions.PendingDictionaryEntryFactory;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DictionaryPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DictionaryPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.FileStatusPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.FileStatusPersistenceService;
import com.iqser.red.service.persistence.service.v1.api.shared.model.AnalyzeRequest; import com.iqser.red.service.persistence.service.v1.api.shared.model.AnalyzeRequest;
@ -51,35 +51,48 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemp
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.type.DictionaryEntryType; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.type.DictionaryEntryType;
import io.micrometer.observation.annotation.Observed; import io.micrometer.observation.annotation.Observed;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.experimental.FieldDefaults;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@Service @Service
@Slf4j @Slf4j
@RequiredArgsConstructor @RequiredArgsConstructor
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
public class EntityLogMergeService { public class EntityLogMergeService {
private final DictionaryPersistenceService dictionaryPersistenceService; DictionaryPersistenceService dictionaryPersistenceService;
private final RabbitTemplate rabbitTemplate; RabbitTemplate rabbitTemplate;
private final FileStatusService fileStatusService; FileStatusService fileStatusService;
private final FileStatusPersistenceService fileStatusPersistenceService; FileStatusPersistenceService fileStatusPersistenceService;
PendingDictionaryEntryFactory pendingDictionaryEntryFactory;
@Observed(name = "EntityLogMergeService", contextualName = "merge-entity-log") @Observed(name = "EntityLogMergeService", contextualName = "merge-entity-log")
public EntityLog mergeEntityLog(ManualRedactions manualRedactions, EntityLog entityLog, DossierEntity dossier) { public EntityLog mergeEntityLog(ManualRedactions manualRedactions, EntityLog entityLog, DossierEntity dossier) {
log.debug("Merging EntityLog"); log.debug("Merging EntityLog");
List<BaseAnnotation> allManualChanges = allManualChanges(manualRedactions); List<BaseAnnotation> allManualChanges = manualRedactions.buildAll();
List<String> manualChangesIds = allManualChanges.stream().map(BaseAnnotation::getAnnotationId).toList();
List<String> manualChangesIds = allManualChanges.stream()
.map(BaseAnnotation::getAnnotationId)
.toList();
List<EntityLogEntry> matchingEntities = entityLog.getEntityLogEntry() List<EntityLogEntry> matchingEntities = entityLog.getEntityLogEntry()
.stream() .stream()
.filter(entityLogEntry -> manualChangesIds.contains(entityLogEntry.getId())) .filter(entityLogEntry -> manualChangesIds.contains(entityLogEntry.getId()))
.collect(Collectors.toList()); .collect(Collectors.toList());
final int analysisNumber = entityLog.getAnalysisNumber(); final int analysisNumber = entityLog.getAnalysisNumber();
// Sort manual changes by date, so we process them in order of when they were requested // Sort manual changes by date, so we process them in order of when they were requested
allManualChanges = allManualChanges.stream().sorted(Comparator.comparing(BaseAnnotation::getRequestDate)).toList(); List<BaseAnnotation> allLocalManualChanges = allManualChanges.stream()
allManualChanges.forEach(manualChange -> { .filter(BaseAnnotation::isLocal)
.sorted(Comparator.comparing(BaseAnnotation::getRequestDate))
.toList();
allLocalManualChanges.forEach(manualChange -> {
// this is ugly and should be replaced with switch pattern matching https://openjdk.org/jeps/406 -> requires Java 17 (preview) or higher // this is ugly and should be replaced with switch pattern matching https://openjdk.org/jeps/406 -> requires Java 17 (preview) or higher
if (manualChange instanceof ManualRedactionEntry manualRedactionEntry) { if (manualChange instanceof ManualRedactionEntry manualRedactionEntry) {
var entityLogEntry = mergeManualRedactionEntries(manualRedactionEntry, entityLog, dossier); var entityLogEntry = mergeManualRedactionEntries(manualRedactionEntry, entityLog, dossier);
@ -97,11 +110,45 @@ public class EntityLogMergeService {
} }
}); });
// Sort manual changes by date, so we process them in order of when they were requested
List<BaseAnnotation> allDictionaryManualChanges = allManualChanges.stream()
.filter(baseAnnotation -> !baseAnnotation.isLocal())
.sorted(Comparator.comparing(BaseAnnotation::getRequestDate))
.toList();
List<EntityLogEntry> pendingEntries = allDictionaryManualChanges.stream()
.map(manualChange -> {
if (manualChange instanceof ManualRedactionEntry manualRedactionEntry) {
return pendingDictionaryEntryFactory.buildAddToDictionaryEntry(manualRedactionEntry);
} else if (manualChange instanceof IdRemoval idRemoval) {
return pendingDictionaryEntryFactory.buildRemoveFromDictionary(idRemoval, findMatchingEntry(idRemoval.getAnnotationId(), matchingEntities));
} else if (manualChange instanceof ManualResizeRedaction manualResizeRedaction) {
return pendingDictionaryEntryFactory.buildResizeWithDictionary(manualResizeRedaction, findMatchingEntry(manualChange.getAnnotationId(), matchingEntities));
} else if (manualChange instanceof ManualRecategorization manualRecategorization) {
return pendingDictionaryEntryFactory.buildRecategorizeWithDictionary(manualRecategorization,
findMatchingEntry(manualChange.getAnnotationId(), matchingEntities));
} else {
throw new IllegalArgumentException(String.format("Manual change of type %s has no defined dictionary action!", manualChange.getClass()));
}
})
.toList();
entityLog.getEntityLogEntry().addAll(pendingEntries);
log.debug("EntityLog merged successfully."); log.debug("EntityLog merged successfully.");
return entityLog; return entityLog;
} }
private EntityLogEntry findMatchingEntry(String annotationId, List<EntityLogEntry> matchingEntities) {
return matchingEntities.stream()
.filter(entityLogEntry -> entityLogEntry.getId().equals(annotationId))
.findAny()
.orElseThrow(() -> new NotFoundException("No matching EntityLogEntry found for id " + annotationId));
}
private Optional<EntityLogEntry> mergeManualRedactionEntries(ManualRedactionEntry manualRedactionEntry, EntityLog entityLog, DossierEntity dossier) { private Optional<EntityLogEntry> mergeManualRedactionEntries(ManualRedactionEntry manualRedactionEntry, EntityLog entityLog, DossierEntity dossier) {
if (manualRedactionEntry.getPositions() == null || manualRedactionEntry.getPositions().isEmpty()) { if (manualRedactionEntry.getPositions() == null || manualRedactionEntry.getPositions().isEmpty()) {
@ -111,7 +158,10 @@ public class EntityLogMergeService {
if (isFalsePositive(manualRedactionEntry)) { if (isFalsePositive(manualRedactionEntry)) {
var matchingEntities = entityLog.getEntityLogEntry() var matchingEntities = entityLog.getEntityLogEntry()
.stream() .stream()
.filter(entityLogEntry -> equalPosition(manualRedactionEntry.getPositions().get(0), entityLogEntry.getPositions().get(0))) .filter(entityLogEntry -> equalPosition(manualRedactionEntry.getPositions()
.get(0),
entityLogEntry.getPositions()
.get(0)))
.toList(); .toList();
matchingEntities.forEach(matchingEntity -> mergeFalsePositive(entityLog, matchingEntity)); matchingEntities.forEach(matchingEntity -> mergeFalsePositive(entityLog, matchingEntity));
return Optional.empty(); return Optional.empty();
@ -119,12 +169,12 @@ public class EntityLogMergeService {
List<ManualChange> manualChanges = new ArrayList<>(); List<ManualChange> manualChanges = new ArrayList<>();
manualChanges.add(ManualChange.builder() manualChanges.add(ManualChange.builder()
.manualRedactionType(calculateManualRedactionType(manualRedactionEntry)) .manualRedactionType(ManualRedactionType.ADD)
.requestedDate(manualRedactionEntry.getRequestDate()) .requestedDate(manualRedactionEntry.getRequestDate())
.processedDate(null) .processedDate(null)
.userId(manualRedactionEntry.getUser()) .userId(manualRedactionEntry.getUser())
.propertyChanges(Map.of("value", manualRedactionEntry.getValue())) .propertyChanges(Map.of("value", manualRedactionEntry.getValue()))
.build()); .build());
List<Change> changes = new ArrayList<>(); List<Change> changes = new ArrayList<>();
changes.add(Change.builder().analysisNumber(entityLog.getAnalysisNumber()).dateTime(manualRedactionEntry.getRequestDate()).type(ChangeType.ADDED).build()); changes.add(Change.builder().analysisNumber(entityLog.getAnalysisNumber()).dateTime(manualRedactionEntry.getRequestDate()).type(ChangeType.ADDED).build());
@ -154,6 +204,10 @@ public class EntityLogMergeService {
.engines(Set.of(Engine.MANUAL)) .engines(Set.of(Engine.MANUAL))
.reference(new HashSet<>()) .reference(new HashSet<>())
.importedRedactionIntersections(new HashSet<>()) .importedRedactionIntersections(new HashSet<>())
.containingNodeId(Collections.emptyList())
.closestHeadline("")
.startOffset(-1)
.endOffset(-1)
.build(); .build();
entityLog.getEntityLogEntry().add(entityLogEntry); entityLog.getEntityLogEntry().add(entityLogEntry);
@ -182,25 +236,30 @@ public class EntityLogMergeService {
private void mergeIdsToRemove(IdRemoval idRemoval, List<EntityLogEntry> entityLogEntries, int analysisNumber) { private void mergeIdsToRemove(IdRemoval idRemoval, List<EntityLogEntry> entityLogEntries, int analysisNumber) {
var entity = entityLogEntries.stream().filter(entityLogEntry -> entityLogEntry.getId().equals(idRemoval.getAnnotationId())).findAny(); var entity = entityLogEntries.stream()
.filter(entityLogEntry -> entityLogEntry.getId().equals(idRemoval.getAnnotationId()))
.findAny();
entity.ifPresent(entityLogEntry -> { entity.ifPresent(entityLogEntry -> {
entityLogEntry.setState(EntryState.IGNORED); entityLogEntry.setState(EntryState.IGNORED);
entityLogEntry.getEngines().add(Engine.MANUAL); entityLogEntry.getEngines().add(Engine.MANUAL);
addChanges(entityLogEntry.getChanges(), ChangeType.REMOVED, analysisNumber, idRemoval.getRequestDate()); addChanges(entityLogEntry.getChanges(), ChangeType.REMOVED, analysisNumber, idRemoval.getRequestDate());
entityLogEntry.getManualChanges() entityLogEntry.getManualChanges()
.add(ManualChange.builder() .add(ManualChange.builder()
.manualRedactionType(idRemoval.isRemoveFromDictionary() ? ManualRedactionType.REMOVE_FROM_DICTIONARY : ManualRedactionType.REMOVE_LOCALLY) .manualRedactionType(ManualRedactionType.REMOVE)
.requestedDate(idRemoval.getRequestDate()) .requestedDate(idRemoval.getRequestDate())
.processedDate(null) .processedDate(null)
.userId(idRemoval.getUser()) .userId(idRemoval.getUser())
.build()); .propertyChanges(Collections.emptyMap())
.build());
}); });
} }
private void mergeResizeRedactions(ManualResizeRedaction manualResizeRedaction, List<EntityLogEntry> entityLogEntries, int analysisNumber) { private void mergeResizeRedactions(ManualResizeRedaction manualResizeRedaction, List<EntityLogEntry> entityLogEntries, int analysisNumber) {
var entity = entityLogEntries.stream().filter(entityLogEntry -> entityLogEntry.getId().equals(manualResizeRedaction.getAnnotationId())).findAny(); var entity = entityLogEntries.stream()
.filter(entityLogEntry -> entityLogEntry.getId().equals(manualResizeRedaction.getAnnotationId()))
.findAny();
entity.ifPresent(entityLogEntry -> { entity.ifPresent(entityLogEntry -> {
entityLogEntry.setTextAfter(manualResizeRedaction.getTextAfter()); entityLogEntry.setTextAfter(manualResizeRedaction.getTextAfter());
entityLogEntry.setTextBefore(manualResizeRedaction.getTextBefore()); entityLogEntry.setTextBefore(manualResizeRedaction.getTextBefore());
@ -209,7 +268,7 @@ public class EntityLogMergeService {
entityLogEntry.getEngines().add(Engine.MANUAL); entityLogEntry.getEngines().add(Engine.MANUAL);
addChanges(entityLogEntry.getChanges(), ChangeType.CHANGED, analysisNumber, manualResizeRedaction.getRequestDate()); addChanges(entityLogEntry.getChanges(), ChangeType.CHANGED, analysisNumber, manualResizeRedaction.getRequestDate());
ManualChange.ManualChangeBuilder manualChange = ManualChange.builder() ManualChange.ManualChangeBuilder manualChange = ManualChange.builder()
.manualRedactionType(manualResizeRedaction.getUpdateDictionary() ? ManualRedactionType.RESIZE_IN_DICTIONARY : ManualRedactionType.RESIZE) .manualRedactionType(ManualRedactionType.RESIZE)
.requestedDate(manualResizeRedaction.getRequestDate()) .requestedDate(manualResizeRedaction.getRequestDate())
.processedDate(null) .processedDate(null)
.userId(manualResizeRedaction.getUser()); .userId(manualResizeRedaction.getUser());
@ -223,7 +282,9 @@ public class EntityLogMergeService {
private void mergeLegalBasisChanges(ManualLegalBasisChange manualLegalBasisChange, List<EntityLogEntry> entityLogEntries, int analysisNumber) { private void mergeLegalBasisChanges(ManualLegalBasisChange manualLegalBasisChange, List<EntityLogEntry> entityLogEntries, int analysisNumber) {
var entity = entityLogEntries.stream().filter(entityLogEntry -> entityLogEntry.getId().equals(manualLegalBasisChange.getAnnotationId())).findAny(); var entity = entityLogEntries.stream()
.filter(entityLogEntry -> entityLogEntry.getId().equals(manualLegalBasisChange.getAnnotationId()))
.findAny();
entity.ifPresent(entityLogEntry -> { entity.ifPresent(entityLogEntry -> {
entityLogEntry.setLegalBasis(manualLegalBasisChange.getLegalBasis()); entityLogEntry.setLegalBasis(manualLegalBasisChange.getLegalBasis());
entityLogEntry.setSection(manualLegalBasisChange.getSection()); entityLogEntry.setSection(manualLegalBasisChange.getSection());
@ -233,12 +294,12 @@ public class EntityLogMergeService {
Map<String, String> propertyChanges = getPropertyChanges(manualLegalBasisChange); Map<String, String> propertyChanges = getPropertyChanges(manualLegalBasisChange);
entityLogEntry.getManualChanges() entityLogEntry.getManualChanges()
.add(ManualChange.builder() .add(ManualChange.builder()
.manualRedactionType(ManualRedactionType.LEGAL_BASIS_CHANGE) .manualRedactionType(ManualRedactionType.LEGAL_BASIS_CHANGE)
.requestedDate(manualLegalBasisChange.getRequestDate()) .requestedDate(manualLegalBasisChange.getRequestDate())
.processedDate(null) .processedDate(null)
.propertyChanges(propertyChanges) .propertyChanges(propertyChanges)
.userId(manualLegalBasisChange.getUser()) .userId(manualLegalBasisChange.getUser())
.build()); .build());
}); });
} }
@ -263,7 +324,9 @@ public class EntityLogMergeService {
private void mergeRecategorizations(ManualRecategorization recategorization, List<EntityLogEntry> entityLogEntries, DossierEntity dossier, int analysisNumber) { private void mergeRecategorizations(ManualRecategorization recategorization, List<EntityLogEntry> entityLogEntries, DossierEntity dossier, int analysisNumber) {
boolean isHint = isHint(recategorization.getType(), dossier); boolean isHint = isHint(recategorization.getType(), dossier);
var entity = entityLogEntries.stream().filter(entityLogEntry -> entityLogEntry.getId().equals(recategorization.getAnnotationId())).findAny(); var entity = entityLogEntries.stream()
.filter(entityLogEntry -> entityLogEntry.getId().equals(recategorization.getAnnotationId()))
.findAny();
entity.ifPresent(entityLogEntry -> { entity.ifPresent(entityLogEntry -> {
entityLogEntry.setType(recategorization.getType()); entityLogEntry.setType(recategorization.getType());
entityLogEntry.setEntryType(getEntryType(isHint, recategorization.getType())); entityLogEntry.setEntryType(getEntryType(isHint, recategorization.getType()));
@ -272,26 +335,28 @@ public class EntityLogMergeService {
addChanges(entityLogEntry.getChanges(), ChangeType.CHANGED, analysisNumber, recategorization.getRequestDate()); addChanges(entityLogEntry.getChanges(), ChangeType.CHANGED, analysisNumber, recategorization.getRequestDate());
entityLogEntry.getManualChanges() entityLogEntry.getManualChanges()
.add(ManualChange.builder() .add(ManualChange.builder()
.manualRedactionType(ManualRedactionType.RECATEGORIZE) .manualRedactionType(ManualRedactionType.RECATEGORIZE)
.requestedDate(recategorization.getRequestDate()) .requestedDate(recategorization.getRequestDate())
.processedDate(recategorization.getProcessedDate()) .processedDate(recategorization.getProcessedDate())
.userId(recategorization.getUser()) .userId(recategorization.getUser())
.propertyChanges(Map.of("type", recategorization.getType())) .propertyChanges(Map.of("type", recategorization.getType()))
.build()); .build());
}); });
} }
private void mergeForceRedactions(ManualForceRedaction forceRedaction, List<EntityLogEntry> entityLogEntries, int analysisNumber) { private void mergeForceRedactions(ManualForceRedaction forceRedaction, List<EntityLogEntry> entityLogEntries, int analysisNumber) {
var entity = entityLogEntries.stream().filter(entityLogEntry -> entityLogEntry.getId().equals(forceRedaction.getAnnotationId())).findAny(); var entity = entityLogEntries.stream()
.filter(entityLogEntry -> entityLogEntry.getId().equals(forceRedaction.getAnnotationId()))
.findAny();
entity.ifPresent(entityLogEntry -> { entity.ifPresent(entityLogEntry -> {
entityLogEntry.setLegalBasis(forceRedaction.getLegalBasis()); entityLogEntry.setLegalBasis(forceRedaction.getLegalBasis());
entityLogEntry.setState(entityLogEntry.getEntryType().equals(EntryType.HINT) ? EntryState.SKIPPED : EntryState.APPLIED); entityLogEntry.setState(entityLogEntry.getEntryType().equals(EntryType.HINT) ? EntryState.SKIPPED : EntryState.APPLIED);
entityLogEntry.getEngines().add(Engine.MANUAL); entityLogEntry.getEngines().add(Engine.MANUAL);
addChanges(entityLogEntry.getChanges(), ChangeType.CHANGED, analysisNumber, forceRedaction.getRequestDate()); addChanges(entityLogEntry.getChanges(), ChangeType.CHANGED, analysisNumber, forceRedaction.getRequestDate());
var forceRedactManualChange = ManualChange.builder() var forceRedactManualChange = ManualChange.builder()
.manualRedactionType(entityLogEntry.getEntryType().equals(EntryType.HINT) ? ManualRedactionType.FORCE_HINT : ManualRedactionType.FORCE_REDACT) .manualRedactionType(ManualRedactionType.FORCE)
.requestedDate(forceRedaction.getRequestDate()) .requestedDate(forceRedaction.getRequestDate())
.processedDate(forceRedaction.getProcessedDate()) .processedDate(forceRedaction.getProcessedDate())
.userId(forceRedaction.getUser()); .userId(forceRedaction.getUser());
@ -313,15 +378,6 @@ public class EntityLogMergeService {
} }
private ManualRedactionType calculateManualRedactionType(ManualRedactionEntry manualRedactionEntry) {
if (manualRedactionEntry.isAddToDictionary() || manualRedactionEntry.isAddToDossierDictionary()) {
return ManualRedactionType.ADD_TO_DICTIONARY;
}
return ManualRedactionType.ADD_LOCALLY;
}
private void addChanges(List<Change> changes, ChangeType changeType, int analysisNumber, OffsetDateTime offsetDateTime) { private void addChanges(List<Change> changes, ChangeType changeType, int analysisNumber, OffsetDateTime offsetDateTime) {
if (!changes.isEmpty()) { if (!changes.isEmpty()) {
@ -338,7 +394,10 @@ public class EntityLogMergeService {
TypeEntity typeEntity = dictionaryPersistenceService.getType(typeId); TypeEntity typeEntity = dictionaryPersistenceService.getType(typeId);
if (typeEntity == null) { if (typeEntity == null) {
var optionalType = dictionaryPersistenceService.getAllTypes(false).stream().filter(typeEntity1 -> typeEntity1.getType().equals(type)).findFirst(); var optionalType = dictionaryPersistenceService.getAllTypes(false)
.stream()
.filter(typeEntity1 -> typeEntity1.getType().equals(type))
.findFirst();
if (optionalType.isPresent()) { if (optionalType.isPresent()) {
typeEntity = optionalType.get(); typeEntity = optionalType.get();
} else { } else {
@ -352,7 +411,10 @@ public class EntityLogMergeService {
private boolean equalPosition(Rectangle position1, Position position2) { private boolean equalPosition(Rectangle position1, Position position2) {
return position1.getTopLeftX() == position2.x() && position1.getTopLeftY() == position2.y() && position1.getWidth() == position2.w() && position1.getHeight() == position2.h(); return position1.getTopLeftX() == position2.x()
&& position1.getTopLeftY() == position2.y()
&& position1.getWidth() == position2.w()
&& position1.getHeight() == position2.h();
} }
@ -364,17 +426,6 @@ public class EntityLogMergeService {
} }
private List<BaseAnnotation> allManualChanges(ManualRedactions manualRedactions) {
return Stream.of(manualRedactions.getEntriesToAdd(),
manualRedactions.getForceRedactions(),
manualRedactions.getResizeRedactions(),
manualRedactions.getRecategorizations(),
manualRedactions.getIdsToRemove(),
manualRedactions.getLegalBasisChanges()).flatMap(Collection::stream).map(baseAnnotation -> (BaseAnnotation) baseAnnotation).toList();
}
public void sendToAnalyseQueue(String fileId, DossierEntity dossier, FileModel fileModel, ManualRedactions manualRedactions) { public void sendToAnalyseQueue(String fileId, DossierEntity dossier, FileModel fileModel, ManualRedactions manualRedactions) {
var fileEntity = fileStatusPersistenceService.getStatus(fileId); var fileEntity = fileStatusPersistenceService.getStatus(fileId);

View File

@ -8,9 +8,9 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierEntity; import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierEntity;
import com.iqser.red.service.persistence.management.v1.processor.model.ManualChangesQueryOptions;
import com.iqser.red.service.persistence.management.v1.processor.service.manualredactions.ManualRedactionProviderService; import com.iqser.red.service.persistence.management.v1.processor.service.manualredactions.ManualRedactionProviderService;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLog; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLog;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogEntry; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogEntry;
@ -64,18 +64,23 @@ public class EntityLogService {
if (includeUnprocessed) { if (includeUnprocessed) {
DossierEntity dossier = dossierService.getDossierById(dossierId); DossierEntity dossier = dossierService.getDossierById(dossierId);
ManualRedactions manualRedactions = manualRedactionProviderService.getManualRedactions(fileId, true); ManualRedactions manualRedactions = manualRedactionProviderService.getManualRedactions(fileId, ManualChangesQueryOptions.unprocessedOnly());
entityLogMergeService.mergeEntityLog(manualRedactions, entityLog, dossier); entityLogMergeService.mergeEntityLog(manualRedactions, entityLog, dossier);
} }
if (fileStatus.getExcludedPages() != null && !fileStatus.getExcludedPages().isEmpty()) { if (fileStatus.getExcludedPages() != null && !fileStatus.getExcludedPages().isEmpty()) {
entityLog.getEntityLogEntry() entityLog.getEntityLogEntry()
.removeIf(entry -> entry.getPositions().stream().anyMatch(position -> fileStatus.getExcludedPages().contains(position.getPageNumber())) // .removeIf(entry -> entry.getPositions()
&& entry.getManualChanges().stream().noneMatch(m -> m.getManualRedactionType().equals(ManualRedactionType.ADD_LOCALLY))); .stream()
.anyMatch(position -> fileStatus.getExcludedPages().contains(position.getPageNumber())) //
&& entry.getManualChanges()
.stream()
.noneMatch(m -> m.getManualRedactionType().equals(ManualRedactionType.ADD)));
} }
Map<String, Integer> commentCountPerAnnotationId = commentService.getCommentCounts(fileId); Map<String, Integer> commentCountPerAnnotationId = commentService.getCommentCounts(fileId);
entityLog.getEntityLogEntry().forEach(entityLogEntry -> entityLogEntry.setNumberOfComments(commentCountPerAnnotationId.getOrDefault(entityLogEntry.getId(), 0))); entityLog.getEntityLogEntry()
.forEach(entityLogEntry -> entityLogEntry.setNumberOfComments(commentCountPerAnnotationId.getOrDefault(entityLogEntry.getId(), 0)));
return entityLog; return entityLog;
} }
@ -102,7 +107,7 @@ public class EntityLogService {
} }
for (var manualChange : redactionLogEntry.getManualChanges()) { for (var manualChange : redactionLogEntry.getManualChanges()) {
if (manualChange.getProcessedDate() != null && manualChange.getProcessedDate().isAfter(filteredEntityLogRequest.getSpecifiedDate()) || // if (manualChange.getProcessedDate() != null && manualChange.getProcessedDate().isAfter(filteredEntityLogRequest.getSpecifiedDate()) || //
manualChange.getRequestedDate() != null && manualChange.getRequestedDate().isAfter(filteredEntityLogRequest.getSpecifiedDate())) { manualChange.getRequestedDate() != null && manualChange.getRequestedDate().isAfter(filteredEntityLogRequest.getSpecifiedDate())) {
isAfterSpecifiedDate = true; isAfterSpecifiedDate = true;
break; break;
} }

View File

@ -14,6 +14,7 @@ import org.springframework.stereotype.Service;
import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException; import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException;
import com.iqser.red.service.persistence.management.v1.processor.exception.DossierNotFoundException; import com.iqser.red.service.persistence.management.v1.processor.exception.DossierNotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.model.ManualChangesQueryOptions;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.ViewedPagesPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.ViewedPagesPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.AddRedactionPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.AddRedactionPersistenceService;
@ -114,42 +115,44 @@ public class FileService {
public void softDeleteFile(String dossierId, String fileId, OffsetDateTime softDeletedTime) { public void softDeleteFile(String dossierId, String fileId, OffsetDateTime softDeletedTime) {
forceRedactionPersistenceService.findForceRedactions(fileId, false) ManualChangesQueryOptions options = ManualChangesQueryOptions.allWithoutDeleted();
forceRedactionPersistenceService.findEntriesByFileIdAndOptions(fileId, options)
.forEach(annotation -> { .forEach(annotation -> {
forceRedactionPersistenceService.softDelete(fileId, annotation.getId().getAnnotationId(), softDeletedTime); forceRedactionPersistenceService.softDelete(fileId, annotation.getId().getAnnotationId(), softDeletedTime);
commentPersistenceService.findCommentsByAnnotationId(fileId, annotation.getId().getAnnotationId(), false) commentPersistenceService.findCommentsByAnnotationId(fileId, annotation.getId().getAnnotationId(), false)
.forEach(comment -> commentPersistenceService.softDelete(comment.getId(), softDeletedTime)); .forEach(comment -> commentPersistenceService.softDelete(comment.getId(), softDeletedTime));
}); });
removeRedactionPersistenceService.findRemoveRedactions(fileId, false) removeRedactionPersistenceService.findEntriesByFileIdAndOptions(fileId, options)
.forEach(annotation -> { .forEach(annotation -> {
removeRedactionPersistenceService.softDelete(fileId, annotation.getId().getAnnotationId(), softDeletedTime); removeRedactionPersistenceService.softDelete(fileId, annotation.getId().getAnnotationId(), softDeletedTime);
commentPersistenceService.findCommentsByAnnotationId(fileId, annotation.getId().getAnnotationId(), false) commentPersistenceService.findCommentsByAnnotationId(fileId, annotation.getId().getAnnotationId(), false)
.forEach(comment -> commentPersistenceService.softDelete(comment.getId(), softDeletedTime)); .forEach(comment -> commentPersistenceService.softDelete(comment.getId(), softDeletedTime));
}); });
addRedactionPersistenceService.findAddRedactions(fileId, false) addRedactionPersistenceService.findEntriesByFileIdAndOptions(fileId, options)
.forEach(annotation -> { .forEach(annotation -> {
addRedactionPersistenceService.softDelete(fileId, annotation.getId().getAnnotationId(), softDeletedTime); addRedactionPersistenceService.softDelete(fileId, annotation.getId().getAnnotationId(), softDeletedTime);
commentPersistenceService.findCommentsByAnnotationId(fileId, annotation.getId().getAnnotationId(), false) commentPersistenceService.findCommentsByAnnotationId(fileId, annotation.getId().getAnnotationId(), false)
.forEach(comment -> commentPersistenceService.softDelete(comment.getId(), softDeletedTime)); .forEach(comment -> commentPersistenceService.softDelete(comment.getId(), softDeletedTime));
}); });
recategorizationPersistenceService.findRecategorizations(fileId, false) recategorizationPersistenceService.findEntriesByFileIdAndOptions(fileId, options)
.forEach(recatigorization -> { .forEach(recatigorization -> {
recategorizationPersistenceService.softDelete(fileId, recatigorization.getId().getAnnotationId(), softDeletedTime); recategorizationPersistenceService.softDelete(fileId, recatigorization.getId().getAnnotationId(), softDeletedTime);
commentPersistenceService.findCommentsByAnnotationId(fileId, recatigorization.getId().getAnnotationId(), false) commentPersistenceService.findCommentsByAnnotationId(fileId, recatigorization.getId().getAnnotationId(), false)
.forEach(comment -> commentPersistenceService.softDelete(comment.getId(), softDeletedTime)); .forEach(comment -> commentPersistenceService.softDelete(comment.getId(), softDeletedTime));
}); });
resizeRedactionPersistenceService.findResizeRedactions(fileId, false) resizeRedactionPersistenceService.findEntriesByFileIdAndOptions(fileId, options)
.forEach(annotation -> { .forEach(annotation -> {
resizeRedactionPersistenceService.softDelete(fileId, annotation.getId().getAnnotationId(), softDeletedTime); resizeRedactionPersistenceService.softDelete(fileId, annotation.getId().getAnnotationId(), softDeletedTime);
commentPersistenceService.findCommentsByAnnotationId(fileId, annotation.getId().getAnnotationId(), false) commentPersistenceService.findCommentsByAnnotationId(fileId, annotation.getId().getAnnotationId(), false)
.forEach(comment -> commentPersistenceService.softDelete(comment.getId(), softDeletedTime)); .forEach(comment -> commentPersistenceService.softDelete(comment.getId(), softDeletedTime));
}); });
legalBasisChangePersistenceService.findLegalBasisChanges(fileId, false) legalBasisChangePersistenceService.findEntriesByFileIdAndOptions(fileId, options)
.forEach(legalBasisChange -> { .forEach(legalBasisChange -> {
legalBasisChangePersistenceService.softDelete(fileId, legalBasisChange.getId().getAnnotationId(), softDeletedTime); legalBasisChangePersistenceService.softDelete(fileId, legalBasisChange.getId().getAnnotationId(), softDeletedTime);
commentPersistenceService.findCommentsByAnnotationId(fileId, legalBasisChange.getId().getAnnotationId(), false) commentPersistenceService.findCommentsByAnnotationId(fileId, legalBasisChange.getId().getAnnotationId(), false)
@ -187,35 +190,37 @@ public class FileService {
} }
}); });
forceRedactionPersistenceService.findForceRedactions(fileId, true) ManualChangesQueryOptions options = ManualChangesQueryOptions.all();
forceRedactionPersistenceService.findEntriesByFileIdAndOptions(fileId, options)
.forEach(annotation -> { .forEach(annotation -> {
forceRedactionPersistenceService.hardDelete(fileId, annotation.getId().getAnnotationId()); forceRedactionPersistenceService.hardDelete(fileId, annotation.getId().getAnnotationId());
commentPersistenceService.findCommentsByAnnotationId(fileId, annotation.getId().getAnnotationId(), true) commentPersistenceService.findCommentsByAnnotationId(fileId, annotation.getId().getAnnotationId(), true)
.forEach(comment -> commentPersistenceService.hardDelete(comment.getId())); .forEach(comment -> commentPersistenceService.hardDelete(comment.getId()));
}); });
removeRedactionPersistenceService.findRemoveRedactions(fileId, true) removeRedactionPersistenceService.findEntriesByFileIdAndOptions(fileId, options)
.forEach(annotation -> { .forEach(annotation -> {
removeRedactionPersistenceService.hardDelete(fileId, annotation.getId().getAnnotationId()); removeRedactionPersistenceService.hardDelete(fileId, annotation.getId().getAnnotationId());
commentPersistenceService.findCommentsByAnnotationId(fileId, annotation.getId().getAnnotationId(), true) commentPersistenceService.findCommentsByAnnotationId(fileId, annotation.getId().getAnnotationId(), true)
.forEach(comment -> commentPersistenceService.hardDelete(comment.getId())); .forEach(comment -> commentPersistenceService.hardDelete(comment.getId()));
}); });
addRedactionPersistenceService.findAddRedactions(fileId, true) addRedactionPersistenceService.findEntriesByFileIdAndOptions(fileId, options)
.forEach(annotation -> { .forEach(annotation -> {
addRedactionPersistenceService.hardDelete(fileId, annotation.getId().getAnnotationId()); addRedactionPersistenceService.hardDelete(fileId, annotation.getId().getAnnotationId());
commentPersistenceService.findCommentsByAnnotationId(fileId, annotation.getId().getAnnotationId(), true) commentPersistenceService.findCommentsByAnnotationId(fileId, annotation.getId().getAnnotationId(), true)
.forEach(comment -> commentPersistenceService.hardDelete(comment.getId())); .forEach(comment -> commentPersistenceService.hardDelete(comment.getId()));
}); });
recategorizationPersistenceService.findRecategorizations(fileId, true) recategorizationPersistenceService.findEntriesByFileIdAndOptions(fileId, options)
.forEach(recatigorization -> { .forEach(recatigorization -> {
recategorizationPersistenceService.hardDelete(fileId, recatigorization.getId().getAnnotationId()); recategorizationPersistenceService.hardDelete(fileId, recatigorization.getId().getAnnotationId());
commentPersistenceService.findCommentsByAnnotationId(fileId, recatigorization.getId().getAnnotationId(), true) commentPersistenceService.findCommentsByAnnotationId(fileId, recatigorization.getId().getAnnotationId(), true)
.forEach(comment -> commentPersistenceService.hardDelete(comment.getId())); .forEach(comment -> commentPersistenceService.hardDelete(comment.getId()));
}); });
resizeRedactionPersistenceService.findResizeRedactions(fileId, true) resizeRedactionPersistenceService.findEntriesByFileIdAndOptions(fileId, options)
.forEach(annotation -> { .forEach(annotation -> {
resizeRedactionPersistenceService.hardDelete(fileId, annotation.getId().getAnnotationId()); resizeRedactionPersistenceService.hardDelete(fileId, annotation.getId().getAnnotationId());
commentPersistenceService.findCommentsByAnnotationId(fileId, annotation.getId().getAnnotationId(), true) commentPersistenceService.findCommentsByAnnotationId(fileId, annotation.getId().getAnnotationId(), true)
@ -246,7 +251,8 @@ public class FileService {
public void undeleteFile(String dossierTemplateId, String dossierId, String fileId, OffsetDateTime softDeletedTime) { public void undeleteFile(String dossierTemplateId, String dossierId, String fileId, OffsetDateTime softDeletedTime) {
forceRedactionPersistenceService.findForceRedactions(fileId, true) ManualChangesQueryOptions options = ManualChangesQueryOptions.all();
forceRedactionPersistenceService.findEntriesByFileIdAndOptions(fileId, options)
.forEach(annotation -> { .forEach(annotation -> {
if (annotation.getSoftDeletedTime().equals(softDeletedTime) || annotation.getSoftDeletedTime().isAfter(softDeletedTime)) { if (annotation.getSoftDeletedTime().equals(softDeletedTime) || annotation.getSoftDeletedTime().isAfter(softDeletedTime)) {
forceRedactionPersistenceService.undelete(fileId, annotation.getId().getAnnotationId()); forceRedactionPersistenceService.undelete(fileId, annotation.getId().getAnnotationId());
@ -259,7 +265,7 @@ public class FileService {
} }
}); });
removeRedactionPersistenceService.findRemoveRedactions(fileId, true) removeRedactionPersistenceService.findEntriesByFileIdAndOptions(fileId, options)
.forEach(annotation -> { .forEach(annotation -> {
if (annotation.getSoftDeletedTime().equals(softDeletedTime) || annotation.getSoftDeletedTime().isAfter(softDeletedTime)) { if (annotation.getSoftDeletedTime().equals(softDeletedTime) || annotation.getSoftDeletedTime().isAfter(softDeletedTime)) {
removeRedactionPersistenceService.undelete(fileId, annotation.getId().getAnnotationId()); removeRedactionPersistenceService.undelete(fileId, annotation.getId().getAnnotationId());
@ -272,7 +278,7 @@ public class FileService {
} }
}); });
addRedactionPersistenceService.findAddRedactions(fileId, true) addRedactionPersistenceService.findEntriesByFileIdAndOptions(fileId, options)
.forEach(annotation -> { .forEach(annotation -> {
if (annotation != null && annotation.getSoftDeletedTime() != null && (annotation.getSoftDeletedTime().equals(softDeletedTime) || annotation.getSoftDeletedTime() if (annotation != null && annotation.getSoftDeletedTime() != null && (annotation.getSoftDeletedTime().equals(softDeletedTime) || annotation.getSoftDeletedTime()
.isAfter(softDeletedTime))) { .isAfter(softDeletedTime))) {
@ -286,7 +292,7 @@ public class FileService {
} }
}); });
recategorizationPersistenceService.findRecategorizations(fileId, true) recategorizationPersistenceService.findEntriesByFileIdAndOptions(fileId, options)
.forEach(recatigorization -> { .forEach(recatigorization -> {
if (recatigorization.getSoftDeletedTime().equals(softDeletedTime) || recatigorization.getSoftDeletedTime().isAfter(softDeletedTime)) { if (recatigorization.getSoftDeletedTime().equals(softDeletedTime) || recatigorization.getSoftDeletedTime().isAfter(softDeletedTime)) {
recategorizationPersistenceService.undelete(fileId, recatigorization.getId().getAnnotationId()); recategorizationPersistenceService.undelete(fileId, recatigorization.getId().getAnnotationId());
@ -299,7 +305,7 @@ public class FileService {
} }
}); });
resizeRedactionPersistenceService.findResizeRedactions(fileId, true) resizeRedactionPersistenceService.findEntriesByFileIdAndOptions(fileId, options)
.forEach(annotation -> { .forEach(annotation -> {
if (annotation.getSoftDeletedTime().equals(softDeletedTime) || annotation.getSoftDeletedTime().isAfter(softDeletedTime)) { if (annotation.getSoftDeletedTime().equals(softDeletedTime) || annotation.getSoftDeletedTime().isAfter(softDeletedTime)) {
resizeRedactionPersistenceService.undelete(fileId, annotation.getId().getAnnotationId()); resizeRedactionPersistenceService.undelete(fileId, annotation.getId().getAnnotationId());
@ -312,7 +318,7 @@ public class FileService {
} }
}); });
legalBasisChangePersistenceService.findLegalBasisChanges(fileId, true) legalBasisChangePersistenceService.findEntriesByFileIdAndOptions(fileId, options)
.forEach(annotation -> { .forEach(annotation -> {
if (annotation.getSoftDeletedTime().equals(softDeletedTime) || annotation.getSoftDeletedTime().isAfter(softDeletedTime)) { if (annotation.getSoftDeletedTime().equals(softDeletedTime) || annotation.getSoftDeletedTime().isAfter(softDeletedTime)) {
legalBasisChangePersistenceService.undelete(fileId, annotation.getId().getAnnotationId()); legalBasisChangePersistenceService.undelete(fileId, annotation.getId().getAnnotationId());

View File

@ -22,6 +22,7 @@ import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.
import com.iqser.red.service.persistence.management.v1.processor.exception.InternalServerErrorException; import com.iqser.red.service.persistence.management.v1.processor.exception.InternalServerErrorException;
import com.iqser.red.service.persistence.management.v1.processor.model.CvAnalysisServiceRequest; import com.iqser.red.service.persistence.management.v1.processor.model.CvAnalysisServiceRequest;
import com.iqser.red.service.persistence.management.v1.processor.model.FileIdentifier; import com.iqser.red.service.persistence.management.v1.processor.model.FileIdentifier;
import com.iqser.red.service.persistence.management.v1.processor.model.ManualChangesQueryOptions;
import com.iqser.red.service.persistence.management.v1.processor.model.NerServiceRequest; import com.iqser.red.service.persistence.management.v1.processor.model.NerServiceRequest;
import com.iqser.red.service.persistence.management.v1.processor.model.OCRStatusUpdateResponse; import com.iqser.red.service.persistence.management.v1.processor.model.OCRStatusUpdateResponse;
import com.iqser.red.service.persistence.management.v1.processor.model.VisualLayoutParsingServiceRequest; import com.iqser.red.service.persistence.management.v1.processor.model.VisualLayoutParsingServiceRequest;
@ -233,7 +234,7 @@ public class FileStatusService {
.analysisNumber(fileModel.getNumberOfAnalyses() + 1) .analysisNumber(fileModel.getNumberOfAnalyses() + 1)
.sectionsToReanalyse(sectionsToReanalyse) .sectionsToReanalyse(sectionsToReanalyse)
.fileId(fileId) .fileId(fileId)
.manualRedactions(manualRedactionProviderService.getManualRedactions(fileId)) .manualRedactions(manualRedactionProviderService.getManualRedactions(fileId, ManualChangesQueryOptions.allWithoutDeleted()))
.dossierTemplateId(dossier.getDossierTemplateId()) .dossierTemplateId(dossier.getDossierTemplateId())
.lastProcessed(fileModel.getLastProcessed()) .lastProcessed(fileModel.getLastProcessed())
.fileAttributes(convertAttributes(fileEntity.getFileAttributes(), dossier.getDossierTemplateId())) .fileAttributes(convertAttributes(fileEntity.getFileAttributes(), dossier.getDossierTemplateId()))
@ -717,27 +718,28 @@ public class FileStatusService {
comments.forEach((key, value) -> value.forEach(comment -> commentPersistenceService.softDelete(comment.getId(), now))); comments.forEach((key, value) -> value.forEach(comment -> commentPersistenceService.softDelete(comment.getId(), now)));
// wipe force redactions // wipe force redactions
var forceRedactions = forceRedactionPersistenceService.findForceRedactions(fileId, false); ManualChangesQueryOptions options = ManualChangesQueryOptions.allWithoutDeleted();
var forceRedactions = forceRedactionPersistenceService.findEntriesByFileIdAndOptions(fileId, options);
forceRedactions.forEach(f -> forceRedactionPersistenceService.softDelete(fileId, f.getId().getAnnotationId(), now)); forceRedactions.forEach(f -> forceRedactionPersistenceService.softDelete(fileId, f.getId().getAnnotationId(), now));
// wipe add manual redactions // wipe add manual redactions
var addRedactions = addRedactionPersistenceService.findAddRedactions(fileId, false); var addRedactions = addRedactionPersistenceService.findEntriesByFileIdAndOptions(fileId, options);
addRedactions.forEach(f -> addRedactionPersistenceService.softDelete(fileId, f.getId().getAnnotationId(), now)); addRedactions.forEach(f -> addRedactionPersistenceService.softDelete(fileId, f.getId().getAnnotationId(), now));
// wipe removeRedactions // wipe removeRedactions
var removeRedactions = removeRedactionPersistenceService.findRemoveRedactions(fileId, false); var removeRedactions = removeRedactionPersistenceService.findEntriesByFileIdAndOptions(fileId, options);
removeRedactions.forEach(f -> removeRedactionPersistenceService.softDelete(fileId, f.getId().getAnnotationId(), now)); removeRedactions.forEach(f -> removeRedactionPersistenceService.softDelete(fileId, f.getId().getAnnotationId(), now));
// wipe image recat // wipe image recat
var imageRecategorizations = recategorizationPersistenceService.findRecategorizations(fileId, false); var imageRecategorizations = recategorizationPersistenceService.findEntriesByFileIdAndOptions(fileId, options);
imageRecategorizations.forEach(f -> recategorizationPersistenceService.softDelete(fileId, f.getId().getAnnotationId(), now));// wipe image recat imageRecategorizations.forEach(f -> recategorizationPersistenceService.softDelete(fileId, f.getId().getAnnotationId(), now));// wipe image recat
// wipe resize redactions // wipe resize redactions
var resizeRedactions = resizeRedactionPersistenceService.findResizeRedactions(fileId, false); var resizeRedactions = resizeRedactionPersistenceService.findEntriesByFileIdAndOptions(fileId, options);
resizeRedactions.forEach(f -> resizeRedactionPersistenceService.softDelete(fileId, f.getId().getAnnotationId(), now)); resizeRedactions.forEach(f -> resizeRedactionPersistenceService.softDelete(fileId, f.getId().getAnnotationId(), now));
// wipe legal basis changes // wipe legal basis changes
var legalBasisChanges = legalBasisChangePersistenceService.findLegalBasisChanges(fileId, false); var legalBasisChanges = legalBasisChangePersistenceService.findEntriesByFileIdAndOptions(fileId, options);
legalBasisChanges.forEach(f -> legalBasisChangePersistenceService.softDelete(fileId, f.getId().getAnnotationId(), now)); legalBasisChanges.forEach(f -> legalBasisChangePersistenceService.softDelete(fileId, f.getId().getAnnotationId(), now));
fileStatusPersistenceService.updateHasComments(fileId, false); fileStatusPersistenceService.updateHasComments(fileId, false);

View File

@ -2,6 +2,7 @@ package com.iqser.red.service.persistence.management.v1.processor.service.manual
import static com.knecon.fforesight.databasetenantcommons.providers.utils.MagicConverter.convert; import static com.knecon.fforesight.databasetenantcommons.providers.utils.MagicConverter.convert;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -13,6 +14,7 @@ import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualRedactionEntryEntity; import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualRedactionEntryEntity;
import com.iqser.red.service.persistence.management.v1.processor.model.ManualChangesQueryOptions;
import com.iqser.red.service.persistence.management.v1.processor.service.CommentService; import com.iqser.red.service.persistence.management.v1.processor.service.CommentService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.AddRedactionPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.AddRedactionPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.ForceRedactionPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.ForceRedactionPersistenceService;
@ -49,13 +51,7 @@ public class ManualRedactionProviderService {
@Transactional @Transactional
public ManualRedactions getManualRedactions(String fileId) { public ManualRedactions getManualRedactions(String fileId, ManualChangesQueryOptions options) {
return getManualRedactions(fileId, false);
}
public ManualRedactions getManualRedactions(String fileId, boolean unprocessed) {
Set<ManualRedactionEntry> entriesToAdd; Set<ManualRedactionEntry> entriesToAdd;
Set<IdRemoval> removals; Set<IdRemoval> removals;
@ -64,37 +60,50 @@ public class ManualRedactionProviderService {
Set<ManualLegalBasisChange> legalBasisChanges; Set<ManualLegalBasisChange> legalBasisChanges;
Set<ManualResizeRedaction> resizeRedactions; Set<ManualResizeRedaction> resizeRedactions;
if (unprocessed) { if (!options.getExcludedClasses().contains(ManualRedactionEntry.class)) {
entriesToAdd = convertEntriesToAdd(addRedactionPersistenceService.findUnprocessedRedactions(fileId)); entriesToAdd = new HashSet<>(convert(addRedactionPersistenceService.findEntriesByFileIdAndOptions(fileId, options),
removals = convert(removeRedactionPersistenceService.findUnprocessedRemoveRedactions(fileId), IdRemoval.class); ManualRedactionEntry.class,
forceRedactions = convert(forceRedactionPersistenceService.findUnprocessedForceRedactions(fileId), ManualForceRedaction.class); new ManualRedactionMapper()));
recategorizations = new HashSet<>(convert(recategorizationPersistenceService.findUnprocessedRecategorizations(fileId),
ManualRecategorization.class,
new ManualRecategorizationMapper()));
legalBasisChanges = convert(legalBasisChangePersistenceService.findUnprocessedLegalBasisChanges(fileId), ManualLegalBasisChange.class);
resizeRedactions = new HashSet<>(convert(resizeRedactionPersistenceService.findUnprocessedResizeRedactions(fileId),
ManualResizeRedaction.class,
new ManualResizeRedactionMapper()));
} else { } else {
entriesToAdd = convertEntriesToAdd(addRedactionPersistenceService.findAddRedactions(fileId, false)); entriesToAdd = Collections.emptySet();
removals = convert(removeRedactionPersistenceService.findRemoveRedactions(fileId, false), IdRemoval.class); }
forceRedactions = convert(forceRedactionPersistenceService.findForceRedactions(fileId, false), ManualForceRedaction.class);
recategorizations = new HashSet<>(convert(recategorizationPersistenceService.findRecategorizations(fileId, false), if (!options.getExcludedClasses().contains(ManualRecategorization.class)) {
ManualRecategorization.class, recategorizations = new HashSet<>(convert(recategorizationPersistenceService.findEntriesByFileIdAndOptions(fileId, options),
new ManualRecategorizationMapper())); ManualRecategorization.class,
legalBasisChanges = convert(legalBasisChangePersistenceService.findLegalBasisChanges(fileId, false), ManualLegalBasisChange.class); new ManualRecategorizationMapper()));
resizeRedactions = new HashSet<>(convert(resizeRedactionPersistenceService.findResizeRedactions(fileId, false), } else {
ManualResizeRedaction.class, recategorizations = Collections.emptySet();
new ManualResizeRedactionMapper())); }
if (!options.getExcludedClasses().contains(ManualResizeRedaction.class)) {
resizeRedactions = new HashSet<>(convert(resizeRedactionPersistenceService.findEntriesByFileIdAndOptions(fileId, options),
ManualResizeRedaction.class,
new ManualResizeRedactionMapper()));
} else {
resizeRedactions = Collections.emptySet();
}
if (!options.getExcludedClasses().contains(IdRemoval.class)) {
removals = new HashSet<>(convert(removeRedactionPersistenceService.findEntriesByFileIdAndOptions(fileId, options), IdRemoval.class));
} else {
removals = Collections.emptySet();
}
if (!options.getExcludedClasses().contains(ManualForceRedaction.class)) {
forceRedactions = new HashSet<>(convert(forceRedactionPersistenceService.findEntriesByFileIdAndOptions(fileId, options), ManualForceRedaction.class));
} else {
forceRedactions = Collections.emptySet();
}
if (!options.getExcludedClasses().contains(ManualLegalBasisChange.class)) {
legalBasisChanges = new HashSet<>(convert(legalBasisChangePersistenceService.findEntriesByFileIdAndOptions(fileId, options), ManualLegalBasisChange.class));
} else {
legalBasisChanges = Collections.emptySet();
} }
return new ManualRedactions(removals, entriesToAdd, forceRedactions, recategorizations, legalBasisChanges, resizeRedactions); return new ManualRedactions(removals, entriesToAdd, forceRedactions, recategorizations, legalBasisChanges, resizeRedactions);
}
private Set<ManualRedactionEntry> convertEntriesToAdd(List<ManualRedactionEntryEntity> source) {
return source.stream().map(entry -> convert(entry, ManualRedactionEntry.class, new ManualRedactionMapper())).collect(Collectors.toSet());
} }

View File

@ -21,6 +21,7 @@ import com.iqser.red.service.persistence.management.v1.processor.entity.annotati
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.RectangleEntity; import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.RectangleEntity;
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException; import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.model.ManualChangesQueryOptions;
import com.iqser.red.service.persistence.management.v1.processor.service.CommentService; import com.iqser.red.service.persistence.management.v1.processor.service.CommentService;
import com.iqser.red.service.persistence.management.v1.processor.service.EntityLogMergeService; import com.iqser.red.service.persistence.management.v1.processor.service.EntityLogMergeService;
import com.iqser.red.service.persistence.management.v1.processor.service.EntityLogService; import com.iqser.red.service.persistence.management.v1.processor.service.EntityLogService;
@ -110,13 +111,13 @@ public class ManualRedactionService {
response.add(ManualAddResponse.builder().annotationId(annotationId).commentId(commentId).build()); response.add(ManualAddResponse.builder().annotationId(annotationId).commentId(commentId).build());
} }
manualRedactionEntryEntities = manualRedactionEntryEntities.stream() var localManualRedactionEntryEntities = manualRedactionEntryEntities.stream()
.filter(manualRedactionEntry -> !manualRedactionEntry.isAddToDictionary() && !manualRedactionEntry.isAddToDossierDictionary()) .filter(manualRedactionEntry -> !manualRedactionEntry.isAddToDictionary() && !manualRedactionEntry.isAddToAllDossiers())
.collect(Collectors.toList()); .collect(Collectors.toList());
FileModel fileStatus = fileStatusService.getStatus(fileId); FileModel fileStatus = fileStatusService.getStatus(fileId);
if (!manualRedactionEntryEntities.isEmpty() && fileStatus.isExcludedFromAutomaticAnalysis()) { if (!localManualRedactionEntryEntities.isEmpty() && fileStatus.isExcludedFromAutomaticAnalysis()) {
ManualRedactions manualRedactions = ManualRedactions.builder().entriesToAdd(convertEntriesToAdd(manualRedactionEntryEntities)).build(); ManualRedactions manualRedactions = ManualRedactions.builder().entriesToAdd(convertEntriesToAdd(localManualRedactionEntryEntities)).build();
entityLogMergeService.sendToAnalyseQueue(fileId, dossierEntity, fileStatusService.getStatus(fileId), manualRedactions); entityLogMergeService.sendToAnalyseQueue(fileId, dossierEntity, fileStatusService.getStatus(fileId), manualRedactions);
} else { } else {
reprocess(dossierId, fileId); reprocess(dossierId, fileId);
@ -353,9 +354,9 @@ public class ManualRedactionService {
} }
public ManualRedactions getManualRedactions(String fileId, boolean unprocessed) { public ManualRedactions getManualRedactions(String fileId, ManualChangesQueryOptions options) {
return manualRedactionProviderService.getManualRedactions(fileId, unprocessed); return manualRedactionProviderService.getManualRedactions(fileId, options);
} }
@ -364,54 +365,42 @@ public class ManualRedactionService {
if (manualRedactions != null) { if (manualRedactions != null) {
if (manualRedactions.getEntriesToAdd() != null) { manualRedactions.getEntriesToAdd()
manualRedactions.getEntriesToAdd() .forEach(e -> {
.forEach(e -> { if (e.getProcessedDate() == null) {
if (e.getProcessedDate() == null) { addRedactionPersistenceService.markAsProcessed(e);
addRedactionPersistenceService.markAsProcessed(e); }
} });
}); manualRedactions.getIdsToRemove()
} .forEach(e -> {
if (manualRedactions.getIdsToRemove() != null) { if (e.getProcessedDate() == null) {
manualRedactions.getIdsToRemove() removeRedactionPersistenceService.markAsProcessed(e);
.forEach(e -> { }
if (e.getProcessedDate() == null) { });
removeRedactionPersistenceService.markAsProcessed(e); manualRedactions.getForceRedactions()
} .forEach(e -> {
}); if (e.getProcessedDate() == null) {
} forceRedactionPersistenceService.markAsProcessed(e.getAnnotationId(), e.getFileId());
if (manualRedactions.getForceRedactions() != null) { }
manualRedactions.getForceRedactions() });
.forEach(e -> { manualRedactions.getRecategorizations()
if (e.getProcessedDate() == null) { .forEach(e -> {
forceRedactionPersistenceService.markAsProcessed(e.getAnnotationId(), e.getFileId()); if (e.getProcessedDate() == null) {
} recategorizationPersistenceService.markAsProcessed(e.getAnnotationId(), e.getFileId());
}); }
} });
if (manualRedactions.getRecategorizations() != null) { manualRedactions.getResizeRedactions()
manualRedactions.getRecategorizations() .forEach(e -> {
.forEach(e -> { if (e.getProcessedDate() == null) {
if (e.getProcessedDate() == null) { resizeRedactionPersistenceService.markAsProcessed(e.getAnnotationId(), e.getFileId());
recategorizationPersistenceService.markAsProcessed(e.getAnnotationId(), e.getFileId()); }
} });
}); manualRedactions.getLegalBasisChanges()
} .forEach(e -> {
if (manualRedactions.getResizeRedactions() != null) { if (e.getProcessedDate() == null) {
manualRedactions.getResizeRedactions() legalBasisChangePersistenceService.markAsProcessed(e.getAnnotationId(), e.getFileId());
.forEach(e -> { }
if (e.getProcessedDate() == null) { });
resizeRedactionPersistenceService.markAsProcessed(e.getAnnotationId(), e.getFileId());
}
});
}
if (manualRedactions.getLegalBasisChanges() != null) {
manualRedactions.getLegalBasisChanges()
.forEach(e -> {
if (e.getProcessedDate() == null) {
legalBasisChangePersistenceService.markAsProcessed(e.getAnnotationId(), e.getFileId());
}
});
}
} }
} }

View File

@ -21,6 +21,7 @@ import com.iqser.red.service.persistence.management.v1.processor.entity.annotati
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualRecategorizationEntity; import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualRecategorizationEntity;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualRedactionEntryEntity; import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualRedactionEntryEntity;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.model.ManualChangesQueryOptions;
import com.iqser.red.service.persistence.management.v1.processor.service.EntityLogService; import com.iqser.red.service.persistence.management.v1.processor.service.EntityLogService;
import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusService; import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService;
@ -96,7 +97,7 @@ public class ManualRedactionUndoService {
private ManualRedactions getManualRedactions(String fileId) { private ManualRedactions getManualRedactions(String fileId) {
return manualRedactionProviderService.getManualRedactions(fileId); return manualRedactionProviderService.getManualRedactions(fileId, ManualChangesQueryOptions.allWithoutDeleted());
} }

View File

@ -0,0 +1,197 @@
package com.iqser.red.service.persistence.management.v1.processor.service.manualredactions;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.Engine;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogEntry;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryState;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.ManualChange;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.ManualRedactionType;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.Position;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.Rectangle;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.IdRemoval;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualRecategorization;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualRedactionEntry;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualResizeRedaction;
@Service
public class PendingDictionaryEntryFactory {
public EntityLogEntry buildAddToDictionaryEntry(ManualRedactionEntry manualRedactionEntry) {
var manualChanges = List.of(ManualChange.builder()
.manualRedactionType(ManualRedactionType.ADD_TO_DICTIONARY)
.requestedDate(manualRedactionEntry.getRequestDate())
.processedDate(null)
.userId(manualRedactionEntry.getUser())
.propertyChanges(Map.of("value", manualRedactionEntry.getValue()))
.build());
return EntityLogEntry.builder()
.id(manualRedactionEntry.getAnnotationId())
.value(manualRedactionEntry.getValue())
.type(manualRedactionEntry.getType())
.entryType(manualRedactionEntry.getDictionaryEntryType().toEntryType())
.state(EntryState.PENDING)
.dictionaryEntry(manualRedactionEntry.isAddToDictionary())
.dossierDictionaryEntry(manualRedactionEntry.isAddToDossierDictionary())
.reason("Pending add to dictionary.")
.legalBasis("Pending add to dictionary.")
.matchedRule("")
.containingNodeId(Collections.emptyList())
.closestHeadline("")
.section("")
.positions(convertPositions(manualRedactionEntry.getPositions()))
.textAfter("")
.textBefore("")
.startOffset(-1)
.endOffset(-1)
.changes(Collections.emptyList())
.manualChanges(manualChanges)
.engines(Set.of(Engine.DICTIONARY))
.reference(Collections.emptySet())
.importedRedactionIntersections(Collections.emptySet())
.build();
}
private List<Position> convertPositions(List<Rectangle> rectangles) {
return rectangles.stream()
.map(rectangle -> new Position(rectangle.getTopLeftX(), rectangle.getTopLeftY(), rectangle.getWidth(), rectangle.getHeight(), rectangle.getPage()))
.collect(Collectors.toList());
}
public EntityLogEntry buildRemoveFromDictionary(IdRemoval manualChange, EntityLogEntry originalEntry) {
var manualChanges = List.of(ManualChange.builder()
.manualRedactionType(ManualRedactionType.REMOVE_FROM_DICTIONARY)
.requestedDate(manualChange.getRequestDate())
.processedDate(manualChange.getProcessedDate())
.userId(manualChange.getUser())
.propertyChanges(Map.of("remove", originalEntry.getValue()))
.build());
return EntityLogEntry.builder()
.id(originalEntry.getId())
.value(originalEntry.getValue())
.type(originalEntry.getType())
.entryType(originalEntry.getEntryType())
.state(EntryState.PENDING)
.dictionaryEntry(manualChange.isRemoveFromDictionary())
.dossierDictionaryEntry(!manualChange.isRemoveFromAllDossiers())
.reason("Pending remove from dictionary.")
.legalBasis("Pending remove from dictionary.")
.matchedRule("")
.containingNodeId(Collections.emptyList())
.closestHeadline("")
.section("")
.positions(originalEntry.getPositions())
.textAfter("")
.textBefore("")
.startOffset(-1)
.endOffset(-1)
.changes(Collections.emptyList())
.manualChanges(manualChanges)
.engines(Set.of(Engine.DICTIONARY))
.reference(Collections.emptySet())
.importedRedactionIntersections(Collections.emptySet())
.build();
}
public EntityLogEntry buildResizeWithDictionary(ManualResizeRedaction manualChange, EntityLogEntry originalEntry) {
Map<String, String> propertyChanges = buildPropertyChangesForManualResize(manualChange, originalEntry);
var manualChanges = List.of(ManualChange.builder()
.manualRedactionType(ManualRedactionType.RESIZE_IN_DICTIONARY)
.requestedDate(manualChange.getRequestDate())
.processedDate(manualChange.getProcessedDate())
.userId(manualChange.getUser())
.propertyChanges(propertyChanges)
.build());
return EntityLogEntry.builder()
.id(originalEntry.getId())
.value(manualChange.getValue())
.type(originalEntry.getType())
.entryType(originalEntry.getEntryType())
.state(EntryState.PENDING)
.dictionaryEntry(manualChange.getUpdateDictionary())
.dossierDictionaryEntry(!manualChange.isAddToAllDossiers())
.reason("Pending resize with dictionary.")
.legalBasis("Pending resize with dictionary.")
.matchedRule("")
.containingNodeId(Collections.emptyList())
.closestHeadline("")
.section("")
.positions(convertPositions(manualChange.getPositions()))
.textAfter("")
.textBefore("")
.startOffset(-1)
.endOffset(-1)
.changes(Collections.emptyList())
.manualChanges(manualChanges)
.engines(Set.of(Engine.DICTIONARY))
.reference(Collections.emptySet())
.importedRedactionIntersections(Collections.emptySet())
.build();
}
private static Map<String, String> buildPropertyChangesForManualResize(ManualResizeRedaction manualChange, EntityLogEntry originalEntry) {
Map<String, String> prop;
if (manualChange.getValue().length() >= originalEntry.getValue().length()) {
prop = Map.of("add", manualChange.getValue());
} else {
prop = Map.of("add", manualChange.getValue(), "remove", originalEntry.getValue());
}
return prop;
}
public EntityLogEntry buildRecategorizeWithDictionary(ManualRecategorization manualChange, EntityLogEntry originalEntry) {
var manualChanges = List.of(ManualChange.builder()
.manualRedactionType(ManualRedactionType.RECATEGORIZE_IN_DICTIONARY)
.requestedDate(manualChange.getRequestDate())
.processedDate(manualChange.getProcessedDate())
.userId(manualChange.getUser())
.propertyChanges(Map.of("type", manualChange.getType()))
.build());
return EntityLogEntry.builder()
.id(originalEntry.getId())
.value(originalEntry.getValue())
.type(manualChange.getType())
.entryType(originalEntry.getEntryType())
.state(EntryState.PENDING)
.dictionaryEntry(manualChange.isAddToDictionary())
.dossierDictionaryEntry(!manualChange.isAddToAllDossiers())
.reason("Pending recategorize with dictionary.")
.legalBasis("Pending recategorize with dictionary.")
.matchedRule("")
.containingNodeId(Collections.emptyList())
.closestHeadline("")
.section("")
.positions(originalEntry.getPositions())
.textAfter("")
.textBefore("")
.startOffset(-1)
.endOffset(-1)
.changes(Collections.emptyList())
.manualChanges(manualChanges)
.engines(Set.of(Engine.DICTIONARY))
.reference(Collections.emptySet())
.importedRedactionIntersections(Collections.emptySet())
.build();
}
}

View File

@ -15,6 +15,7 @@ import com.iqser.red.service.persistence.management.v1.processor.entity.annotati
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualRedactionEntryEntity; import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualRedactionEntryEntity;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.RectangleEntity; import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.RectangleEntity;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.model.ManualChangesQueryOptions;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.ManualRedactionRepository; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.ManualRedactionRepository;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.AddRedactionRequest; import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.AddRedactionRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.Rectangle; import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.Rectangle;
@ -79,9 +80,9 @@ public class AddRedactionPersistenceService {
} }
public List<ManualRedactionEntryEntity> findAddRedactions(String fileId, boolean includeDeletions) { public List<ManualRedactionEntryEntity> findEntriesByFileIdAndOptions(String fileId, ManualChangesQueryOptions options) {
return manualRedactionRepository.findByFileIdIncludeDeletions(fileId, includeDeletions); return manualRedactionRepository.findByFileIdAndOptions(fileId, options.isIncludeDeletions(), options.isIncludeOnlyUnprocessed(), options.isIncludeDictChanges());
} }
@ -91,12 +92,6 @@ public class AddRedactionPersistenceService {
} }
public List<ManualRedactionEntryEntity> findUnprocessedRedactions(String fileId) {
return manualRedactionRepository.findByFileIdAndUnprocessed(fileId);
}
@Transactional @Transactional
public void hardDelete(String fileId, String annotationId) { public void hardDelete(String fileId, String annotationId) {

View File

@ -3,6 +3,7 @@ package com.iqser.red.service.persistence.management.v1.processor.service.persis
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
@ -12,6 +13,7 @@ import org.springframework.transaction.annotation.Transactional;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.AnnotationEntityId; import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.AnnotationEntityId;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualForceRedactionEntity; import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualForceRedactionEntity;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.model.ManualChangesQueryOptions;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.ForceRedactionRepository; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.ForceRedactionRepository;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ForceRedactionRequest; import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ForceRedactionRequest;
@ -35,6 +37,10 @@ public class ForceRedactionPersistenceService {
forceRedactionRepository.saveAndFlush(manualForceRedaction); forceRedactionRepository.saveAndFlush(manualForceRedaction);
} }
public List<ManualForceRedactionEntity> findEntriesByFileIdAndOptions(String fileId, ManualChangesQueryOptions options) {
return forceRedactionRepository.findByFileIdAndOptions(fileId, options.isIncludeDeletions(), options.isIncludeOnlyUnprocessed());
}
@Transactional @Transactional
public void hardDelete(String fileId, String annotationId) { public void hardDelete(String fileId, String annotationId) {
@ -64,13 +70,13 @@ public class ForceRedactionPersistenceService {
} }
public Set<ManualForceRedactionEntity> findForceRedactions(String fileId, boolean includeDeletions) { public Set<ManualForceRedactionEntity> findForceRedactions(String fileId, boolean includeDeletions, boolean includeDictChanges) {
return new HashSet<>(forceRedactionRepository.findByFileIdIncludeDeletions(fileId, includeDeletions)); return new HashSet<>(forceRedactionRepository.findByFileIdIncludeDeletions(fileId, includeDeletions));
} }
public Set<ManualForceRedactionEntity> findUnprocessedForceRedactions(String fileId) { public Set<ManualForceRedactionEntity> findUnprocessedForceRedactions(String fileId, boolean includeDictChanges) {
return new HashSet<>(forceRedactionRepository.findByFileIdAndUnprocessed(fileId)); return new HashSet<>(forceRedactionRepository.findByFileIdAndUnprocessed(fileId));
} }

View File

@ -3,6 +3,7 @@ package com.iqser.red.service.persistence.management.v1.processor.service.persis
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -14,6 +15,7 @@ import com.iqser.red.service.persistence.management.v1.processor.entity.annotati
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualLegalBasisChangeEntity; import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualLegalBasisChangeEntity;
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException; import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.model.ManualChangesQueryOptions;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.LegalBasisChangeRepository; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.LegalBasisChangeRepository;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.LegalBasisChangeRequest; import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.LegalBasisChangeRequest;
@ -78,7 +80,7 @@ public class LegalBasisChangePersistenceService {
} }
public Set<ManualLegalBasisChangeEntity> findLegalBasisChanges(String fileId, boolean includeDeletions) { public Set<ManualLegalBasisChangeEntity> findLegalBasisChanges(String fileId, boolean includeDeletions, boolean includeDictChanges) {
return new HashSet<>(legalBasisChangeRepository.findByFileIdIncludeDeletions(fileId, includeDeletions)); return new HashSet<>(legalBasisChangeRepository.findByFileIdIncludeDeletions(fileId, includeDeletions));
} }
@ -95,4 +97,9 @@ public class LegalBasisChangePersistenceService {
legalBasisChangeRepository.markAsProcessed(new AnnotationEntityId(annotationId, fileId), OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); legalBasisChangeRepository.markAsProcessed(new AnnotationEntityId(annotationId, fileId), OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
} }
public List<ManualLegalBasisChangeEntity> findEntriesByFileIdAndOptions(String fileId, ManualChangesQueryOptions options) {
return legalBasisChangeRepository.findByFileIdAndOptions(fileId, options.isIncludeDeletions(), options.isIncludeOnlyUnprocessed());
}
} }

View File

@ -12,6 +12,7 @@ import org.springframework.transaction.annotation.Transactional;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.AnnotationEntityId; import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.AnnotationEntityId;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualRecategorizationEntity; import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualRecategorizationEntity;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.model.ManualChangesQueryOptions;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.RecategorizationRepository; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.RecategorizationRepository;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.RecategorizationRequest; import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.RecategorizationRequest;
@ -79,13 +80,19 @@ public class RecategorizationPersistenceService {
} }
public List<ManualRecategorizationEntity> findRecategorizations(String fileId, boolean includeDeletions) { public List<ManualRecategorizationEntity> findRecategorizations(String fileId, boolean includeDeletions, boolean includeDictChanges) {
return recategorizationRepository.findByFileIdIncludeDeletions(fileId, includeDeletions); return recategorizationRepository.findByFileIdIncludeDeletions(fileId, includeDeletions);
} }
public List<ManualRecategorizationEntity> findUnprocessedRecategorizations(String fileId) { public List<ManualRecategorizationEntity> findEntriesByFileIdAndOptions(String fileId, ManualChangesQueryOptions options) {
return recategorizationRepository.findByFileIdAndOptions(fileId, options.isIncludeDeletions(), options.isIncludeOnlyUnprocessed(), options.isIncludeDictChanges());
}
public List<ManualRecategorizationEntity> findUnprocessedRecategorizations(String fileId, boolean includeDictChanges) {
return recategorizationRepository.findUnprocessedByFileId(fileId); return recategorizationRepository.findUnprocessedByFileId(fileId);
} }

View File

@ -13,6 +13,7 @@ import org.springframework.transaction.annotation.Transactional;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.AnnotationEntityId; import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.AnnotationEntityId;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.IdRemovalEntity; import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.IdRemovalEntity;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.model.ManualChangesQueryOptions;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.RemoveRedactionRepository; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.RemoveRedactionRepository;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.RemoveRedactionRequest; import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.RemoveRedactionRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.IdRemoval; import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.IdRemoval;
@ -47,13 +48,13 @@ public class RemoveRedactionPersistenceService {
} }
public Set<IdRemovalEntity> findRemoveRedactions(String fileId, boolean includeDeletions) { public Set<IdRemovalEntity> findRemoveRedactions(String fileId, boolean includeDeletions, boolean includeDictChanges) {
return new HashSet<>(removeRedactionRepository.findByFileIdIncludeDeletions(fileId, includeDeletions)); return new HashSet<>(removeRedactionRepository.findByFileIdIncludeDeletions(fileId, includeDeletions));
} }
public Set<IdRemovalEntity> findUnprocessedRemoveRedactions(String fileId) { public Set<IdRemovalEntity> findUnprocessedRemoveRedactions(String fileId, boolean includeDictChanges) {
return new HashSet<>(removeRedactionRepository.findByFileIdAndUnprocessed(fileId)); return new HashSet<>(removeRedactionRepository.findByFileIdAndUnprocessed(fileId));
} }
@ -64,6 +65,10 @@ public class RemoveRedactionPersistenceService {
return removeRedactionRepository.findAll(); return removeRedactionRepository.findAll();
} }
public List<IdRemovalEntity> findEntriesByFileIdAndOptions(String fileId, ManualChangesQueryOptions options) {
return removeRedactionRepository.findByFileIdAndOptions(fileId, options.isIncludeDeletions(), options.isIncludeOnlyUnprocessed(), options.isIncludeDictChanges());
}
@Transactional @Transactional
public void hardDelete(String fileId, String annotationId) { public void hardDelete(String fileId, String annotationId) {

View File

@ -14,6 +14,7 @@ import com.iqser.red.service.persistence.management.v1.processor.entity.annotati
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualResizeRedactionEntity; import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualResizeRedactionEntity;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.RectangleEntity; import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.RectangleEntity;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.model.ManualChangesQueryOptions;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.ResizeRedactionRepository; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.ResizeRedactionRepository;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ResizeRedactionRequest; import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ResizeRedactionRequest;
import com.knecon.fforesight.databasetenantcommons.providers.utils.MagicConverter; import com.knecon.fforesight.databasetenantcommons.providers.utils.MagicConverter;
@ -86,13 +87,14 @@ public class ResizeRedactionPersistenceService {
.orElseThrow(() -> new NotFoundException("Unknown file/annotation combination: " + fileId + "/" + annotationId)); .orElseThrow(() -> new NotFoundException("Unknown file/annotation combination: " + fileId + "/" + annotationId));
} }
public Optional<ManualResizeRedactionEntity> findResizeRedactionById(String fileId, String annotationId) { public Optional<ManualResizeRedactionEntity> findResizeRedactionById(String fileId, String annotationId) {
return resizeRedactionRepository.findById(new AnnotationEntityId(annotationId, fileId)); return resizeRedactionRepository.findById(new AnnotationEntityId(annotationId, fileId));
} }
public List<ManualResizeRedactionEntity> findResizeRedactions(String fileId, boolean includeDeletions) { public List<ManualResizeRedactionEntity> findResizeRedactions(String fileId, boolean includeDeletions, boolean includeDictChanges) {
return resizeRedactionRepository.findByFileIdIncludeDeletions(fileId, includeDeletions); return resizeRedactionRepository.findByFileIdIncludeDeletions(fileId, includeDeletions);
} }
@ -115,4 +117,10 @@ public class ResizeRedactionPersistenceService {
resizeRedactionRepository.markAsProcessed(new AnnotationEntityId(annotationId, fileId), OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); resizeRedactionRepository.markAsProcessed(new AnnotationEntityId(annotationId, fileId), OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
} }
public List<ManualResizeRedactionEntity> findEntriesByFileIdAndOptions(String fileId, ManualChangesQueryOptions options) {
return resizeRedactionRepository.findByFileIdAndOptions(fileId, options.isIncludeDeletions(), options.isIncludeOnlyUnprocessed(), options.isIncludeDictChanges());
}
} }

View File

@ -35,4 +35,14 @@ public interface ForceRedactionRepository extends JpaRepository<ManualForceRedac
@Query("update ManualForceRedactionEntity mfr set mfr.processedDate = :processedDate where mfr.id = :annotationEntityId") @Query("update ManualForceRedactionEntity mfr set mfr.processedDate = :processedDate where mfr.id = :annotationEntityId")
void markAsProcessed(@Param("annotationEntityId") AnnotationEntityId annotationEntityId, @Param("processedDate") OffsetDateTime processedDate); void markAsProcessed(@Param("annotationEntityId") AnnotationEntityId annotationEntityId, @Param("processedDate") OffsetDateTime processedDate);
@Query("""
select m
from ManualForceRedactionEntity m
where m.id.fileId = :fileId
and ((:unprocessed = true and m.processedDate is null) or :unprocessed = false)
and (:includeDeletions = true or m.softDeletedTime is null)
""")
List<ManualForceRedactionEntity> findByFileIdAndOptions(@Param("fileId") String fileId,
@Param("includeDeletions") boolean includeDeletions,
@Param("unprocessed") boolean unprocessed);
} }

View File

@ -35,4 +35,16 @@ public interface LegalBasisChangeRepository extends JpaRepository<ManualLegalBas
@Query("update ManualLegalBasisChangeEntity mlbc set mlbc.processedDate = :processedDate where mlbc.id = :annotationEntityId") @Query("update ManualLegalBasisChangeEntity mlbc set mlbc.processedDate = :processedDate where mlbc.id = :annotationEntityId")
void markAsProcessed(@Param("annotationEntityId") AnnotationEntityId annotationEntityId, @Param("processedDate") OffsetDateTime processedDate); void markAsProcessed(@Param("annotationEntityId") AnnotationEntityId annotationEntityId, @Param("processedDate") OffsetDateTime processedDate);
@Query("""
select m
from ManualLegalBasisChangeEntity m
where m.id.fileId = :fileId
and ((:unprocessed = true and m.processedDate is null) or :unprocessed = false)
and (:includeDeletions = true or m.softDeletedTime is null)
""")
List<ManualLegalBasisChangeEntity> findByFileIdAndOptions(@Param("fileId") String fileId,
@Param("includeDeletions") boolean includeDeletions,
@Param("unprocessed") boolean unprocessed);
} }

View File

@ -18,6 +18,7 @@ public interface ManualRedactionRepository extends JpaRepository<ManualRedaction
@Query("update ManualRedactionEntryEntity m set m.softDeletedTime = :softDeleteTime where m.id = :id") @Query("update ManualRedactionEntryEntity m set m.softDeletedTime = :softDeleteTime where m.id = :id")
void updateSoftDelete(@Param("id") AnnotationEntityId id, @Param("softDeleteTime") OffsetDateTime softDeleteTime); void updateSoftDelete(@Param("id") AnnotationEntityId id, @Param("softDeleteTime") OffsetDateTime softDeleteTime);
@Modifying @Modifying
@Query("update ManualRedactionEntryEntity m set m.addToDictionary = :isAddOrRemoveFromDictionary, m.addToDossierDictionary = :isAddOrRemoveFromDossierDictionary where m.id = :id") @Query("update ManualRedactionEntryEntity m set m.addToDictionary = :isAddOrRemoveFromDictionary, m.addToDossierDictionary = :isAddOrRemoveFromDossierDictionary where m.id = :id")
void updateStatus(@Param("id") AnnotationEntityId id, void updateStatus(@Param("id") AnnotationEntityId id,
@ -37,6 +38,19 @@ public interface ManualRedactionRepository extends JpaRepository<ManualRedaction
List<ManualRedactionEntryEntity> findByFileIdAndUnprocessed(@Param("fileId") String fileId); List<ManualRedactionEntryEntity> findByFileIdAndUnprocessed(@Param("fileId") String fileId);
@Query("""
select m
from ManualRedactionEntryEntity m
where m.id.fileId = :fileId
and ((:unprocessed = true and m.processedDate is null) or :unprocessed = false)
and (:includeDeletions = true or m.softDeletedTime is null)
and (:includeDictChanges = true or (m.addToDictionary = false and m.addToAllDossiers = false))
""")
List<ManualRedactionEntryEntity> findByFileIdAndOptions(@Param("fileId") String fileId,
@Param("includeDeletions") boolean includeDeletions,
@Param("unprocessed") boolean unprocessed,
@Param("includeDictChanges") boolean includeDictChanges);
@Modifying @Modifying
@Query("update ManualRedactionEntryEntity m set m.processedDate = :processedDate where m.id = :annotationEntityId") @Query("update ManualRedactionEntryEntity m set m.processedDate = :processedDate where m.id = :annotationEntityId")
void markAsProcessed(@Param("annotationEntityId") AnnotationEntityId annotationEntityId, @Param("processedDate") OffsetDateTime processedDate); void markAsProcessed(@Param("annotationEntityId") AnnotationEntityId annotationEntityId, @Param("processedDate") OffsetDateTime processedDate);

View File

@ -18,17 +18,35 @@ public interface RecategorizationRepository extends JpaRepository<ManualRecatego
@Query("update ManualRecategorizationEntity mir set mir.softDeletedTime = :softDeletedTime where mir.id = :annotationEntityId") @Query("update ManualRecategorizationEntity mir set mir.softDeletedTime = :softDeletedTime where mir.id = :annotationEntityId")
void updateSoftDelete(@Param("annotationEntityId") AnnotationEntityId annotationEntityId, @Param("softDeletedTime") OffsetDateTime softDeletedTime); void updateSoftDelete(@Param("annotationEntityId") AnnotationEntityId annotationEntityId, @Param("softDeletedTime") OffsetDateTime softDeletedTime);
@Query("select mir from ManualRecategorizationEntity mir where mir.id = :annotationEntityId and mir.softDeletedTime is null") @Query("select mir from ManualRecategorizationEntity mir where mir.id = :annotationEntityId and mir.softDeletedTime is null")
Optional<ManualRecategorizationEntity> findByIdAndNotSoftDeleted(@Param("annotationEntityId") AnnotationEntityId annotationEntityId); Optional<ManualRecategorizationEntity> findByIdAndNotSoftDeleted(@Param("annotationEntityId") AnnotationEntityId annotationEntityId);
@Query("select mir from ManualRecategorizationEntity mir where mir.id.fileId = :fileId and (:includeDeletions = true or mir.softDeletedTime is null)") @Query("select mir from ManualRecategorizationEntity mir where mir.id.fileId = :fileId and (:includeDeletions = true or mir.softDeletedTime is null)")
List<ManualRecategorizationEntity> findByFileIdIncludeDeletions(@Param("fileId") String fileId, @Param("includeDeletions") boolean includeDeletions); List<ManualRecategorizationEntity> findByFileIdIncludeDeletions(@Param("fileId") String fileId, @Param("includeDeletions") boolean includeDeletions);
@Query("select mir from ManualRecategorizationEntity mir where mir.id.fileId = :fileId and mir.processedDate is null") @Query("select mir from ManualRecategorizationEntity mir where mir.id.fileId = :fileId and mir.processedDate is null")
List<ManualRecategorizationEntity> findUnprocessedByFileId(@Param("fileId") String fileId); List<ManualRecategorizationEntity> findUnprocessedByFileId(@Param("fileId") String fileId);
@Modifying @Modifying
@Query("update ManualRecategorizationEntity mir set mir.processedDate = :processedDate where mir.id = :annotationEntityId") @Query("update ManualRecategorizationEntity mir set mir.processedDate = :processedDate where mir.id = :annotationEntityId")
void markAsProcessed(@Param("annotationEntityId") AnnotationEntityId annotationEntityId, @Param("processedDate") OffsetDateTime processedDate); void markAsProcessed(@Param("annotationEntityId") AnnotationEntityId annotationEntityId, @Param("processedDate") OffsetDateTime processedDate);
@Query("""
select m
from ManualRecategorizationEntity m
where m.id.fileId = :fileId
and ((:unprocessed = true and m.processedDate is null) or :unprocessed = false)
and (:includeDeletions = true or m.softDeletedTime is null)
and (:includeDictChanges = true or (m.addToDictionary = false and m.addToAllDossiers = false))
""")
List<ManualRecategorizationEntity> findByFileIdAndOptions(@Param("fileId") String fileId,
@Param("includeDeletions") boolean includeDeletions,
@Param("unprocessed") boolean unprocessed,
@Param("includeDictChanges") boolean includeDictChanges);
} }

View File

@ -32,4 +32,16 @@ public interface RemoveRedactionRepository extends JpaRepository<IdRemovalEntity
void markAsProcessed(@Param("annotationEntityId") AnnotationEntityId annotationEntityId, @Param("processedDate") OffsetDateTime processedDate); void markAsProcessed(@Param("annotationEntityId") AnnotationEntityId annotationEntityId, @Param("processedDate") OffsetDateTime processedDate);
@Query("""
select m
from IdRemovalEntity m
where m.id.fileId = :fileId
and ((:unprocessed = true and m.processedDate is null) or :unprocessed = false)
and (:includeDeletions = true or m.softDeletedTime is null)
and (:includeDictChanges = true or (m.removeFromDictionary = false and m.removeFromAllDossiers = false))
""")
List<IdRemovalEntity> findByFileIdAndOptions(@Param("fileId") String fileId,
@Param("includeDeletions") boolean includeDeletions,
@Param("unprocessed") boolean unprocessed,
@Param("includeDictChanges") boolean includeDictChanges);
} }

View File

@ -43,4 +43,16 @@ public interface ResizeRedactionRepository extends JpaRepository<ManualResizeRed
@Query("update ManualResizeRedactionEntity mir set mir.processedDate = :processedDate where mir.id = :annotationEntityId") @Query("update ManualResizeRedactionEntity mir set mir.processedDate = :processedDate where mir.id = :annotationEntityId")
void markAsProcessed(@Param("annotationEntityId") AnnotationEntityId annotationEntityId, @Param("processedDate") OffsetDateTime processedDate); void markAsProcessed(@Param("annotationEntityId") AnnotationEntityId annotationEntityId, @Param("processedDate") OffsetDateTime processedDate);
@Query("""
select m
from ManualResizeRedactionEntity m
where m.id.fileId = :fileId
and ((:unprocessed = true and m.processedDate is null) or :unprocessed = false)
and (:includeDeletions = true or m.softDeletedTime is null)
and (:includeDictChanges = true or (m.updateDictionary = false and m.addToAllDossiers = false))
""")
List<ManualResizeRedactionEntity> findByFileIdAndOptions(@Param("fileId") String fileId,
@Param("includeDeletions") boolean includeDeletions,
@Param("unprocessed") boolean unprocessed,
@Param("includeDictChanges") boolean includeDictChanges);
} }

View File

@ -6,7 +6,6 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
@ -35,6 +34,7 @@ import com.iqser.red.service.persistence.management.v1.processor.service.EntityL
import com.iqser.red.service.persistence.management.v1.processor.service.FileManagementStorageService; import com.iqser.red.service.persistence.management.v1.processor.service.FileManagementStorageService;
import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusService; import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusService;
import com.iqser.red.service.persistence.management.v1.processor.service.manualredactions.ManualRedactionProviderService; import com.iqser.red.service.persistence.management.v1.processor.service.manualredactions.ManualRedactionProviderService;
import com.iqser.red.service.persistence.management.v1.processor.service.manualredactions.PendingDictionaryEntryFactory;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DictionaryPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DictionaryPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierTemplatePersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierTemplatePersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.FileStatusPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.FileStatusPersistenceService;
@ -95,7 +95,7 @@ public class EntityLogMergeTest {
@BeforeEach @BeforeEach
public void setUp() { public void setUp() {
entityLogMergeService = new EntityLogMergeService(dictionaryPersistenceService, rabbitTemplate, fileStatusService, fileStatusPersistenceService); entityLogMergeService = new EntityLogMergeService(dictionaryPersistenceService, rabbitTemplate, fileStatusService, fileStatusPersistenceService, new PendingDictionaryEntryFactory());
} }
@ -117,7 +117,7 @@ public class EntityLogMergeTest {
var entityLog = provideEntityLog(entryToRemoveId, entryToResizeId, entryLegalBasisId, forceRedactionId); var entityLog = provideEntityLog(entryToRemoveId, entryToResizeId, entryLegalBasisId, forceRedactionId);
when(manualRedactionProviderService.getManualRedactions(fileId, true)).thenReturn(manualRedactions); when(manualRedactionProviderService.getManualRedactions(any(), any())).thenReturn(manualRedactions);
when(fileStatusService.getStatus(fileId)).thenReturn(FileModel.builder() when(fileStatusService.getStatus(fileId)).thenReturn(FileModel.builder()
.excluded(false) .excluded(false)
.dossierStatusId(dossierTemplateId) .dossierStatusId(dossierTemplateId)
@ -147,14 +147,14 @@ public class EntityLogMergeTest {
assertEquals(entityLogEntry.getValue(), "Test"); assertEquals(entityLogEntry.getValue(), "Test");
assertEquals(entityLogEntry.getReason(), "Reason"); assertEquals(entityLogEntry.getReason(), "Reason");
assertTrue(entityLogEntry.getEngines().contains(Engine.MANUAL)); assertTrue(entityLogEntry.getEngines().contains(Engine.MANUAL));
assertEquals(entityLogEntry.getManualChanges().get(0).getManualRedactionType(), ManualRedactionType.ADD_LOCALLY); assertEquals(entityLogEntry.getManualChanges().get(0).getManualRedactionType(), ManualRedactionType.ADD);
var optionalRemoveEntryLogEntry = response.getEntityLogEntry().stream().filter(entityLogEntry1 -> entityLogEntry1.getId().equals(entryToRemoveId)).findFirst(); var optionalRemoveEntryLogEntry = response.getEntityLogEntry().stream().filter(entityLogEntry1 -> entityLogEntry1.getId().equals(entryToRemoveId)).findFirst();
assertTrue(optionalRemoveEntryLogEntry.isPresent()); assertTrue(optionalRemoveEntryLogEntry.isPresent());
var removeEntryLogEntry = optionalRemoveEntryLogEntry.get(); var removeEntryLogEntry = optionalRemoveEntryLogEntry.get();
assertEquals(removeEntryLogEntry.getEntryType(), EntryType.ENTITY); assertEquals(removeEntryLogEntry.getEntryType(), EntryType.ENTITY);
assertEquals(removeEntryLogEntry.getState(), EntryState.IGNORED); assertEquals(removeEntryLogEntry.getState(), EntryState.IGNORED);
assertEquals(removeEntryLogEntry.getManualChanges().get(0).getManualRedactionType(), ManualRedactionType.REMOVE_LOCALLY); assertEquals(removeEntryLogEntry.getManualChanges().get(0).getManualRedactionType(), ManualRedactionType.REMOVE);
assertEquals(removeEntryLogEntry.getChanges().get(0).getType(), ChangeType.REMOVED); assertEquals(removeEntryLogEntry.getChanges().get(0).getType(), ChangeType.REMOVED);
assertTrue(removeEntryLogEntry.getEngines().contains(Engine.MANUAL)); assertTrue(removeEntryLogEntry.getEngines().contains(Engine.MANUAL));
@ -188,7 +188,7 @@ public class EntityLogMergeTest {
assertEquals(forceRedactionEntryLogEntry.getLegalBasis(), "Force"); assertEquals(forceRedactionEntryLogEntry.getLegalBasis(), "Force");
assertEquals(forceRedactionEntryLogEntry.getEntryType(), EntryType.ENTITY); assertEquals(forceRedactionEntryLogEntry.getEntryType(), EntryType.ENTITY);
assertEquals(forceRedactionEntryLogEntry.getState(), EntryState.APPLIED); assertEquals(forceRedactionEntryLogEntry.getState(), EntryState.APPLIED);
assertEquals(forceRedactionEntryLogEntry.getManualChanges().get(0).getManualRedactionType(), ManualRedactionType.FORCE_REDACT); assertEquals(forceRedactionEntryLogEntry.getManualChanges().get(0).getManualRedactionType(), ManualRedactionType.FORCE);
assertEquals(forceRedactionEntryLogEntry.getChanges().get(0).getType(), ChangeType.CHANGED); assertEquals(forceRedactionEntryLogEntry.getChanges().get(0).getType(), ChangeType.CHANGED);
assertTrue(forceRedactionEntryLogEntry.getEngines().contains(Engine.MANUAL)); assertTrue(forceRedactionEntryLogEntry.getEngines().contains(Engine.MANUAL));
@ -200,7 +200,7 @@ public class EntityLogMergeTest {
assertEquals(rectangleEntryLogEntry.getState(), EntryState.APPLIED); assertEquals(rectangleEntryLogEntry.getState(), EntryState.APPLIED);
assertEquals(rectangleEntryLogEntry.getValue(), "Test2"); assertEquals(rectangleEntryLogEntry.getValue(), "Test2");
assertEquals(rectangleEntryLogEntry.getReason(), "Rectangle"); assertEquals(rectangleEntryLogEntry.getReason(), "Rectangle");
assertEquals(rectangleEntryLogEntry.getManualChanges().get(0).getManualRedactionType(), ManualRedactionType.ADD_LOCALLY); assertEquals(rectangleEntryLogEntry.getManualChanges().get(0).getManualRedactionType(), ManualRedactionType.ADD);
assertTrue(rectangleEntryLogEntry.getEngines().contains(Engine.MANUAL)); assertTrue(rectangleEntryLogEntry.getEngines().contains(Engine.MANUAL));
} }

View File

@ -45,7 +45,10 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogEntry; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogEntry;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryState; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryState;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryType; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryType;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.AddRedactionRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ManualRedactions;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.Rectangle; import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.Rectangle;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualRedactionEntry;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileType; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileType;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.type.DictionaryEntryType; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.type.DictionaryEntryType;
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.AddRedactionRequestModel; import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.AddRedactionRequestModel;
@ -54,6 +57,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.Lega
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.RecategorizationRequestModel; import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.RecategorizationRequestModel;
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.RemoveRedactionRequestModel; import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.RemoveRedactionRequestModel;
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.ResizeRedactionRequestModel; import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.ResizeRedactionRequestModel;
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.Point;
import feign.FeignException; import feign.FeignException;
@ -514,7 +518,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
.build(); .build();
var addRedactions = manualRedactionClient.addRedactionBulk(dossier1.getId(), file1.getId(), Set.of(redactionDos, redactionDosTempDict)); var addRedactions = manualRedactionClient.addRedactionBulk(dossier1.getId(), file1.getId(), Set.of(redactionDos, redactionDosTempDict));
var loadedRedactionsFile1 = manualRedactionClient.getManualRedactions(file1.getDossierId(), file1.getFileId(), false); var loadedRedactionsFile1 = manualRedactionClient.getManualRedactions(file1.getDossierId(), file1.getFileId(), false, true);
var entityLog1 = new EntityLog(1, var entityLog1 = new EntityLog(1,
1, 1,
@ -573,7 +577,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
manualRedactionClient.resizeRedactionBulk(dossier1.getId(), file1.getFileId(), Set.of(resizeRedactionDosAndAddToAllDos), false); manualRedactionClient.resizeRedactionBulk(dossier1.getId(), file1.getFileId(), Set.of(resizeRedactionDosAndAddToAllDos), false);
loadedRedactionsFile1 = manualRedactionClient.getManualRedactions(file1.getDossierId(), file1.getFileId(), false); loadedRedactionsFile1 = manualRedactionClient.getManualRedactions(file1.getDossierId(), file1.getFileId(), false, true);
assertThat(loadedRedactionsFile1.getResizeRedactions()).hasSize(1); assertThat(loadedRedactionsFile1.getResizeRedactions()).hasSize(1);
assertThat(loadedRedactionsFile1.getResizeRedactions() assertThat(loadedRedactionsFile1.getResizeRedactions()
@ -679,7 +683,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
.build(); .build();
var addRedactions = manualRedactionClient.addRedactionBulk(dossier1.getId(), file1.getId(), Set.of(redactionDos, redactionDosTempDict)); var addRedactions = manualRedactionClient.addRedactionBulk(dossier1.getId(), file1.getId(), Set.of(redactionDos, redactionDosTempDict));
var loadedRedactionsFile1 = manualRedactionClient.getManualRedactions(file1.getDossierId(), file1.getFileId(), false); var loadedRedactionsFile1 = manualRedactionClient.getManualRedactions(file1.getDossierId(), file1.getFileId(), false, true);
var entityLog1 = new EntityLog(1, var entityLog1 = new EntityLog(1,
1, 1,
@ -738,7 +742,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
manualRedactionClient.resizeRedactionBulk(dossier1.getId(), file1.getFileId(), Set.of(resizeRedactionDosAndAddToAllDos), false); manualRedactionClient.resizeRedactionBulk(dossier1.getId(), file1.getFileId(), Set.of(resizeRedactionDosAndAddToAllDos), false);
loadedRedactionsFile1 = manualRedactionClient.getManualRedactions(file1.getDossierId(), file1.getFileId(), false); loadedRedactionsFile1 = manualRedactionClient.getManualRedactions(file1.getDossierId(), file1.getFileId(), false, true);
assertThat(loadedRedactionsFile1.getResizeRedactions()).hasSize(1); assertThat(loadedRedactionsFile1.getResizeRedactions()).hasSize(1);
assertThat(loadedRedactionsFile1.getResizeRedactions() assertThat(loadedRedactionsFile1.getResizeRedactions()
@ -804,7 +808,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
@Test @Test
public void testEnlargeResizeRedactionInDossierTemplateDictionaryWithAddToAllDossiers() { public void MtestEnlargeResizeRedactionInDossierTemplateDictionaryWithAddToAllDossiers() {
// preparíng prerequisites // preparíng prerequisites
var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate(); var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();
@ -907,7 +911,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
var resizeRedactions = manualRedactionClient.resizeRedactionBulk(dossier2.getId(), file2.getFileId(), Set.of(resizeRedactionDosTemp), false); var resizeRedactions = manualRedactionClient.resizeRedactionBulk(dossier2.getId(), file2.getFileId(), Set.of(resizeRedactionDosTemp), false);
var loadedRedactionsFile2 = manualRedactionClient.getManualRedactions(file2.getDossierId(), file2.getFileId(), false); var loadedRedactionsFile2 = manualRedactionClient.getManualRedactions(file2.getDossierId(), file2.getFileId(), false, true);
assertThat(loadedRedactionsFile2.getResizeRedactions()).hasSize(1); assertThat(loadedRedactionsFile2.getResizeRedactions()).hasSize(1);
assertThat(loadedRedactionsFile2.getResizeRedactions() assertThat(loadedRedactionsFile2.getResizeRedactions()
@ -1073,7 +1077,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
var resizeRedactions = manualRedactionClient.resizeRedactionBulk(dossier2.getId(), file2.getFileId(), Set.of(resizeRedactionDosTemp), false); var resizeRedactions = manualRedactionClient.resizeRedactionBulk(dossier2.getId(), file2.getFileId(), Set.of(resizeRedactionDosTemp), false);
var loadedRedactionsFile2 = manualRedactionClient.getManualRedactions(file2.getDossierId(), file2.getFileId(), false); var loadedRedactionsFile2 = manualRedactionClient.getManualRedactions(file2.getDossierId(), file2.getFileId(), false, true);
assertThat(loadedRedactionsFile2.getResizeRedactions()).hasSize(1); assertThat(loadedRedactionsFile2.getResizeRedactions()).hasSize(1);
assertThat(loadedRedactionsFile2.getResizeRedactions() assertThat(loadedRedactionsFile2.getResizeRedactions()
@ -1330,13 +1334,13 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
.sourceId("SourceId") .sourceId("SourceId")
.build())); .build()));
var allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false); var allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false, true);
assertEquals(allManualRedactions.getEntriesToAdd().size(), 1); assertEquals(allManualRedactions.getEntriesToAdd().size(), 1);
assertTrue(allManualRedactions.getEntriesToAdd() assertTrue(allManualRedactions.getEntriesToAdd()
.stream() .stream()
.anyMatch(entry -> entry.getValue().equals("Luke Skywalker"))); .anyMatch(entry -> entry.getValue().equals("Luke Skywalker")));
var unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true); var unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true, true);
assertEquals(unprocessedManualRedactions.getEntriesToAdd().size(), 1); assertEquals(unprocessedManualRedactions.getEntriesToAdd().size(), 1);
assertTrue(unprocessedManualRedactions.getEntriesToAdd() assertTrue(unprocessedManualRedactions.getEntriesToAdd()
.stream() .stream()
@ -1367,7 +1371,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
.sourceId("SourceId") .sourceId("SourceId")
.build())); .build()));
allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false); allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false, true);
assertEquals(allManualRedactions.getEntriesToAdd().size(), 2); assertEquals(allManualRedactions.getEntriesToAdd().size(), 2);
assertTrue(allManualRedactions.getEntriesToAdd() assertTrue(allManualRedactions.getEntriesToAdd()
.stream() .stream()
@ -1376,7 +1380,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
.stream() .stream()
.anyMatch(entry -> entry.getValue().equals("Luke Skywalker"))); .anyMatch(entry -> entry.getValue().equals("Luke Skywalker")));
unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true); unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true, true);
assertEquals(unprocessedManualRedactions.getEntriesToAdd().size(), 1); assertEquals(unprocessedManualRedactions.getEntriesToAdd().size(), 1);
assertTrue(unprocessedManualRedactions.getEntriesToAdd() assertTrue(unprocessedManualRedactions.getEntriesToAdd()
.stream() .stream()
@ -1395,7 +1399,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
.dossierId(dossier.getId()) .dossierId(dossier.getId())
.build()); .build());
allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false); allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false, true);
assertEquals(allManualRedactions.getEntriesToAdd().size(), 2); assertEquals(allManualRedactions.getEntriesToAdd().size(), 2);
assertTrue(allManualRedactions.getEntriesToAdd() assertTrue(allManualRedactions.getEntriesToAdd()
.stream() .stream()
@ -1404,7 +1408,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
.stream() .stream()
.anyMatch(entry -> entry.getValue().equals("Luke Skywalker"))); .anyMatch(entry -> entry.getValue().equals("Luke Skywalker")));
unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true); unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true, true);
assertTrue(unprocessedManualRedactions.getEntriesToAdd().isEmpty()); assertTrue(unprocessedManualRedactions.getEntriesToAdd().isEmpty());
dictionaryClient.addEntry(type.getType(), type.getDossierTemplateId(), List.of("Luke Skywalker"), false, dossier.getId(), DictionaryEntryType.ENTRY); dictionaryClient.addEntry(type.getType(), type.getDossierTemplateId(), List.of("Luke Skywalker"), false, dossier.getId(), DictionaryEntryType.ENTRY);
@ -1458,13 +1462,13 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
.build()), .build()),
false); false);
var allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false); var allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false, true);
assertEquals(allManualRedactions.getIdsToRemove().size(), 1); assertEquals(allManualRedactions.getIdsToRemove().size(), 1);
assertTrue(allManualRedactions.getIdsToRemove() assertTrue(allManualRedactions.getIdsToRemove()
.stream() .stream()
.anyMatch(entry -> entry.getAnnotationId().equals("AnnotationId"))); .anyMatch(entry -> entry.getAnnotationId().equals("AnnotationId")));
var unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true); var unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true, true);
assertEquals(unprocessedManualRedactions.getIdsToRemove().size(), 1); assertEquals(unprocessedManualRedactions.getIdsToRemove().size(), 1);
assertTrue(unprocessedManualRedactions.getIdsToRemove() assertTrue(unprocessedManualRedactions.getIdsToRemove()
.stream() .stream()
@ -1489,7 +1493,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
.build()), .build()),
false); false);
allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false); allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false, true);
assertEquals(allManualRedactions.getIdsToRemove().size(), 2); assertEquals(allManualRedactions.getIdsToRemove().size(), 2);
assertTrue(allManualRedactions.getIdsToRemove() assertTrue(allManualRedactions.getIdsToRemove()
.stream() .stream()
@ -1498,7 +1502,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
.stream() .stream()
.anyMatch(entry -> entry.getAnnotationId().equals("AnnotationId2"))); .anyMatch(entry -> entry.getAnnotationId().equals("AnnotationId2")));
unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true); unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true, true);
assertEquals(unprocessedManualRedactions.getIdsToRemove().size(), 1); assertEquals(unprocessedManualRedactions.getIdsToRemove().size(), 1);
assertTrue(unprocessedManualRedactions.getIdsToRemove() assertTrue(unprocessedManualRedactions.getIdsToRemove()
.stream() .stream()
@ -1517,7 +1521,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
.dossierId(dossier.getId()) .dossierId(dossier.getId())
.build()); .build());
allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false); allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false, true);
assertEquals(allManualRedactions.getIdsToRemove().size(), 2); assertEquals(allManualRedactions.getIdsToRemove().size(), 2);
assertTrue(allManualRedactions.getIdsToRemove() assertTrue(allManualRedactions.getIdsToRemove()
.stream() .stream()
@ -1526,7 +1530,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
.stream() .stream()
.anyMatch(entry -> entry.getAnnotationId().equals("AnnotationId2"))); .anyMatch(entry -> entry.getAnnotationId().equals("AnnotationId2")));
unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true); unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true, true);
assertTrue(unprocessedManualRedactions.getIdsToRemove().isEmpty()); assertTrue(unprocessedManualRedactions.getIdsToRemove().isEmpty());
} }
@ -1542,13 +1546,13 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
file.getId(), file.getId(),
Set.of(ForceRedactionRequestModel.builder().annotationId("forceRedactionAnnotation").comment("comment").legalBasis("1").build())); Set.of(ForceRedactionRequestModel.builder().annotationId("forceRedactionAnnotation").comment("comment").legalBasis("1").build()));
var allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false); var allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false, true);
assertEquals(allManualRedactions.getForceRedactions().size(), 1); assertEquals(allManualRedactions.getForceRedactions().size(), 1);
assertTrue(allManualRedactions.getForceRedactions() assertTrue(allManualRedactions.getForceRedactions()
.stream() .stream()
.anyMatch(entry -> entry.getAnnotationId().equals("forceRedactionAnnotation"))); .anyMatch(entry -> entry.getAnnotationId().equals("forceRedactionAnnotation")));
var unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true); var unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true, true);
assertEquals(unprocessedManualRedactions.getForceRedactions().size(), 1); assertEquals(unprocessedManualRedactions.getForceRedactions().size(), 1);
assertTrue(unprocessedManualRedactions.getForceRedactions() assertTrue(unprocessedManualRedactions.getForceRedactions()
.stream() .stream()
@ -1568,7 +1572,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
file.getId(), file.getId(),
Set.of(ForceRedactionRequestModel.builder().annotationId("forceRedactionAnnotation2").comment("comment").legalBasis("1").build())); Set.of(ForceRedactionRequestModel.builder().annotationId("forceRedactionAnnotation2").comment("comment").legalBasis("1").build()));
allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false); allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false, true);
assertEquals(allManualRedactions.getForceRedactions().size(), 2); assertEquals(allManualRedactions.getForceRedactions().size(), 2);
assertTrue(allManualRedactions.getForceRedactions() assertTrue(allManualRedactions.getForceRedactions()
.stream() .stream()
@ -1577,7 +1581,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
.stream() .stream()
.anyMatch(entry -> entry.getAnnotationId().equals("forceRedactionAnnotation"))); .anyMatch(entry -> entry.getAnnotationId().equals("forceRedactionAnnotation")));
unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true); unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true, true);
assertEquals(unprocessedManualRedactions.getForceRedactions().size(), 1); assertEquals(unprocessedManualRedactions.getForceRedactions().size(), 1);
assertTrue(unprocessedManualRedactions.getForceRedactions() assertTrue(unprocessedManualRedactions.getForceRedactions()
.stream() .stream()
@ -1596,7 +1600,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
.dossierId(dossier.getId()) .dossierId(dossier.getId())
.build()); .build());
allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false); allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false, true);
assertEquals(allManualRedactions.getForceRedactions().size(), 2); assertEquals(allManualRedactions.getForceRedactions().size(), 2);
assertTrue(allManualRedactions.getForceRedactions() assertTrue(allManualRedactions.getForceRedactions()
.stream() .stream()
@ -1605,7 +1609,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
.stream() .stream()
.anyMatch(entry -> entry.getAnnotationId().equals("forceRedactionAnnotation2"))); .anyMatch(entry -> entry.getAnnotationId().equals("forceRedactionAnnotation2")));
unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true); unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true, true);
assertTrue(unprocessedManualRedactions.getForceRedactions().isEmpty()); assertTrue(unprocessedManualRedactions.getForceRedactions().isEmpty());
} }
@ -1650,13 +1654,13 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
manualRedactionClient.recategorizeBulk(dossier.getId(), file.getId(), Set.of(RecategorizationRequestModel.builder().annotationId("dv").legalBasis("").build()), false); manualRedactionClient.recategorizeBulk(dossier.getId(), file.getId(), Set.of(RecategorizationRequestModel.builder().annotationId("dv").legalBasis("").build()), false);
var allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false); var allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false, true);
assertEquals(allManualRedactions.getRecategorizations().size(), 1); assertEquals(allManualRedactions.getRecategorizations().size(), 1);
assertTrue(allManualRedactions.getRecategorizations() assertTrue(allManualRedactions.getRecategorizations()
.stream() .stream()
.anyMatch(entry -> entry.getAnnotationId().equals("dv"))); .anyMatch(entry -> entry.getAnnotationId().equals("dv")));
var unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true); var unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true, true);
assertEquals(unprocessedManualRedactions.getRecategorizations().size(), 1); assertEquals(unprocessedManualRedactions.getRecategorizations().size(), 1);
assertTrue(unprocessedManualRedactions.getRecategorizations() assertTrue(unprocessedManualRedactions.getRecategorizations()
.stream() .stream()
@ -1674,7 +1678,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
manualRedactionClient.recategorizeBulk(dossier.getId(), file.getId(), Set.of(RecategorizationRequestModel.builder().annotationId("dv2").legalBasis("").build()), false); manualRedactionClient.recategorizeBulk(dossier.getId(), file.getId(), Set.of(RecategorizationRequestModel.builder().annotationId("dv2").legalBasis("").build()), false);
allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false); allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false, true);
assertEquals(allManualRedactions.getRecategorizations().size(), 2); assertEquals(allManualRedactions.getRecategorizations().size(), 2);
assertTrue(allManualRedactions.getRecategorizations() assertTrue(allManualRedactions.getRecategorizations()
.stream() .stream()
@ -1683,7 +1687,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
.stream() .stream()
.anyMatch(entry -> entry.getAnnotationId().equals("dv2"))); .anyMatch(entry -> entry.getAnnotationId().equals("dv2")));
unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true); unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true, true);
assertEquals(unprocessedManualRedactions.getRecategorizations().size(), 1); assertEquals(unprocessedManualRedactions.getRecategorizations().size(), 1);
assertTrue(unprocessedManualRedactions.getRecategorizations() assertTrue(unprocessedManualRedactions.getRecategorizations()
.stream() .stream()
@ -1702,7 +1706,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
.dossierId(dossier.getId()) .dossierId(dossier.getId())
.build()); .build());
allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false); allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false, true);
assertEquals(allManualRedactions.getRecategorizations().size(), 2); assertEquals(allManualRedactions.getRecategorizations().size(), 2);
assertTrue(allManualRedactions.getRecategorizations() assertTrue(allManualRedactions.getRecategorizations()
.stream() .stream()
@ -1711,7 +1715,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
.stream() .stream()
.anyMatch(entry -> entry.getAnnotationId().equals("dv2"))); .anyMatch(entry -> entry.getAnnotationId().equals("dv2")));
unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true); unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true, true);
assertTrue(unprocessedManualRedactions.getRecategorizations().isEmpty()); assertTrue(unprocessedManualRedactions.getRecategorizations().isEmpty());
} }
@ -1758,13 +1762,13 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
file.getId(), file.getId(),
Set.of(LegalBasisChangeRequestModel.builder().legalBasis("legalBasis").annotationId("AnnotationId").build())); Set.of(LegalBasisChangeRequestModel.builder().legalBasis("legalBasis").annotationId("AnnotationId").build()));
var allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false); var allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false, true);
assertEquals(allManualRedactions.getLegalBasisChanges().size(), 1); assertEquals(allManualRedactions.getLegalBasisChanges().size(), 1);
assertTrue(allManualRedactions.getLegalBasisChanges() assertTrue(allManualRedactions.getLegalBasisChanges()
.stream() .stream()
.anyMatch(entry -> entry.getLegalBasis().equals("legalBasis"))); .anyMatch(entry -> entry.getLegalBasis().equals("legalBasis")));
var unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true); var unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true, true);
assertEquals(unprocessedManualRedactions.getLegalBasisChanges().size(), 1); assertEquals(unprocessedManualRedactions.getLegalBasisChanges().size(), 1);
assertTrue(unprocessedManualRedactions.getLegalBasisChanges() assertTrue(unprocessedManualRedactions.getLegalBasisChanges()
.stream() .stream()
@ -1784,7 +1788,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
file.getId(), file.getId(),
Set.of(LegalBasisChangeRequestModel.builder().legalBasis("legalBasis2").annotationId("AnnotationId2").build())); Set.of(LegalBasisChangeRequestModel.builder().legalBasis("legalBasis2").annotationId("AnnotationId2").build()));
allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false); allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false, true);
assertEquals(allManualRedactions.getLegalBasisChanges().size(), 2); assertEquals(allManualRedactions.getLegalBasisChanges().size(), 2);
assertTrue(allManualRedactions.getLegalBasisChanges() assertTrue(allManualRedactions.getLegalBasisChanges()
.stream() .stream()
@ -1793,7 +1797,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
.stream() .stream()
.anyMatch(entry -> entry.getLegalBasis().equals("legalBasis2"))); .anyMatch(entry -> entry.getLegalBasis().equals("legalBasis2")));
unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true); unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true, true);
assertEquals(unprocessedManualRedactions.getLegalBasisChanges().size(), 1); assertEquals(unprocessedManualRedactions.getLegalBasisChanges().size(), 1);
assertTrue(unprocessedManualRedactions.getLegalBasisChanges() assertTrue(unprocessedManualRedactions.getLegalBasisChanges()
.stream() .stream()
@ -1812,7 +1816,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
.dossierId(dossier.getId()) .dossierId(dossier.getId())
.build()); .build());
allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false); allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false, true);
assertEquals(allManualRedactions.getLegalBasisChanges().size(), 2); assertEquals(allManualRedactions.getLegalBasisChanges().size(), 2);
assertTrue(allManualRedactions.getLegalBasisChanges() assertTrue(allManualRedactions.getLegalBasisChanges()
.stream() .stream()
@ -1821,11 +1825,89 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
.stream() .stream()
.anyMatch(entry -> entry.getLegalBasis().equals("legalBasis2"))); .anyMatch(entry -> entry.getLegalBasis().equals("legalBasis2")));
unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true); unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true, true);
assertTrue(unprocessedManualRedactions.getResizeRedactions().isEmpty()); assertTrue(unprocessedManualRedactions.getResizeRedactions().isEmpty());
} }
@Test
public void testQueryOptions() {
var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();
var dossier = dossierTesterAndProvider.provideTestDossier(dossierTemplate);
var file = fileTesterAndProvider.testAndProvideFile(dossier);
var type = typeProvider.testAndProvideType(dossierTemplate, null, "type", false);
dictionaryClient.addEntry(type.getType(), type.getDossierTemplateId(), List.of("Luke Skywalker"), false, dossier.getId(), DictionaryEntryType.ENTRY);
var entityLog = new EntityLog(1,
1,
List.of(EntityLogEntry.builder()
.id("AnnotationId")
.type(type.getType())
.value("Luke Skywalker")
.entryType(EntryType.ENTITY)
.state(EntryState.APPLIED)
.dictionaryEntry(false)
.build(),
EntityLogEntry.builder()
.id("AnnotationId2")
.type(type.getType())
.value("Skywalker Luke")
.entryType(EntryType.ENTITY)
.state(EntryState.APPLIED)
.dictionaryEntry(false)
.build()),
null,
0,
0,
0,
0);
fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog);
when(entityLogService.getEntityLog(Mockito.any(), Mockito.any())).thenReturn(entityLog);
manualRedactionClient.legalBasisChangeBulk(dossier.getId(),
file.getId(),
Set.of(LegalBasisChangeRequestModel.builder().legalBasis("legalBasis").annotationId("AnnotationId").build()));
manualRedactionClient.addRedactionBulk(dossier.getId(),
file.getId(),
Set.of(AddRedactionRequestModel.builder()
.value("Peter")
.type("type")
.legalBasis("legalBasis")
.reason("reason")
.positions(List.of(new Rectangle(new Point(0, 0), 10, 10, 1)))
.dictionaryEntryType(DictionaryEntryType.ENTRY)
.addToDictionary(true)
.build()));
var allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false, false);
assertEquals(allManualRedactions.getLegalBasisChanges().size(), 1);
assertTrue(allManualRedactions.getLegalBasisChanges()
.stream()
.anyMatch(entry -> entry.getLegalBasis().equals("legalBasis")));
var unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true, false);
assertEquals(unprocessedManualRedactions.buildAll().size(), 1);
assertTrue(unprocessedManualRedactions.getLegalBasisChanges()
.stream()
.anyMatch(entry -> entry.getLegalBasis().equals("legalBasis")));
var unprocessedManualRedactionsWithDict = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true, true);
assertEquals(unprocessedManualRedactionsWithDict.buildAll().size(), 2);
assertTrue(unprocessedManualRedactionsWithDict.getLegalBasisChanges()
.stream()
.anyMatch(entry -> entry.getLegalBasis().equals("legalBasis")));
assertTrue(unprocessedManualRedactionsWithDict.getEntriesToAdd()
.stream()
.anyMatch(entry -> entry.getValue().equals("Peter")));
}
@Test @Test
public void testLegalBasisInManualRecategorization() { public void testLegalBasisInManualRecategorization() {
@ -1888,7 +1970,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
manualRedactionClient.recategorizeBulk(dossier.getId(), file.getId(), Set.of(recatModel, recatModelNoLegalBasis), false); manualRedactionClient.recategorizeBulk(dossier.getId(), file.getId(), Set.of(recatModel, recatModelNoLegalBasis), false);
var allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false); var allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false, true);
assertEquals(2, allManualRedactions.getRecategorizations().size()); assertEquals(2, allManualRedactions.getRecategorizations().size());
assertTrue(allManualRedactions.getRecategorizations() assertTrue(allManualRedactions.getRecategorizations()
.stream() .stream()
@ -1897,10 +1979,12 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
assertThatThrownBy(() -> manualRedactionClient.recategorizeBulk(dossier.getId(), file.getId(), Set.of(recatModelLongLegalBasis), false) assertThatThrownBy(() -> manualRedactionClient.recategorizeBulk(dossier.getId(), file.getId(), Set.of(recatModelLongLegalBasis), false)
.get(0)).isInstanceOf(FeignException.class).hasMessageContaining("The legal basis is too long"); .get(0)).isInstanceOf(FeignException.class).hasMessageContaining("The legal basis is too long");
assertEquals("", allManualRedactions.getRecategorizations() assertEquals("",
.stream() allManualRedactions.getRecategorizations()
.filter(manualRecategorization -> manualRecategorization.getAnnotationId().equals("annotationId3")) .stream()
.findFirst().get().getLegalBasis()); .filter(manualRecategorization -> manualRecategorization.getAnnotationId().equals("annotationId3"))
.findFirst()
.get().getLegalBasis());
} }

View File

@ -4,5 +4,6 @@ public enum EntryState {
APPLIED, APPLIED,
SKIPPED, SKIPPED,
IGNORED, IGNORED,
REMOVED REMOVED,
PENDING
} }

View File

@ -1,14 +1,24 @@
package com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog; package com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog;
public enum ManualRedactionType { public enum ManualRedactionType {
@Deprecated
ADD_LOCALLY, ADD_LOCALLY,
ADD_TO_DICTIONARY, @Deprecated
REMOVE_LOCALLY,
REMOVE_FROM_DICTIONARY,
FORCE_REDACT, FORCE_REDACT,
@Deprecated
FORCE_HINT, FORCE_HINT,
@Deprecated
REMOVE_LOCALLY,
ADD,
ADD_TO_DICTIONARY,
REMOVE,
REMOVE_FROM_DICTIONARY,
FORCE,
RECATEGORIZE, RECATEGORIZE,
RECATEGORIZE_IN_DICTIONARY,
LEGAL_BASIS_CHANGE, LEGAL_BASIS_CHANGE,
RESIZE, // Treat internally as a local resize. Documine already has documents with the value "RESIZE" in them, so we need it for backwards compatibility RESIZE,
RESIZE_IN_DICTIONARY RESIZE_IN_DICTIONARY
} }

View File

@ -1,11 +1,12 @@
package com.iqser.red.service.persistence.service.v1.api.shared.model.annotations; package com.iqser.red.service.persistence.service.v1.api.shared.model.annotations;
import java.util.HashMap; import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.BaseAnnotation;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.IdRemoval; import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.IdRemoval;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualForceRedaction; import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualForceRedaction;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualLegalBasisChange; import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualLegalBasisChange;
@ -17,6 +18,7 @@ import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.NonNull;
@Data @Data
@Builder @Builder
@ -24,22 +26,60 @@ import lombok.NoArgsConstructor;
@NoArgsConstructor @NoArgsConstructor
public class ManualRedactions { public class ManualRedactions {
@NonNull
@Builder.Default @Builder.Default
private Set<IdRemoval> idsToRemove = new HashSet<>(); private Set<IdRemoval> idsToRemove = new HashSet<>();
@NonNull
@Builder.Default @Builder.Default
private Set<ManualRedactionEntry> entriesToAdd = new HashSet<>(); private Set<ManualRedactionEntry> entriesToAdd = new HashSet<>();
@NonNull
@Builder.Default @Builder.Default
private Set<ManualForceRedaction> forceRedactions = new HashSet<>(); private Set<ManualForceRedaction> forceRedactions = new HashSet<>();
@NonNull
@Builder.Default @Builder.Default
private Set<ManualRecategorization> recategorizations = new HashSet<>(); private Set<ManualRecategorization> recategorizations = new HashSet<>();
@NonNull
@Builder.Default @Builder.Default
private Set<ManualLegalBasisChange> legalBasisChanges = new HashSet<>(); private Set<ManualLegalBasisChange> legalBasisChanges = new HashSet<>();
@NonNull
@Builder.Default @Builder.Default
private Set<ManualResizeRedaction> resizeRedactions = new HashSet<>(); private Set<ManualResizeRedaction> resizeRedactions = new HashSet<>();
public List<BaseAnnotation> buildAll() {
List<BaseAnnotation> all = new ArrayList<>(idsToRemove.size()
+ entriesToAdd.size()
+ forceRedactions.size()
+ recategorizations.size()
+ legalBasisChanges.size()
+ resizeRedactions.size());
all.addAll(idsToRemove);
all.addAll(entriesToAdd);
all.addAll(forceRedactions);
all.addAll(recategorizations);
all.addAll(legalBasisChanges);
all.addAll(resizeRedactions);
return all;
}
public List<BaseAnnotation> buildAllSorted() {
return buildAll().stream()
.sorted(Comparator.comparing(BaseAnnotation::getRequestDate))
.toList();
}
public boolean isEmpty() {
return idsToRemove.isEmpty()
&& entriesToAdd.isEmpty()
&& forceRedactions.isEmpty()
&& recategorizations.isEmpty()
&& legalBasisChanges.isEmpty()
&& resizeRedactions.isEmpty();
}
} }

View File

@ -17,7 +17,7 @@ import lombok.experimental.SuperBuilder;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@EqualsAndHashCode @EqualsAndHashCode
public class BaseAnnotation { public abstract class BaseAnnotation {
private String annotationId; private String annotationId;
private String fileId; private String fileId;
@ -26,6 +26,7 @@ public class BaseAnnotation {
private OffsetDateTime processedDate; private OffsetDateTime processedDate;
private OffsetDateTime softDeletedTime; private OffsetDateTime softDeletedTime;
public abstract boolean isLocal();
@Deprecated(forRemoval = true) @Deprecated(forRemoval = true)
public boolean isApproved() { public boolean isApproved() {

View File

@ -16,4 +16,11 @@ public class IdRemoval extends BaseAnnotation {
private boolean removeFromDictionary; private boolean removeFromDictionary;
private boolean removeFromAllDossiers; private boolean removeFromAllDossiers;
@Override
public boolean isLocal() {
return !(removeFromDictionary || removeFromAllDossiers);
}
} }

View File

@ -15,4 +15,11 @@ public class ManualForceRedaction extends BaseAnnotation {
private String legalBasis; private String legalBasis;
@Override
public boolean isLocal() {
return true;
}
} }

View File

@ -17,4 +17,11 @@ public class ManualLegalBasisChange extends BaseAnnotation {
private String value; private String value;
private String legalBasis; private String legalBasis;
@Override
public boolean isLocal() {
return true;
}
} }

View File

@ -15,5 +15,14 @@ public class ManualRecategorization extends BaseAnnotation {
private String type; private String type;
private String legalBasis; private String legalBasis;
private boolean addToDictionary;
private boolean addToAllDossiers;
@Override
public boolean isLocal() {
return !(addToDictionary || addToAllDossiers);
}
} }

View File

@ -33,4 +33,11 @@ public class ManualRedactionEntry extends BaseAnnotation {
private String sourceId; private String sourceId;
private DictionaryEntryType dictionaryEntryType; private DictionaryEntryType dictionaryEntryType;
@Override
public boolean isLocal() {
return !(addToDictionary || addToDossierDictionary);
}
} }

View File

@ -25,4 +25,11 @@ public class ManualResizeRedaction extends BaseAnnotation {
private Boolean updateDictionary; private Boolean updateDictionary;
private boolean addToAllDossiers; private boolean addToAllDossiers;
@Override
public boolean isLocal() {
return !(updateDictionary || addToAllDossiers);
}
} }

View File

@ -1,7 +1,27 @@
package com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.type; package com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.type;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryType;
public enum DictionaryEntryType { public enum DictionaryEntryType {
ENTRY, ENTRY,
FALSE_POSITIVE, FALSE_POSITIVE {
FALSE_RECOMMENDATION @Override
public EntryType toEntryType() {
return EntryType.FALSE_POSITIVE;
}
},
FALSE_RECOMMENDATION {
@Override
public EntryType toEntryType() {
return EntryType.FALSE_RECOMMENDATION;
}
};
public EntryType toEntryType() {
return EntryType.ENTITY;
}
} }