diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DossierResource.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DossierResource.java index 6f7f51508..b8ed39205 100644 --- a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DossierResource.java +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DossierResource.java @@ -1,11 +1,13 @@ package com.iqser.red.service.persistence.service.v1.api.resources; +import com.iqser.red.service.persistence.service.v1.api.model.common.JSONPrimitive; import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.CreateOrUpdateDossierRequest; import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.Dossier; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; +import java.time.OffsetDateTime; import java.util.List; import java.util.Set; @@ -22,6 +24,15 @@ public interface DossierResource { String INCLUDE_DELETED_PARAM = "includeDeleted"; + String SINCE_REQUEST_PARAM="since"; + + String CHANGES_PATH = "/has-changes"; + + @ResponseBody + @ResponseStatus(value = HttpStatus.OK) + @GetMapping(value = REST_PATH+CHANGES_PATH, produces = MediaType.APPLICATION_JSON_VALUE) + JSONPrimitive hasChangesSince(@RequestParam(SINCE_REQUEST_PARAM) OffsetDateTime since); + @PostMapping(value = REST_PATH, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) Dossier addDossier(@RequestBody CreateOrUpdateDossierRequest dossierRequest); diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DossierStatsResource.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DossierStatsResource.java index 57ec5f47a..ab5a53e67 100644 --- a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DossierStatsResource.java +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DossierStatsResource.java @@ -4,8 +4,10 @@ import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.do import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import java.util.List; import java.util.Map; import java.util.Set; @@ -19,6 +21,6 @@ public interface DossierStatsResource { @GetMapping(value = REST_PATH + DOSSIER_ID_PATH_PARAM, produces = MediaType.APPLICATION_JSON_VALUE) DossierStats getDossierStats(@PathVariable(DOSSIER_ID_PARAM) String dossierId); - @GetMapping(value = REST_PATH, produces = MediaType.APPLICATION_JSON_VALUE) - Map getDossierStats(@RequestBody Set dossierIds); + @PostMapping(value = REST_PATH, produces = MediaType.APPLICATION_JSON_VALUE) + List getDossierStats(@RequestBody Set dossierIds); } diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/NotificationResource.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/NotificationResource.java index 23dcdb924..a83e081e6 100644 --- a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/NotificationResource.java +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/NotificationResource.java @@ -1,11 +1,13 @@ package com.iqser.red.service.persistence.service.v1.api.resources; import com.iqser.red.service.persistence.service.v1.api.model.audit.AddNotificationRequest; +import com.iqser.red.service.persistence.service.v1.api.model.common.JSONPrimitive; import com.iqser.red.service.persistence.service.v1.api.model.notification.Notification; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; +import java.time.OffsetDateTime; import java.util.List; @ResponseStatus(value = HttpStatus.OK) @@ -14,6 +16,7 @@ public interface NotificationResource { String NOTIFICATION_PATH = "/notification"; String TOGGLE_SEEN_PATH = "/toggle-seen"; String TOGGLE_READ_PATH = "/toggle-read"; + String CHANGES_PATH = "/has-changes"; String USER_ID_PARAM = "userId"; String USER_ID_PATH_PARAM = "/{" + USER_ID_PARAM + "}"; @@ -21,7 +24,13 @@ public interface NotificationResource { String INCLUDE_SEEN_PARAM = "includeSeen"; String SET_SEEN_PARAM = "setSeen"; String SET_READ_PARAM = "setRead"; + String SINCE_REQUEST_PARAM = "since"; + @ResponseBody + @ResponseStatus(value = HttpStatus.OK) + @GetMapping(value = NOTIFICATION_PATH + CHANGES_PATH + USER_ID_PATH_PARAM, produces = MediaType.APPLICATION_JSON_VALUE) + JSONPrimitive hasNewNotificationsSince(@PathVariable(USER_ID_PARAM) String userId, + @RequestParam(SINCE_REQUEST_PARAM) OffsetDateTime since); @PostMapping(value = NOTIFICATION_PATH, consumes = MediaType.APPLICATION_JSON_VALUE) void addNotification(@RequestBody AddNotificationRequest addNotificationRequest); diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/StatusResource.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/StatusResource.java index d2499bd12..c14be1f06 100644 --- a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/StatusResource.java +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/StatusResource.java @@ -6,6 +6,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; +import java.time.OffsetDateTime; import java.util.List; import java.util.Set; @@ -19,16 +20,26 @@ public interface StatusResource { String FILE_ID = "fileId"; String FILE_ID_PATH_VARIABLE = "/{" + FILE_ID + "}"; + String CHANGES_PATH = "/has-changes"; + String EXCLUDED_STATUS_PARAM = "excluded"; String APPROVER_ID_REQUEST_PARAM = "approverId"; String REVIEWER_ID_REQUEST_PARAM = "reviewerId"; + String SINCE_REQUEST_PARAM="since"; + + @ResponseBody @ResponseStatus(value = HttpStatus.OK) @GetMapping(value = STATUS_PATH, produces = MediaType.APPLICATION_JSON_VALUE) List getAllStatuses(); + @ResponseBody + @ResponseStatus(value = HttpStatus.OK) + @GetMapping(value = STATUS_PATH+DOSSIER_ID_PATH_PARAM+CHANGES_PATH, produces = MediaType.APPLICATION_JSON_VALUE) + JSONPrimitive hasChangesSince(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @RequestParam(SINCE_REQUEST_PARAM) OffsetDateTime since); + @ResponseBody @ResponseStatus(value = HttpStatus.OK) @GetMapping(value = STATUS_PATH + DOSSIER_ID_PATH_PARAM, produces = MediaType.APPLICATION_JSON_VALUE) diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/entity/dossier/DossierEntity.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/entity/dossier/DossierEntity.java index 673ebf04e..c1995b577 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/entity/dossier/DossierEntity.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/entity/dossier/DossierEntity.java @@ -33,6 +33,9 @@ public class DossierEntity { @Column private OffsetDateTime date; + @Column + private OffsetDateTime lastUpdated; + @Column(length = 4000) private String description; diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DossierPersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DossierPersistenceService.java index 2762e5551..1c877d535 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DossierPersistenceService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DossierPersistenceService.java @@ -31,6 +31,7 @@ public class DossierPersistenceService { private final DossierTemplateRepository dossierTemplateRepository; private final ReportTemplateRepository reportTemplateRepository; + public DossierEntity insert(CreateOrUpdateDossierRequest createOrUpdateDossierRequest) { DossierEntity dossier = new DossierEntity(); @@ -38,7 +39,7 @@ public class DossierPersistenceService { dossier.setId(UUID.randomUUID().toString()); dossier.setStatus(DossierStatus.ACTIVE); dossier.setDate(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); - + dossier.setLastUpdated(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); dossier.setDossierTemplate(dossierTemplateRepository.getOne(createOrUpdateDossierRequest.getDossierTemplateId())); var reportTemplates = reportTemplateRepository.findAllById(createOrUpdateDossierRequest.getReportTemplateIds()); reportTemplates.forEach(r -> r.getDossiers().add(dossier)); @@ -56,6 +57,7 @@ public class DossierPersistenceService { dossierRepository.findById(dossierId).ifPresent(dossier -> { BeanUtils.copyProperties(createOrUpdateDossierRequest, dossier); dossier.setDossierTemplate(dossierTemplateRepository.getOne(createOrUpdateDossierRequest.getDossierTemplateId())); + dossier.setLastUpdated(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); var reportTemplates = reportTemplateRepository.findAllById(createOrUpdateDossierRequest.getReportTemplateIds()); reportTemplates.forEach(r -> r.getDossiers().add(dossier)); dossier.setReportTemplates(reportTemplates); @@ -104,6 +106,7 @@ public class DossierPersistenceService { public void hardDelete(String dossierId) { dossierRepository.findById(dossierId).ifPresent(dossier -> { dossier.setHardDeletedTime(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); + dossier.setLastUpdated(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); dossier.setStatus(DossierStatus.DELETED); dossier.setSoftDeletedTime(dossier.getSoftDeletedTime() == null ? OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS) : dossier.getSoftDeletedTime()); }); @@ -117,6 +120,7 @@ public class DossierPersistenceService { throw new BadRequestException("Cannot undelete a hard-deleted dossier!"); } dossier.setStatus(DossierStatus.ACTIVE); + dossier.setLastUpdated(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); dossier.setSoftDeletedTime(null); }); } @@ -125,9 +129,13 @@ public class DossierPersistenceService { @Transactional public void markDossierAsDeleted(String dossierId, OffsetDateTime softDeletedTime) { dossierRepository.findById(dossierId).ifPresent(dossier -> { + dossier.setLastUpdated(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); dossier.setStatus(DossierStatus.DELETED); dossier.setSoftDeletedTime(softDeletedTime); }); } + public boolean hasChangesSince(OffsetDateTime since) { + return dossierRepository.existsByLastUpdatedIsAfter(since.truncatedTo(ChronoUnit.MILLIS)); + } } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/FileStatusPersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/FileStatusPersistenceService.java index 16d618678..03ccc41c7 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/FileStatusPersistenceService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/FileStatusPersistenceService.java @@ -47,7 +47,7 @@ public class FileStatusPersistenceService { file.setAdded(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); file.setUploader(uploader); file.setLastUploaded(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); - + file.setLastUpdated(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); fileRepository.save(file); } @@ -78,7 +78,7 @@ public class FileStatusPersistenceService { @Transactional public void updateFlags(String fileId, boolean hasRedactions, boolean hasHints, boolean hasImages, boolean hasSuggestions, boolean hasComments, boolean hasUpdates) { - fileRepository.updateFlags(fileId, hasRedactions, hasHints, hasImages, hasSuggestions, hasComments, hasUpdates); + fileRepository.updateFlags(fileId, OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS), hasRedactions, hasHints, hasImages, hasSuggestions, hasComments, hasUpdates); } @@ -112,6 +112,7 @@ public class FileStatusPersistenceService { fileRepository.findById(fileId).ifPresentOrElse((file) -> { file.setProcessingStatus(ProcessingStatus.PROCESSED); + file.setLastUpdated(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); file.setLastIndexed(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); }, () -> { throw new NotFoundException("Unknown file=" + fileId); @@ -123,6 +124,7 @@ public class FileStatusPersistenceService { public void updateLastOCRTime(String fileId, OffsetDateTime time) { fileRepository.findById(fileId).ifPresentOrElse((file) -> { + file.setLastUpdated(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); file.setLastOCRTime(time); }, () -> { throw new NotFoundException("Unknown file=" + fileId); @@ -134,6 +136,7 @@ public class FileStatusPersistenceService { public void updateHasComments(String fileId, boolean hasComments) { fileRepository.findById(fileId).ifPresentOrElse((file) -> { + file.setLastUpdated(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); file.setHasAnnotationComments(hasComments); }, () -> { throw new NotFoundException("Unknown file=" + fileId); @@ -144,6 +147,7 @@ public class FileStatusPersistenceService { public void updateLastManualRedaction(String fileId, OffsetDateTime date) { fileRepository.findById(fileId).ifPresentOrElse((file) -> { + file.setLastUpdated(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); file.setLastManualRedaction(date); }, () -> { throw new NotFoundException("Unknown file=" + fileId); @@ -155,6 +159,7 @@ public class FileStatusPersistenceService { public void setUpdateLastManualRedactionAndHasSuggestions(String fileId, OffsetDateTime date, boolean hasSuggestions) { fileRepository.findById(fileId).ifPresentOrElse((file) -> { + file.setLastUpdated(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); file.setLastManualRedaction(date); file.setHasSuggestions(hasSuggestions); }, () -> { @@ -171,6 +176,7 @@ public class FileStatusPersistenceService { fileRepository.findById(fileId).ifPresentOrElse((file) -> { var fileAttributeEntities = convertFileAttributes(dossierId, file, fileAttributes); file.setLastFileAttributeChange(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); + file.setLastUpdated(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); file.setFileAttributes(fileAttributeEntities); }, () -> { throw new NotFoundException("Unknown file=" + fileId); @@ -183,6 +189,7 @@ public class FileStatusPersistenceService { fileRepository.findById(fileId).ifPresentOrElse((file) -> { file.setLastManualRedaction(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); + file.setLastUpdated(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); file.setExcludedPages(excludedPages); }, () -> { throw new NotFoundException("Unknown file=" + fileId); @@ -212,6 +219,7 @@ public class FileStatusPersistenceService { fileRepository.findById(fileId).ifPresentOrElse((file) -> { file.setProcessingStatus(ProcessingStatus.DELETED); + file.setLastUpdated(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); file.setDeleted(softDeletedTime); }, () -> { throw new NotFoundException("Unknown file=" + fileId); @@ -225,6 +233,7 @@ public class FileStatusPersistenceService { fileRepository.findById(fileId).ifPresentOrElse((file) -> { file.setProcessingStatus(ProcessingStatus.DELETED); + file.setLastUpdated(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); file.setDeleted(file.getDeleted() == null ? OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS) : file.getDeleted()); file.setHardDeletedTime(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); @@ -242,6 +251,7 @@ public class FileStatusPersistenceService { if (file.getHardDeletedTime() != null) { throw new BadRequestException("Cannot undelete a hard-deleted dossier file!"); } + file.setLastUpdated(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); file.setProcessingStatus(ProcessingStatus.PROCESSED); file.setDeleted(null); }, () -> { @@ -255,6 +265,7 @@ public class FileStatusPersistenceService { fileRepository.findById(fileId).ifPresentOrElse((file) -> { file.setCurrentReviewer(currentReviewer); file.setLastReviewer(lastReviewer); + file.setLastUpdated(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); file.setWorkflowStatus(currentReviewer == null ? WorkflowStatus.UNASSIGNED :WorkflowStatus.UNDER_REVIEW); }, () -> { throw new NotFoundException("Unknown file=" + fileId); @@ -267,6 +278,7 @@ public class FileStatusPersistenceService { fileRepository.findById(fileId).ifPresentOrElse((file) -> { file.setExcluded(excluded); + file.setLastUpdated(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); file.setLastProcessed(null); file.setLastReviewer(null); file.setCurrentReviewer(null); @@ -334,4 +346,7 @@ public class FileStatusPersistenceService { } + public boolean hasChangesSince(String dossierId, OffsetDateTime since) { + return fileRepository.existsByDossierIdAndLastUpdatedIsAfter(dossierId,since); + } } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/NotificationPersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/NotificationPersistenceService.java index 0b3267a33..a53edee9a 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/NotificationPersistenceService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/NotificationPersistenceService.java @@ -11,6 +11,7 @@ import org.springframework.stereotype.Service; import javax.transaction.Transactional; import java.time.OffsetDateTime; +import java.time.temporal.ChronoUnit; import java.util.List; @Service @@ -20,6 +21,9 @@ public class NotificationPersistenceService { private final NotificationRepository notificationRepository; + public boolean hasNewNotificationsSince(String userId, OffsetDateTime since) { + return notificationRepository.existsByUserIdAndCreationDateIsAfter(userId, since.truncatedTo(ChronoUnit.MILLIS)); + } @SneakyThrows public void insertNotification(AddNotificationRequest addNotificationRequest) { diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DossierRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DossierRepository.java index 6e9afc6fc..d9684fc56 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DossierRepository.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DossierRepository.java @@ -3,5 +3,10 @@ package com.iqser.red.service.persistence.management.v1.processor.service.persis import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierEntity; import org.springframework.data.jpa.repository.JpaRepository; +import java.time.OffsetDateTime; + public interface DossierRepository extends JpaRepository { + + boolean existsByLastUpdatedIsAfter(OffsetDateTime since); + } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/FileRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/FileRepository.java index 3ca4423c0..06fc6f518 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/FileRepository.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/FileRepository.java @@ -12,11 +12,25 @@ import java.util.List; import javax.persistence.Column; public interface FileRepository extends JpaRepository { + + boolean existsByDossierIdAndLastUpdatedIsAfter(String dossierId, OffsetDateTime since); + List findByDossierId(String dossierId); @Modifying - @Query("update FileEntity e set e.hasRedactions = :hasRedactions , e.hasHints = :hasHints, e.hasSuggestions = :hasSuggestions, e.hasImages = :hasImages, e.hasUpdates = :hasUpdates, e.hasAnnotationComments = :hasComments where e.id =:fileId") - void updateFlags(String fileId, boolean hasRedactions, boolean hasHints, boolean hasImages, boolean hasSuggestions, boolean hasComments, boolean hasUpdates); + @Query("update FileEntity e set e.hasRedactions = :hasRedactions ," + + " e.hasHints = :hasHints, e.hasSuggestions = :hasSuggestions," + + " e.hasImages = :hasImages, e.hasUpdates = :hasUpdates, e.hasAnnotationComments = :hasComments, " + + " e.lastUpdated = :lastUpdated " + + " where e.id =:fileId") + void updateFlags(String fileId, + OffsetDateTime lastUpdated, + boolean hasRedactions, + boolean hasHints, + boolean hasImages, + boolean hasSuggestions, + boolean hasComments, + boolean hasUpdates); } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/NotificationRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/NotificationRepository.java index 768863b8a..4da9d32eb 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/NotificationRepository.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/NotificationRepository.java @@ -4,11 +4,14 @@ import com.iqser.red.service.persistence.management.v1.processor.entity.notifica import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; +import java.time.OffsetDateTime; import java.util.List; import java.util.Optional; public interface NotificationRepository extends JpaRepository { + boolean existsByUserIdAndCreationDateIsAfter(String userId, OffsetDateTime since); + List findByUserIdOrderByCreationDateDesc(String userId); @Query("Select n from NotificationEntity n where n.softDeleted is null and n.userId = :userId order by n.creationDate desc") diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/controller/DossierController.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/controller/DossierController.java index 041d51b8c..ff15f8e61 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/controller/DossierController.java +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/controller/DossierController.java @@ -7,6 +7,7 @@ import com.iqser.red.service.peristence.v1.server.utils.DossierMapper; import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierEntity; import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileEntity; import com.iqser.red.service.persistence.management.v1.processor.exception.DossierNotFoundException; +import com.iqser.red.service.persistence.service.v1.api.model.common.JSONPrimitive; import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.CreateOrUpdateDossierRequest; import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.Dossier; import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.DossierStatus; @@ -35,6 +36,12 @@ public class DossierController implements DossierResource { private final FileStatusService fileStatusService; private final FileService fileService; + @Override + public JSONPrimitive hasChangesSince(@RequestParam(SINCE_REQUEST_PARAM) OffsetDateTime since) { + + return JSONPrimitive.of(dossierService.hasChangesSince(since)); + } + @Override @Transactional diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/controller/DossierStatsController.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/controller/DossierStatsController.java index 827793b41..e100fd59e 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/controller/DossierStatsController.java +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/controller/DossierStatsController.java @@ -6,6 +6,7 @@ import com.iqser.red.service.persistence.service.v1.api.resources.DossierStatsRe import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.RestController; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Function; @@ -23,7 +24,7 @@ public class DossierStatsController implements DossierStatsResource { } @Override - public Map getDossierStats(Set dossierIds) { - return dossierIds.stream().collect(Collectors.toMap(Function.identity(), dossierStatsService::getDossierStats)); + public List getDossierStats(Set dossierIds) { + return dossierIds.stream().map(dossierStatsService::getDossierStats).collect(Collectors.toList()); } } diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/controller/FileStatusController.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/controller/FileStatusController.java index 9707c9637..a3b90f1ae 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/controller/FileStatusController.java +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/controller/FileStatusController.java @@ -3,6 +3,7 @@ package com.iqser.red.service.peristence.v1.server.controller; import com.iqser.red.service.peristence.v1.server.service.*; import com.iqser.red.service.peristence.v1.server.utils.FileModelMapper; import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileEntity; +import com.iqser.red.service.persistence.service.v1.api.model.common.JSONPrimitive; import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.FileModel; import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.ProcessingStatus; import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.WorkflowStatus; @@ -13,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import java.time.OffsetDateTime; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -38,6 +40,14 @@ public class FileStatusController implements StatusResource { } + @Override + public JSONPrimitive hasChangesSince(@PathVariable(DOSSIER_ID_PARAM) String dossierId, + @RequestParam(SINCE_REQUEST_PARAM) OffsetDateTime since) { + + return JSONPrimitive.of(fileStatusService.hasChangesSince(dossierId,since)); + } + + @Override public List getDossierStatus(@PathVariable(DOSSIER_ID_PARAM) String dossierId) { diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/controller/NotificationController.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/controller/NotificationController.java index 1d250ff74..86295f103 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/controller/NotificationController.java +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/controller/NotificationController.java @@ -1,7 +1,10 @@ package com.iqser.red.service.peristence.v1.server.controller; +import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.NotificationPersistenceService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.NotificationPreferencesPersistenceService; import com.iqser.red.service.persistence.service.v1.api.model.audit.AddNotificationRequest; +import com.iqser.red.service.persistence.service.v1.api.model.common.JSONPrimitive; import com.iqser.red.service.persistence.service.v1.api.model.notification.Notification; import com.iqser.red.service.persistence.service.v1.api.resources.NotificationResource; import lombok.RequiredArgsConstructor; @@ -21,12 +24,25 @@ public class NotificationController implements NotificationResource { private final NotificationPersistenceService notificationPersistenceService; + private final NotificationPreferencesPersistenceService notificationPreferencesPersistenceService; - public void addNotification(@RequestBody AddNotificationRequest addNotificationRequest) { - - notificationPersistenceService.insertNotification(addNotificationRequest); + @Override + public JSONPrimitive hasNewNotificationsSince(String userId, OffsetDateTime since) { + return JSONPrimitive.of(notificationPersistenceService.hasNewNotificationsSince(userId, since)); } + public void addNotification(@RequestBody AddNotificationRequest addNotificationRequest) { + try { + var userPreferences = notificationPreferencesPersistenceService.getNotificationPreferences(addNotificationRequest.getUserId()); + if (userPreferences.getInAppNotifications().contains(addNotificationRequest.getNotificationType()) + || userPreferences.getEmailNotifications().contains(addNotificationRequest.getNotificationType())) { + notificationPersistenceService.insertNotification(addNotificationRequest); + } + } catch (NotFoundException e) { + notificationPersistenceService.insertNotification(addNotificationRequest); + } + + } public void toggleSeen(@PathVariable(USER_ID_PARAM) String userId, @RequestBody List notificationIds, @RequestParam(SET_SEEN_PARAM) boolean setSeen) { diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/service/DossierService.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/service/DossierService.java index 8f96c1ed0..8b8f18b9f 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/service/DossierService.java +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/service/DossierService.java @@ -94,4 +94,7 @@ public class DossierService { return dossierPersistenceService.findAllDossiers(); } + public boolean hasChangesSince(OffsetDateTime since) { + return dossierPersistenceService.hasChangesSince(since); + } } diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/service/FileStatusService.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/service/FileStatusService.java index ef551e8da..54e8931b3 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/service/FileStatusService.java +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/service/FileStatusService.java @@ -10,6 +10,7 @@ import com.iqser.red.service.persistence.management.v1.processor.entity.dossier. import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileEntity; import com.iqser.red.service.persistence.management.v1.processor.exception.UserNotFoundException; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.*; +import com.iqser.red.service.persistence.service.v1.api.model.common.JSONPrimitive; import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.FileType; import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.ProcessingStatus; import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.WorkflowStatus; @@ -344,4 +345,7 @@ public class FileStatusService { return fileAttributeList; } + public boolean hasChangesSince(String dossierId, OffsetDateTime since) { + return fileStatusPersistenceService.hasChangesSince(dossierId,since); + } } diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DossierStatsTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DossierStatsTest.java index af597611a..9713fa4c2 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DossierStatsTest.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DossierStatsTest.java @@ -10,15 +10,12 @@ import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.do import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.DossierStats; import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.ProcessingStatus; import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.WorkflowStatus; - -import org.hibernate.jdbc.Work; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; - import java.util.HashSet; -import java.util.Map; +import java.util.List; import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; @@ -57,7 +54,7 @@ public class DossierStatsTest extends AbstractPersistenceServerServiceTest { // alter file 1 var loadedFile1 = fileClient.getFileStatus(dossier1.getId(), file1.getId()); assertThat(loadedFile1.isHasRedactions()).isFalse(); - fileRepository.findById(file1.getId()).ifPresent((file)->{ + fileRepository.findById(file1.getId()).ifPresent((file) -> { file.setNumberOfAnalyses(NUMBER_PAGES_ANALYZED); file.setHasRedactions(true); file.setHasHints(true); @@ -68,18 +65,18 @@ public class DossierStatsTest extends AbstractPersistenceServerServiceTest { assertThat(loadedFile1.isHasRedactions()).isTrue(); // alter file 2 - fileRepository.findById(file2.getId()).ifPresent((file)->{ + fileRepository.findById(file2.getId()).ifPresent((file) -> { file.setHasSuggestions(true); fileRepository.save(file); }); // second dossier - dossier2 = dossierTesterAndProvider.provideTestDossier(dossierTemplate,"Dossier2"); + dossier2 = dossierTesterAndProvider.provideTestDossier(dossierTemplate, "Dossier2"); var file3 = fileTesterAndProvider.testAndProvideFile(dossier2, "file3"); var file4 = fileTesterAndProvider.testAndProvideFile(dossier2, "file4"); //alter file 4 - fileRepository.findById(file4.getId()).ifPresent((file)->{ + fileRepository.findById(file4.getId()).ifPresent((file) -> { file.setHasHints(true); file.setWorkflowStatus(WorkflowStatus.APPROVED); fileRepository.save(file); @@ -106,18 +103,18 @@ public class DossierStatsTest extends AbstractPersistenceServerServiceTest { dossierIds.add(dossier1.getId()); dossierIds.add(dossier2.getId()); - Map dossierStatsMap = dossierStatsClient.getDossierStats(dossierIds); + List dossierStatsList = dossierStatsClient.getDossierStats(dossierIds); // get the result for dossier2 - DossierStats dossierStats2 = dossierStatsMap.get(dossier2.getId()); - assertThat(dossierStats2.getNumberOfFiles()).isEqualTo(2); - assertThat(dossierStats2.getNumberOfAnalysedPages()).isEqualTo(0); - assertThat(dossierStats2.isHasRedactionsFilePresent()).isFalse(); - assertThat(dossierStats2.isHasHintsNoRedactionsFilePresent()).isTrue(); - assertThat(dossierStats2.isHasSuggestionsFilePresent()).isFalse(); - assertThat(dossierStats2.isHasUpdatesFilePresent()).isFalse(); - assertThat(dossierStats2.isHasNoFlagsFilePresent()).isTrue(); - assertThat(dossierStats2.getFileCountPerWorkflowStatus().get(WorkflowStatus.UNASSIGNED)).isEqualTo(1); - assertThat(dossierStats2.getFileCountPerWorkflowStatus().get(WorkflowStatus.APPROVED)).isEqualTo(1); + DossierStats dossierStats = dossierStatsList.stream().filter(d -> d.getDossierId().equals(dossier2.getId())).findAny().get(); + assertThat(dossierStats.getNumberOfFiles()).isEqualTo(2); + assertThat(dossierStats.getNumberOfAnalysedPages()).isEqualTo(0); + assertThat(dossierStats.isHasRedactionsFilePresent()).isFalse(); + assertThat(dossierStats.isHasHintsNoRedactionsFilePresent()).isTrue(); + assertThat(dossierStats.isHasSuggestionsFilePresent()).isFalse(); + assertThat(dossierStats.isHasUpdatesFilePresent()).isFalse(); + assertThat(dossierStats.isHasNoFlagsFilePresent()).isTrue(); + assertThat(dossierStats.getFileCountPerWorkflowStatus().get(WorkflowStatus.UNASSIGNED)).isEqualTo(1); + assertThat(dossierStats.getFileCountPerWorkflowStatus().get(WorkflowStatus.APPROVED)).isEqualTo(1); } }