diff --git a/persistence-service-v1/persistence-service-external-api-impl-v2/pom.xml b/persistence-service-v1/persistence-service-external-api-impl-v2/pom.xml
new file mode 100644
index 000000000..f68c42c68
--- /dev/null
+++ b/persistence-service-v1/persistence-service-external-api-impl-v2/pom.xml
@@ -0,0 +1,39 @@
+
+
+
+
+ persistence-service-v1
+ com.iqser.red.service
+ 2.0-SNAPSHOT
+
+
+ 4.0.0
+
+ persistence-service-external-api-impl-v2
+
+ 1.7.30
+ UTF-8
+
+
+
+
+ com.iqser.red.service
+ persistence-service-processor-v1
+ ${project.version}
+
+
+ com.iqser.red.service
+ persistence-service-external-api-v2
+ ${project.version}
+
+
+ com.iqser.red.service
+ persistence-service-external-api-impl-v1
+ ${project.version}
+
+
+
+
+
diff --git a/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/PersistenceServiceExternalApiConfigurationV2.java b/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/PersistenceServiceExternalApiConfigurationV2.java
new file mode 100644
index 000000000..8e71889d8
--- /dev/null
+++ b/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/PersistenceServiceExternalApiConfigurationV2.java
@@ -0,0 +1,11 @@
+package com.iqser.red.persistence.service.v2.external.api.impl;
+
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+
+@Configuration
+@ComponentScan
+public class PersistenceServiceExternalApiConfigurationV2 {
+
+}
diff --git a/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/ComponentControllerV2.java b/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/ComponentControllerV2.java
new file mode 100644
index 000000000..fbd3ef487
--- /dev/null
+++ b/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/ComponentControllerV2.java
@@ -0,0 +1,35 @@
+package com.iqser.red.persistence.service.v2.external.api.impl.controller;
+
+import com.iqser.red.service.persistence.service.v2.api.external.model.FileComponents;
+import com.iqser.red.service.persistence.service.v2.api.external.resource.ComponentResource;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import static com.iqser.red.service.persistence.service.v2.api.external.resource.DossierResource.DOSSIER_ID_PARAM;
+import static com.iqser.red.service.persistence.service.v2.api.external.resource.DossierTemplateResource.DOSSIER_TEMPLATE_ID_PARAM;
+import static com.iqser.red.service.persistence.service.v2.api.external.resource.FileResource.FILE_ID_PARAM;
+
+@RestController
+@Tag(name = "components", description = "Provides operation related to components")
+public class ComponentControllerV2 implements ComponentResource {
+
+
+ @Override
+ public FileComponents getComponents(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
+ @PathVariable(DOSSIER_ID_PARAM) String dossierId,
+ @PathVariable(FILE_ID_PARAM) String fileId,
+ @RequestParam(name = INCLUDE_DETAILS_PARAM, defaultValue = "false", required = false) boolean includeDetails) {
+ return null;
+ }
+
+ @Override
+ public FileComponents getComponentsOfDossier(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
+ @PathVariable(DOSSIER_ID_PARAM) String dossierId,
+ @RequestParam(name = INCLUDE_DETAILS_PARAM, defaultValue = "false", required = false) boolean includeDetails) {
+ return null;
+ }
+
+
+}
diff --git a/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/DossierControllerV2.java b/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/DossierControllerV2.java
new file mode 100644
index 000000000..03888775e
--- /dev/null
+++ b/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/DossierControllerV2.java
@@ -0,0 +1,81 @@
+package com.iqser.red.persistence.service.v2.external.api.impl.controller;
+
+import com.iqser.red.persistence.service.v1.external.api.impl.controller.DossierController;
+import com.iqser.red.persistence.service.v1.external.api.impl.controller.DossierTemplateController;
+import com.iqser.red.service.persistence.management.v1.processor.exception.DossierNotFoundException;
+import com.iqser.red.service.persistence.service.v1.api.shared.model.DossierRequest;
+import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.Dossier;
+import com.iqser.red.service.persistence.service.v2.api.external.model.DossierList;
+import com.iqser.red.service.persistence.service.v2.api.external.resource.DossierResource;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import static com.iqser.red.service.persistence.management.v1.processor.exception.DossierNotFoundException.DOSSIER_NOT_FOUND_MESSAGE;
+import static com.iqser.red.service.persistence.service.v2.api.external.resource.DossierTemplateResource.DOSSIER_TEMPLATE_ID_PARAM;
+
+@RestController
+@RequiredArgsConstructor
+@Tag(name = "dossiers", description = "Provides operation related to dossiers")
+public class DossierControllerV2 implements DossierResource {
+
+ private final DossierTemplateController dossierTemplateController;
+ private final DossierController dossierController;
+
+ public DossierList getDossiers(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
+ @RequestParam(name = INCLUDE_ACTIVE_PARAM, defaultValue = "true", required = false) boolean includeActive,
+ @RequestParam(name = INCLUDE_ARCHIVED_PARAM, defaultValue = "false", required = false) boolean includeArchived,
+ @RequestParam(name = INCLUDE_SOFT_DELETED_PARAM, defaultValue = "false", required = false) boolean includeSoftDeleted) {
+
+ dossierTemplateController.getDossierTemplate(dossierTemplateId);
+
+ var dossiers = dossierController.getDossiers(includeArchived, includeSoftDeleted);
+
+ if (!includeActive) {
+ return new DossierList(dossiers.stream().filter(dossier -> dossier.getSoftDeletedTime() != null || dossier.getArchivedTime() != null).toList());
+ }
+
+ return new DossierList(dossiers);
+ }
+
+
+ public Dossier getDossier(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
+ @PathVariable(DOSSIER_ID_PARAM) String dossierId,
+ @RequestParam(name = INCLUDE_ACTIVE_PARAM, defaultValue = "true", required = false) boolean includeActive,
+ @RequestParam(name = INCLUDE_ARCHIVED_PARAM, defaultValue = "false", required = false) boolean includeArchived,
+ @RequestParam(name = INCLUDE_SOFT_DELETED_PARAM, defaultValue = "false", required = false) boolean includeSoftDeleted) {
+
+ dossierTemplateController.getDossierTemplate(dossierTemplateId);
+
+ var dossier = dossierController.getDossier(dossierId, includeArchived, includeSoftDeleted);
+
+ if (!includeActive && dossier.getArchivedTime() == null && dossier.getSoftDeletedTime() == null) {
+ throw new DossierNotFoundException(String.format(DOSSIER_NOT_FOUND_MESSAGE, dossierId));
+ }
+
+ return dossier;
+ }
+
+
+ public ResponseEntity createDossierOrUpdateDossier(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of the dossier template that is used for the dossier.", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
+ @RequestBody DossierRequest dossier) {
+
+ return dossierController.createDossierOrUpdateDossier(dossier);
+ }
+
+
+ public void deleteDossier(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of the dossier template that is used for the dossier.", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
+ @Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of the dossier to retrieve.", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId) {
+
+ dossierTemplateController.getDossierTemplate(dossierTemplateId);
+
+ dossierController.deleteDossier(dossierId);
+ }
+
+
+}
diff --git a/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/DossierTemplateControllerV2.java b/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/DossierTemplateControllerV2.java
new file mode 100644
index 000000000..b8b164119
--- /dev/null
+++ b/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/DossierTemplateControllerV2.java
@@ -0,0 +1,30 @@
+package com.iqser.red.persistence.service.v2.external.api.impl.controller;
+
+import com.iqser.red.persistence.service.v1.external.api.impl.controller.DossierTemplateController;
+import com.iqser.red.service.persistence.service.v1.api.shared.model.DossierTemplateModel;
+import com.iqser.red.service.persistence.service.v2.api.external.resource.DossierTemplateResource;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RestController
+@RequiredArgsConstructor
+@Tag(name = "dossier-templates", description = "Provides operation related to dossier templates")
+public class DossierTemplateControllerV2 implements DossierTemplateResource {
+
+ private final DossierTemplateController dossierTemplateController;
+
+ public List getAllDossierTemplates() {
+ return dossierTemplateController.getAllDossierTemplates();
+ }
+
+
+ public DossierTemplateModel getDossierTemplate(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId) {
+ return dossierTemplateController.getDossierTemplate(dossierTemplateId);
+ }
+
+
+}
diff --git a/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/FileControllerV2.java b/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/FileControllerV2.java
new file mode 100644
index 000000000..b578a7b8e
--- /dev/null
+++ b/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/FileControllerV2.java
@@ -0,0 +1,142 @@
+package com.iqser.red.persistence.service.v2.external.api.impl.controller;
+
+import com.iqser.red.persistence.service.v1.external.api.impl.controller.*;
+import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
+import com.iqser.red.service.persistence.service.v1.api.shared.model.FileAttributes;
+import com.iqser.red.service.persistence.service.v1.api.shared.model.FileStatus;
+import com.iqser.red.service.persistence.service.v1.api.shared.model.FileUploadResult;
+import com.iqser.red.service.persistence.service.v2.api.external.model.FileDeleteRequest;
+import com.iqser.red.service.persistence.service.v2.api.external.model.FileStatusList;
+import com.iqser.red.service.persistence.service.v2.api.external.resource.FileResource;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static com.iqser.red.service.persistence.service.v2.api.external.resource.DossierResource.*;
+import static com.iqser.red.service.persistence.service.v2.api.external.resource.DossierTemplateResource.DOSSIER_TEMPLATE_ID_PARAM;
+
+@RestController
+@RequiredArgsConstructor
+@Tag(name = "files", description = "Provides operation related to files")
+public class FileControllerV2 implements FileResource {
+
+ private final UploadController uploadController;
+ private final StatusController statusController;
+ private final DossierController dossierController;
+ private final FileManagementController fileManagementController;
+ private final FileAttributesController fileAttributesController;
+ private final DossierTemplateController dossierTemplateController;
+
+ public FileUploadResult upload(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
+ @PathVariable(DOSSIER_ID_PARAM) String dossierId,
+ @RequestPart(name = FILE_PARAM) MultipartFile file,
+ @RequestParam(value = KEEP_MANUAL_CHANGES_PARAM, required = false, defaultValue = "false") boolean keepManualChanges) {
+
+ dossierTemplateController.getDossierTemplate(dossierTemplateId);
+
+ return uploadController.upload(file, dossierId, keepManualChanges);
+ }
+
+ public FileStatusList getDossierStatus(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
+ @PathVariable(DOSSIER_ID_PARAM) String dossierId,
+ @RequestParam(name = INCLUDE_ACTIVE_PARAM, defaultValue = "true", required = false) boolean includeActive,
+ @RequestParam(name = INCLUDE_ARCHIVED_PARAM, defaultValue = "false", required = false) boolean includeArchived,
+ @RequestParam(name = INCLUDE_SOFT_DELETED_PARAM, defaultValue = "false", required = false) boolean includeSoftDeleted) {
+
+ dossierTemplateController.getDossierTemplate(dossierTemplateId);
+
+ List fileStatusList = new ArrayList<>();
+
+ if (!includeArchived && dossierController.getDossier(dossierId, includeArchived, includeSoftDeleted).getArchivedTime() != null) {
+ return new FileStatusList(fileStatusList);
+ }
+
+ if (includeActive) {
+ fileStatusList.addAll(statusController.getDossierStatus(dossierId));
+ }
+
+ if (includeSoftDeleted) {
+ fileStatusList.addAll(statusController.getSoftDeletedDossierStatus(dossierId));
+ }
+
+ return new FileStatusList(fileStatusList);
+ }
+
+
+ public FileStatus getFileStatus(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
+ @PathVariable(DOSSIER_ID_PARAM) String dossierId,
+ @PathVariable(FILE_ID_PARAM) String fileId,
+ @RequestParam(name = INCLUDE_ACTIVE_PARAM, defaultValue = "true", required = false) boolean includeActive,
+ @RequestParam(name = INCLUDE_ARCHIVED_PARAM, defaultValue = "false", required = false) boolean includeArchived,
+ @RequestParam(name = INCLUDE_SOFT_DELETED_PARAM, defaultValue = "false", required = false) boolean includeSoftDeleted) {
+
+ dossierTemplateController.getDossierTemplate(dossierTemplateId);
+
+ boolean dossierIsArchived = dossierController.getDossier(dossierId, includeArchived, includeSoftDeleted).getArchivedTime() != null;
+ if (!includeArchived && dossierIsArchived) {
+ throw new NotFoundException("The requested file does not exist.");
+ }
+
+ var status = statusController.getFileStatus(dossierId, fileId);
+
+ if (!includeActive && !dossierIsArchived && status.getSoftDeletedTime() == null) {
+ throw new NotFoundException("The requested file does not exist.");
+ }
+
+ if (!includeSoftDeleted && status.getSoftDeletedTime() != null) {
+ throw new NotFoundException("The requested file does not exist.");
+ }
+
+ return status;
+ }
+
+
+ public void deleteFile(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
+ @PathVariable(DOSSIER_ID_PARAM) String dossierId,
+ @PathVariable(FILE_ID_PARAM) String fileId,
+ @RequestParam(name = DELETE_PERMANENTLY_PARAM, defaultValue = "false", required = false) boolean deletePermanently) {
+
+ dossierTemplateController.getDossierTemplate(dossierTemplateId);
+
+ if (deletePermanently) {
+ fileManagementController.hardDeleteFiles(dossierId, Set.of(fileId));
+ } else {
+ fileManagementController.deleteFile(dossierId, fileId);
+ }
+
+ }
+
+
+ public void deleteFiles(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
+ @PathVariable(DOSSIER_ID_PARAM) String dossierId,
+ @RequestBody FileDeleteRequest fileDeleteRequest,
+ @RequestParam(name = DELETE_PERMANENTLY_PARAM, defaultValue = "false", required = false) boolean deletePermanently) {
+
+ dossierTemplateController.getDossierTemplate(dossierTemplateId);
+
+ if (deletePermanently) {
+ fileManagementController.hardDeleteFiles(dossierId, new HashSet<>(fileDeleteRequest.getFileIds()));
+ } else {
+ fileManagementController.deleteFiles(dossierId, fileDeleteRequest.getFileIds());
+ }
+ }
+
+
+ public void setFileAttributes(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
+ @PathVariable(DOSSIER_ID_PARAM) String dossierId,
+ @PathVariable(FILE_ID_PARAM) String fileId,
+ @RequestBody FileAttributes fileAttributes) {
+
+ dossierTemplateController.getDossierTemplate(dossierTemplateId);
+
+ fileAttributesController.setFileAttributes(dossierId, fileId, fileAttributes);
+ }
+
+
+}
diff --git a/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/LicenseControllerV2.java b/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/LicenseControllerV2.java
new file mode 100644
index 000000000..1c2118b82
--- /dev/null
+++ b/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/LicenseControllerV2.java
@@ -0,0 +1,23 @@
+package com.iqser.red.persistence.service.v2.external.api.impl.controller;
+
+import com.iqser.red.persistence.service.v1.external.api.impl.controller.LicenseReportController;
+import com.iqser.red.service.persistence.service.v1.api.shared.model.license.LicenseReport;
+import com.iqser.red.service.persistence.service.v1.api.shared.model.license.LicenseReportRequest;
+import com.iqser.red.service.persistence.service.v2.api.external.resource.LicenseResource;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequiredArgsConstructor
+@Tag(name = "license", description = "Provides operation related to the license")
+public class LicenseControllerV2 implements LicenseResource {
+
+ private final LicenseReportController licenseReportController;
+
+ public LicenseReport getReport(@RequestBody LicenseReportRequest reportRequest) {
+ return licenseReportController.getReport(reportRequest);
+ }
+
+}
diff --git a/persistence-service-v1/persistence-service-external-api-impl-v2/src/test/java/com/iqser/red/persistence/service/v2/external/api/impl/IdentityTest.java b/persistence-service-v1/persistence-service-external-api-impl-v2/src/test/java/com/iqser/red/persistence/service/v2/external/api/impl/IdentityTest.java
new file mode 100644
index 000000000..96cf9ba78
--- /dev/null
+++ b/persistence-service-v1/persistence-service-external-api-impl-v2/src/test/java/com/iqser/red/persistence/service/v2/external/api/impl/IdentityTest.java
@@ -0,0 +1,16 @@
+package com.iqser.red.persistence.service.v2.external.api.impl;
+
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class IdentityTest {
+
+ @Test
+ public void mockTest() {
+
+ int i = 1;
+ assertThat(i).isEqualTo(1);
+ }
+
+}
diff --git a/persistence-service-v1/persistence-service-external-api-v2/pom.xml b/persistence-service-v1/persistence-service-external-api-v2/pom.xml
new file mode 100644
index 000000000..c18a660e6
--- /dev/null
+++ b/persistence-service-v1/persistence-service-external-api-v2/pom.xml
@@ -0,0 +1,147 @@
+
+
+
+
+ persistence-service-v1
+ com.iqser.red.service
+ 2.0-SNAPSHOT
+
+
+ 4.0.0
+
+ persistence-service-external-api-v2
+
+
+
+
+ com.iqser.red.service
+ persistence-service-external-api-v1
+ ${project.version}
+
+
+
+ com.iqser.red.service
+ persistence-service-internal-api-v1
+ ${project.version}
+
+
+ com.iqser.red.service
+ redaction-service-api-v1
+
+
+ com.iqser.red.service
+ pdftron-redaction-service-api-v1
+
+
+
+
+
+ com.iqser.red.service
+ pdftron-redaction-service-api-v1
+
+
+ com.iqser.red.service
+ redaction-service-api-v1
+
+
+ com.iqser.red.service
+ persistence-service-api-v1
+
+
+
+
+
+ com.iqser.red.service
+ redaction-service-api-v1
+
+
+ com.iqser.red.service
+ pdftron-redaction-service-api-v1
+
+
+ com.iqser.red.service
+ persistence-service-api-v1
+
+
+
+
+
+ com.iqser.red.service
+ redaction-report-service-api-v1
+
+
+ com.iqser.red.service
+ persistence-service-api-v1
+
+
+
+
+
+ com.iqser.red.service
+ search-service-api-v1
+
+
+
+ org.springdoc
+ springdoc-openapi-ui
+ provided
+
+
+
+
+ com.fasterxml.jackson.dataformat
+ jackson-dataformat-xml
+ 2.13.4
+
+
+
+ com.google.guava
+ guava
+
+
+
+
+ io.github.openfeign
+ feign-core
+ provided
+
+
+
+ org.springframework
+ spring-web
+ provided
+
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+
+
+ com.iqser.red.commons
+ jackson-commons
+
+
+
+
+ com.iqser.red.commons
+ test-commons
+ test
+
+
+ com.iqser.red.service
+ persistence-service-shared-api-v1
+ ${project.version}
+ compile
+
+
+
+
diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/Component.java b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/Component.java
new file mode 100644
index 000000000..d88d45b10
--- /dev/null
+++ b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/Component.java
@@ -0,0 +1,25 @@
+package com.iqser.red.service.persistence.service.v2.api.external.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class Component {
+
+ private String name;
+ private List values;
+ private List originalValues;
+ private String componentRule;
+
+ @Builder.Default
+ private List entityReferences = new ArrayList<>();
+
+}
diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DossierList.java b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DossierList.java
new file mode 100644
index 000000000..8ad51ae1e
--- /dev/null
+++ b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DossierList.java
@@ -0,0 +1,20 @@
+package com.iqser.red.service.persistence.service.v2.api.external.model;
+
+import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.Dossier;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class DossierList {
+
+ @Builder.Default
+ private List dossiers = new ArrayList<>();
+}
diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/Entity.java b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/Entity.java
new file mode 100644
index 000000000..b78ba1fa9
--- /dev/null
+++ b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/Entity.java
@@ -0,0 +1,27 @@
+package com.iqser.red.service.persistence.service.v2.api.external.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.*;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class Entity {
+
+ private String id;
+ private String type;
+ private String value;
+ private String entityRule;
+
+ @Builder.Default
+ private Set pages = new HashSet<>();
+
+ @Builder.Default
+ private Map> components = new HashMap<>();
+
+}
diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/FileComponents.java b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/FileComponents.java
new file mode 100644
index 000000000..d99d7fa72
--- /dev/null
+++ b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/FileComponents.java
@@ -0,0 +1,28 @@
+package com.iqser.red.service.persistence.service.v2.api.external.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class FileComponents {
+
+ private String dossierTemplateId;
+ private String dossierId;
+ private String fileId;
+ private String filename;
+
+ @Builder.Default
+ private Map> components = new HashMap<>();
+
+ private Component componentDetails;
+
+}
diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/FileComponentsList.java b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/FileComponentsList.java
new file mode 100644
index 000000000..f11919e8a
--- /dev/null
+++ b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/FileComponentsList.java
@@ -0,0 +1,19 @@
+package com.iqser.red.service.persistence.service.v2.api.external.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class FileComponentsList {
+
+ @Builder.Default
+ private List fileComponents = new ArrayList<>();
+}
diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/FileDeleteRequest.java b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/FileDeleteRequest.java
new file mode 100644
index 000000000..9dc9b9872
--- /dev/null
+++ b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/FileDeleteRequest.java
@@ -0,0 +1,19 @@
+package com.iqser.red.service.persistence.service.v2.api.external.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class FileDeleteRequest {
+
+ @Builder.Default
+ private List fileIds = new ArrayList<>();
+}
diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/FileStatusList.java b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/FileStatusList.java
new file mode 100644
index 000000000..19ed2d4bc
--- /dev/null
+++ b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/FileStatusList.java
@@ -0,0 +1,20 @@
+package com.iqser.red.service.persistence.service.v2.api.external.model;
+
+import com.iqser.red.service.persistence.service.v1.api.shared.model.FileStatus;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class FileStatusList {
+
+ @Builder.Default
+ private List files = new ArrayList<>();
+}
diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/lombok.config b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/lombok.config
new file mode 100644
index 000000000..f902278dd
--- /dev/null
+++ b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/lombok.config
@@ -0,0 +1 @@
+lombok.anyConstructor.addConstructorProperties=true
\ No newline at end of file
diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/ComponentResource.java b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/ComponentResource.java
new file mode 100644
index 000000000..3862fe1d9
--- /dev/null
+++ b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/ComponentResource.java
@@ -0,0 +1,48 @@
+package com.iqser.red.service.persistence.service.v2.api.external.resource;
+
+import com.iqser.red.service.persistence.service.v2.api.external.model.FileComponents;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import org.springframework.http.HttpStatus;
+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.RequestParam;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+import static com.iqser.red.service.persistence.service.v2.api.external.resource.DossierResource.*;
+import static com.iqser.red.service.persistence.service.v2.api.external.resource.DossierTemplateResource.*;
+import static com.iqser.red.service.persistence.service.v2.api.external.resource.FileResource.*;
+
+@ResponseStatus(value = HttpStatus.OK)
+public interface ComponentResource {
+
+ String PATH = ExternalApiConstants.BASE_PATH + DOSSIER_TEMPLATE_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE + DOSSIER_PATH + DOSSIER_ID_PATH_PARAM + FILE_PATH;
+
+ String COMPONENTS_PATH = "/components";
+
+ String BULK_COMPONENTS_PATH = "/bulk/get-components";
+
+ String INCLUDE_DETAILS_PARAM = "includeDetails";
+
+
+ @GetMapping(value = PATH + FILE_ID_PATH_VARIABLE + COMPONENTS_PATH, produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
+ @Operation(summary = "Returns the components for a file", description = "None")
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
+ FileComponents getComponents(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of the dossier template that is used for the dossier.", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
+ @Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of the dossier that contains the file.", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId,
+ @Parameter(name = FILE_ID_PARAM, description = "The identifier of the file that the components are requested for.", required = true) @PathVariable(FILE_ID_PARAM) String fileId,
+ @Parameter(name = INCLUDE_DETAILS_PARAM, description = "TODO") @RequestParam(name = INCLUDE_DETAILS_PARAM, defaultValue = "false", required = false) boolean includeDetails);
+
+
+ @GetMapping(value = PATH + BULK_COMPONENTS_PATH, produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
+ @Operation(summary = "Returns the components for all files of a dossier", description = "None")
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
+ FileComponents getComponentsOfDossier(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of the dossier template that is used for the dossier.", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
+ @Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of the dossier that contains the file.", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId,
+ @Parameter(name = INCLUDE_DETAILS_PARAM, description = "TODO") @RequestParam(name = INCLUDE_DETAILS_PARAM, defaultValue = "false", required = false) boolean includeDetails);
+
+
+}
diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/DossierResource.java b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/DossierResource.java
new file mode 100644
index 000000000..aac1bc5eb
--- /dev/null
+++ b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/DossierResource.java
@@ -0,0 +1,68 @@
+package com.iqser.red.service.persistence.service.v2.api.external.resource;
+
+import com.iqser.red.service.persistence.service.v1.api.shared.model.DossierRequest;
+import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.Dossier;
+import com.iqser.red.service.persistence.service.v2.api.external.model.DossierList;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import static com.iqser.red.service.persistence.service.v2.api.external.resource.DossierTemplateResource.*;
+
+public interface DossierResource {
+
+ String DOSSIER_PATH = "/dossiers";
+ String PATH = ExternalApiConstants.BASE_PATH + DOSSIER_TEMPLATE_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE + DOSSIER_PATH;
+ String DOSSIER_ID_PARAM = "dossierId";
+ String DOSSIER_ID_PATH_PARAM = "/{" + DOSSIER_ID_PARAM + "}";
+
+ String INCLUDE_ACTIVE_PARAM = "includeActive";
+ String INCLUDE_ARCHIVED_PARAM = "includeArchived";
+ String INCLUDE_SOFT_DELETED_PARAM = "includeSoftDeleted";
+
+
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ @GetMapping(value = PATH, produces = MediaType.APPLICATION_JSON_VALUE)
+ @Operation(summary = "Gets all existing dossiers for a specific dossier template.", description = "None")
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
+ DossierList getDossiers(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of the dossier template that is used for the dossier.", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
+ @Parameter(name = INCLUDE_ACTIVE_PARAM, description = "A Toggle to include active dossiers: If `true` (default) the response contains dossiers that are active, i.e. the dossier is neither archived nor soft-deleted.") @RequestParam(name = INCLUDE_ACTIVE_PARAM, defaultValue = "true", required = false) boolean includeActive,
+ @Parameter(name = INCLUDE_ARCHIVED_PARAM, description = "A Toggle to include archived dossiers: If `true` the response contains dossiers that have been archived.") @RequestParam(name = INCLUDE_ARCHIVED_PARAM, defaultValue = "false", required = false) boolean includeArchived,
+ @Parameter(name = INCLUDE_SOFT_DELETED_PARAM, description = "A Toggle to include soft-deleted dossiers: If `true` the response contains dossiers that have been soft-deleted, i.e. the dossiers can still be restored.") @RequestParam(name = INCLUDE_SOFT_DELETED_PARAM, defaultValue = "false", required = false) boolean includeSoftDeleted);
+
+
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ @GetMapping(value = PATH + DOSSIER_ID_PATH_PARAM, produces = MediaType.APPLICATION_JSON_VALUE)
+ @Operation(summary = "Gets an existing dossier.", description = "By default, the requested dossier will be returned only if it is active. This behavior can be changed by using and combining the respective toggle parameters.")
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Not found")})
+ Dossier getDossier(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of the dossier template that is used for the dossier.", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
+ @Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of the dossier to retrieve.", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId,
+ @Parameter(name = INCLUDE_ACTIVE_PARAM, description = "A Toggle to return an active dossier: If `true` the dossiers will be returned if it is active, i.e. the dossiers is neither archived nor deleted.") @RequestParam(name = INCLUDE_ACTIVE_PARAM, defaultValue = "true", required = false) boolean includeActive,
+ @Parameter(name = INCLUDE_ARCHIVED_PARAM, description = "A Toggle to return an archived dossier: If `true` the dossier will be returned if it is archived.") @RequestParam(name = INCLUDE_ARCHIVED_PARAM, defaultValue = "false", required = false) boolean includeArchived,
+ @Parameter(name = INCLUDE_SOFT_DELETED_PARAM, description = "A Toggle to return a soft-deleted dossier: If `true` the dossier will be returned if it has been soft-deleted, i.e. the dossier can still be restored.") @RequestParam(name = INCLUDE_SOFT_DELETED_PARAM, defaultValue = "false", required = false) boolean includeSoftDeleted);
+
+
+ @ResponseBody
+ @PostMapping(value = PATH, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
+ @Operation(summary = "Creates or updates a dossier for a specific dossier template.", description = "None")
+ @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Successfully saved the dossier."), @ApiResponse(responseCode = "400", description = "Incorrect dossier ID provided or attempted to change dossier-template for a dossier with files."), @ApiResponse(responseCode = "409", description = "Duplicate")})
+ ResponseEntity createDossierOrUpdateDossier(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of the dossier template that is used for the dossier.", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
+ @RequestBody DossierRequest dossier);
+
+
+ @ResponseStatus(value = HttpStatus.NO_CONTENT)
+ @DeleteMapping(value = PATH + DOSSIER_ID_PATH_PARAM)
+ @Operation(summary = "Deletes an existing dossier.", description = "Dossiers get soft-deleted unless specified other. A soft-deleted dossier can be restored during a retention period that is configured in the application settings. The default retention period is 96h.")
+ @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Successfully deleted the dossier."), @ApiResponse(responseCode = "404", description = "Not found")})
+ void deleteDossier(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of the dossier template that is used for the dossier.", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
+ @Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of the dossier to retrieve.", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId);
+
+
+}
diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/DossierTemplateResource.java b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/DossierTemplateResource.java
new file mode 100644
index 000000000..ae5880995
--- /dev/null
+++ b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/DossierTemplateResource.java
@@ -0,0 +1,37 @@
+package com.iqser.red.service.persistence.service.v2.api.external.resource;
+
+import com.iqser.red.service.persistence.service.v1.api.shared.model.DossierTemplateModel;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import org.springframework.http.HttpStatus;
+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.ResponseStatus;
+
+import java.util.List;
+
+@ResponseStatus(HttpStatus.OK)
+public interface DossierTemplateResource {
+
+ String DOSSIER_TEMPLATE_PATH = "/dossier-templates";
+ String PATH = ExternalApiConstants.BASE_PATH + DOSSIER_TEMPLATE_PATH;
+ String DOSSIER_TEMPLATE_ID_PARAM = "dossierTemplateId";
+ String DOSSIER_TEMPLATE_ID_PATH_VARIABLE = "/{" + DOSSIER_TEMPLATE_ID_PARAM + "}";
+
+
+ @GetMapping(value = PATH, produces = MediaType.APPLICATION_JSON_VALUE)
+ @Operation(summary = "Lists all existing DossierTemplates.", description = "None")
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "List of all existing DossierTemplates.")})
+ List getAllDossierTemplates();
+
+
+ @GetMapping(value = PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE)
+ @Operation(summary = "Get a specific DossierTemplate by its identifier.", description = "None")
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Get a specific DossierTemplate by its identifier."), @ApiResponse(responseCode = "404", description = "The DossierTemplate is not found.")})
+ DossierTemplateModel getDossierTemplate(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId);
+
+
+
+}
diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/ExternalApiConstants.java b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/ExternalApiConstants.java
new file mode 100644
index 000000000..4341946a9
--- /dev/null
+++ b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/ExternalApiConstants.java
@@ -0,0 +1,7 @@
+package com.iqser.red.service.persistence.service.v2.api.external.resource;
+
+public interface ExternalApiConstants {
+
+ String BASE_PATH = "/api";
+
+}
diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/FileResource.java b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/FileResource.java
new file mode 100644
index 000000000..112bcb2ef
--- /dev/null
+++ b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/FileResource.java
@@ -0,0 +1,96 @@
+package com.iqser.red.service.persistence.service.v2.api.external.resource;
+
+import com.iqser.red.service.persistence.service.v1.api.shared.model.FileAttributes;
+import com.iqser.red.service.persistence.service.v1.api.shared.model.FileStatus;
+import com.iqser.red.service.persistence.service.v1.api.shared.model.FileUploadResult;
+import com.iqser.red.service.persistence.service.v2.api.external.model.FileDeleteRequest;
+import com.iqser.red.service.persistence.service.v2.api.external.model.FileStatusList;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import static com.iqser.red.service.persistence.service.v2.api.external.resource.DossierResource.*;
+import static com.iqser.red.service.persistence.service.v2.api.external.resource.DossierTemplateResource.*;
+
+public interface FileResource {
+
+ String FILE_PATH = "/files";
+ String PATH = ExternalApiConstants.BASE_PATH + DOSSIER_TEMPLATE_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE + DOSSIER_PATH + DOSSIER_ID_PATH_PARAM + FILE_PATH;
+ String BULK_DELETE_PATH = "/bulk/delete";
+ String FILE_ATTRIBUTES_PATH = "/attributes";
+ String KEEP_MANUAL_CHANGES_PARAM = "keepManualChanges";
+ String DELETE_PERMANENTLY_PARAM = "deletePermanently";
+ String FILE_PARAM = "file";
+ String FILE_ID_PARAM = "fileId";
+ String FILE_ID_PATH_VARIABLE = "/{" + FILE_ID_PARAM + "}";
+
+
+ @ResponseBody
+ @ResponseStatus(value = HttpStatus.CREATED)
+ @PostMapping(value = PATH, consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
+ @Operation(summary = "Upload a file for a specific dossier.", description = "The multipart file upload returns the identifier for the uploaded file. If the dossier contains a file with the same name, it will be overwritten. Supported file types are PDF documents, Microsoft Office documents, and CSV files. Microsoft office files (file extensions `docx`, `xlsx`, or `pptx`) will be converted into PDF documents. Please note that the generated PDF might look slightly different to the original as the system does not necessarily have all fonts. However, it will generate an output on best effort to stay as close to the original as possible. CSV files are used to support a bulk annotation of file attributes. If the dossier is configured in a way to map specific fields of the CSV to file attributes and the CSV matches the mapped structure, the system will process the file or ignore it otherwise.")
+ @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "File upload succeeded. Return the fileId of the uploaded file.")})
+ FileUploadResult upload(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of the dossier template that is used for the dossier.", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
+ @Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of the dossier to where the file is to be uploaded.", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId,
+ @Parameter(name = FILE_PARAM, description = "The file to be uploaded.", required = true) @RequestPart(name = FILE_PARAM) MultipartFile file,
+ @Parameter(name = DOSSIER_ID_PARAM, description = "A Toggle to keep manual changes: Manual changes are manually added annotations or manipulations on existing ones. If set to `true` the system keeps the manual changes on re-uploading (overwriting) the file.") @RequestParam(value = KEEP_MANUAL_CHANGES_PARAM, required = false, defaultValue = "false") boolean keepManualChanges);
+
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ @GetMapping(value = PATH, produces = MediaType.APPLICATION_JSON_VALUE)
+ @Operation(summary = "Gets the status for all files in a dossier.", description = "The status contains information like ... By default, only the status of active files is returned. There are several parameters that can be combined to change the response scope.")
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
+ FileStatusList getDossierStatus(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of the dossier template that is used for the dossier.", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
+ @Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of the dossier containing the file of which the status is requested.", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId,
+ @Parameter(name = INCLUDE_ACTIVE_PARAM, description = "A Toggle to include active files: If `true` (default) the response contains the status of files that are active, i.e. they are not soft-deleted.") @RequestParam(name = INCLUDE_ACTIVE_PARAM, defaultValue = "true", required = false) boolean includeActive,
+ @Parameter(name = INCLUDE_ARCHIVED_PARAM, description = "A Toggle to include files of archived dossiers: If `true` the response contains the status of files that belong to an archived dossier. Set to `false` if you expect a `404 Not found` if the dossier is archived.") @RequestParam(name = INCLUDE_ARCHIVED_PARAM, defaultValue = "false", required = false) boolean includeArchived,
+ @Parameter(name = INCLUDE_SOFT_DELETED_PARAM, description = "A Toggle to include soft-deleted dossiers and files: If `true` the response contains the status of files that have been soft-deleted, i.e. the files can still be restored.") @RequestParam(name = INCLUDE_SOFT_DELETED_PARAM, defaultValue = "false", required = false) boolean includeSoftDeleted);
+
+
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ @GetMapping(value = PATH + FILE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE)
+ @Operation(summary = "Gets the status for a file.", description = "None")
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Not found")})
+ FileStatus getFileStatus(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of the dossier template that is used for the dossier.", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
+ @Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of the dossier containing the file of which the status is requested.", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId,
+ @Parameter(name = FILE_ID_PARAM, description = "The identifier of the file of which the status is requested.", required = true) @PathVariable(FILE_ID_PARAM) String fileId,
+ @Parameter(name = INCLUDE_ACTIVE_PARAM, description = "A Toggle to include active files: If `true` (default) the response contains the status of files that are active, i.e. they are not soft-deleted.") @RequestParam(name = INCLUDE_ACTIVE_PARAM, defaultValue = "true", required = false) boolean includeActive,
+ @Parameter(name = INCLUDE_ARCHIVED_PARAM, description = "A Toggle to include files of archived dossiers: If `true` the response contains the status of files that belong to an archived dossier. Set to `false` if you expect a `404 Not found` if the dossier is archived.") @RequestParam(name = INCLUDE_ARCHIVED_PARAM, defaultValue = "false", required = false) boolean includeArchived,
+ @Parameter(name = INCLUDE_SOFT_DELETED_PARAM, description = "A Toggle to include soft-deleted dossiers and files: If `true` the response contains the status of files that have been soft-deleted, i.e. the files can still be restored.") @RequestParam(name = INCLUDE_SOFT_DELETED_PARAM, defaultValue = "false", required = false) boolean includeSoftDeleted);
+
+
+ @ResponseStatus(value = HttpStatus.NO_CONTENT)
+ @DeleteMapping(value = PATH + FILE_ID_PATH_VARIABLE)
+ @Operation(summary = "Deletes a file for a given dossierId and FileId", description = "When deleting a file, it gets 'soft-deleted' by default, i.e. it can be restored within retention time configured in the dossier template. There is a toggle to also permanently delete the file.")
+ @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK")})
+ void deleteFile(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of the dossier template that is used for the dossier.", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
+ @Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of the dossier that contains the file.", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId,
+ @Parameter(name = FILE_ID_PARAM, description = "The identifier of the file that will be deleted.", required = true) @PathVariable(FILE_ID_PARAM) String fileId,
+ @Parameter(name = DELETE_PERMANENTLY_PARAM, description = "A Toggle to permanently delete the file: If `true` the file will be deleted permanently, i.e. in contrast to a soft-delete (value is `false`) the file cannot be restored anymore. This can be applied also on previously soft-deleted files.") @RequestParam(name = DELETE_PERMANENTLY_PARAM, defaultValue = "false", required = false) boolean deletePermanently);
+
+
+ @ResponseStatus(value = HttpStatus.NO_CONTENT)
+ @PostMapping(value = PATH + BULK_DELETE_PATH)
+ @Operation(summary = "Deletes a list of files of a specific dossier (DELETE with body payload)", description = "None")
+ @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK")})
+ void deleteFiles(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of the dossier template that is used for the dossier.", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
+ @Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of the dossier that contains the file.", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId,
+ @RequestBody FileDeleteRequest fileDeleteRequest,
+ @Parameter(name = DELETE_PERMANENTLY_PARAM, description = "A Toggle to permanently delete the file: If `true` the file will be deleted permanently, i.e. in contrast to a soft-delete (value is `false`) the file cannot be restored anymore. This can be applied also on previously soft-deleted files.") @RequestParam(name = DELETE_PERMANENTLY_PARAM, defaultValue = "false", required = false) boolean deletePermanently);
+
+
+ @Operation(summary = "Set file attributes to an existing file", description = "None")
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
+ @PostMapping(value = PATH + FILE_ID_PATH_VARIABLE + FILE_ATTRIBUTES_PATH, consumes = MediaType.APPLICATION_JSON_VALUE)
+ void setFileAttributes(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of the dossier template that is used for the dossier.", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
+ @Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of the dossier that contains the file.", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId,
+ @Parameter(name = FILE_ID_PARAM, description = "The identifier of the file of which the file attributes are set.", required = true) @PathVariable(FILE_ID_PARAM) String fileId,
+ @RequestBody FileAttributes fileAttributes);
+
+}
diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/LicenseResource.java b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/LicenseResource.java
new file mode 100644
index 000000000..8c5fc799d
--- /dev/null
+++ b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/LicenseResource.java
@@ -0,0 +1,29 @@
+package com.iqser.red.service.persistence.service.v2.api.external.resource;
+
+import com.iqser.red.service.persistence.service.v1.api.shared.model.license.LicenseReport;
+import com.iqser.red.service.persistence.service.v1.api.shared.model.license.LicenseReportRequest;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+public interface LicenseResource {
+
+ String LICENSE_PATH = "/license";
+ String PATH = ExternalApiConstants.BASE_PATH + LICENSE_PATH;
+
+ String ACTIVE_USAGE_PATH = "/active/usage";
+
+ @ResponseBody
+ @ResponseStatus(value = HttpStatus.OK)
+ @PostMapping(value = PATH + ACTIVE_USAGE_PATH, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
+ @Operation(summary = "Creates and serves license report.", description = "None")
+ @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Successfully created and served a license report.")})
+ LicenseReport getReport(@RequestBody LicenseReportRequest reportRequest);
+
+}
diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/main/resources/api/openapi.json b/persistence-service-v1/persistence-service-external-api-v2/src/main/resources/api/openapi.json
new file mode 100644
index 000000000..7704d9c6a
--- /dev/null
+++ b/persistence-service-v1/persistence-service-external-api-v2/src/main/resources/api/openapi.json
@@ -0,0 +1,2550 @@
+{
+ "openapi": "3.0.1",
+ "info": {
+ "title": "Open API Documentation",
+ "description": "TBD",
+ "version": "4.0"
+ },
+ "servers": [
+ {
+ "url": "https://staging.documine.ai",
+ "description": "Generated server url"
+ }
+ ],
+ "security": [
+ {
+ "FF-OAUTH": []
+ }
+ ],
+ "paths": {
+ "/api/dossier-templates": {
+ "get": {
+ "tags": [
+ "dossier-template-controller"
+ ],
+ "summary": "Lists all existing DossierTemplates.",
+ "description": "TODO",
+ "operationId": "getAllDossierTemplates",
+ "responses": {
+ "404": {
+ "description": "Not Found",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "Conflict",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Internal Server Error",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "200": {
+ "description": "List of all existing DossierTemplates.",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/DossierTemplateList"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/api/dossier-template/{dossierTemplateId}": {
+ "get": {
+ "tags": [
+ "dossier-template-controller"
+ ],
+ "summary": "Get a specific DossierTemplate by its identifier.",
+ "description": "TODO",
+ "operationId": "getDossierTemplate",
+ "parameters": [
+ {
+ "name": "dossierTemplateId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The identifier of the dossier template to retrieve."
+ }
+ ],
+ "responses": {
+ "404": {
+ "description": "The DossierTemplate is not found.",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "Conflict",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Internal Server Error",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "200": {
+ "description": "The DossierTemplate.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/DossierTemplate"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/api/dossier-templates/{dossierTemplateId}/dossiers": {
+ "get": {
+ "tags": [
+ "dossier-controller"
+ ],
+ "summary": "Gets all existing dossiers for a specific dossier template.",
+ "description": "TODO",
+ "operationId": "getDossiers",
+ "parameters": [
+ {
+ "name": "dossierTemplateId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The identifier of the dossier template that is used for the dossier."
+ },
+ {
+ "name": "includeActive",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "boolean",
+ "default": true
+ },
+ "description": "A Toggle to include active dossiers: If `true` (default) the response contains dossiers that are active, i.e. the dossier is neither archived nor soft-deleted."
+ },
+ {
+ "name": "includeArchived",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "boolean",
+ "default": false
+ },
+ "description": "A Toggle to include archived dossiers: If `true` the response contains dossiers that have been archived."
+ },
+ {
+ "name": "includeSoftDeleted",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "boolean",
+ "default": false
+ },
+ "description": "A Toggle to include soft-deleted dossiers: If `true` the response contains dossiers that have been soft-deleted, i.e. the dossiers can still be restored."
+ }
+ ],
+ "responses": {
+ "404": {
+ "description": "Not Found",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "Conflict",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Internal Server Error",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "200": {
+ "description": "OK",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/DossierList"
+ }
+ }
+ }
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "dossier-controller"
+ ],
+ "summary": "Creates or updates a dossier for a specific dossier template.",
+ "description": "TODO",
+ "operationId": "createDossierOrUpdateDossier",
+ "parameters": [
+ {
+ "name": "dossierTemplateId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The `dossierTemplateId` that is used for the dossier."
+ }
+ ],
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/DossierRequest"
+ }
+ }
+ },
+ "required": true
+ },
+ "responses": {
+ "404": {
+ "description": "Not Found",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Incorrect dossier ID provided or attempted to change dossier-template for a dossier with files.",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "Duplicate",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Internal Server Error",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "Successfully saved the dossier.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Dossier"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/api/dossier-templates/{dossierTemplateId}/dossiers/{dossierId}": {
+ "get": {
+ "tags": [
+ "dossier-controller"
+ ],
+ "summary": "Gets an existing dossier.",
+ "description": "By default, the requested dossier will be returned only if it is active. This behavior can be changed by using and combining the respective toggle parameters.",
+ "operationId": "getDossier",
+ "parameters": [
+ {
+ "name": "dossierTemplateId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The identifier of the dossier template that is used for the dossier."
+ },
+ {
+ "name": "dossierId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The identifier of the dossier to retrieve."
+ },
+ {
+ "name": "includeActive",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "boolean",
+ "default": true
+ },
+ "description": "A Toggle to return an active dossier: If `true` the dossiers will be returned if it is active, i.e. the dossiers is neither archived nor deleted."
+ },
+ {
+ "name": "includeArchived",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "boolean",
+ "default": false
+ },
+ "description": "A Toggle to return an archived dossier: If `true` the dossier will be returned if it is archived."
+ },
+ {
+ "name": "includeSoftDeleted",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "boolean",
+ "default": false
+ },
+ "description": "A Toggle to return a soft-deleted dossier: If `true` the dossier will be returned if it has been soft-deleted, i.e. the dossier can still be restored."
+ }
+ ],
+ "responses": {
+ "404": {
+ "description": "Not found",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "Conflict",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Internal Server Error",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Dossier"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "dossier-controller"
+ ],
+ "summary": "Deletes an existing dossier.",
+ "description": "Dossiers get soft-deleted unless specified other. A soft-deleted dossier can be restored during a retention period that is configured in the application settings. The default retention period is 96h.",
+ "operationId": "deleteDossier",
+ "parameters": [
+ {
+ "name": "dossierTemplateId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The identifier of the dossier template that is used for the dossier."
+ },
+ {
+ "name": "dossierId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The identifier of the dossier to delete."
+ },
+ {
+ "name": "deletePermanently",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "boolean",
+ "default": false
+ },
+ "description": "A Toggle to permanently delete the dossier: If `true`the dossier will be deleted permanently, i.e. in contrast to a soft-delete (value is `false`) the dossier cannot be restored anymore. This can be applied also on previously soft-deleted dossiers."
+ }
+ ],
+ "responses": {
+ "404": {
+ "description": "Not found",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "Conflict",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Internal Server Error",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "204": {
+ "description": "Successfully deleted the dossier."
+ }
+ }
+ }
+ },
+ "/api/dossier-templates/{dossierTemplateId}/dossiers/{dossierId}/files": {
+ "post": {
+ "tags": [
+ "file-controller"
+ ],
+ "summary": "Upload a file for a specific dossier.",
+ "description": "The multipart file upload returns the identifier for the uploaded file. If the dossier contains a file with the same name, it will be overwritten. Supported file types are PDF documents, Microsoft Office documents, and CSV files. Microsoft office files (file extensions `docx`, `xlsx`, or `pptx`) will be converted into PDF documents. Please note that the generated PDF might look slightly different to the original as the system does not necessarily have all fonts. However, it will generate an output on best effort to stay as close to the original as possible. CSV files are used to support a bulk annotation of file attributes. If the dossier is configured in a way to map specific fields of the CSV to file attributes and the CSV matches the mapped structure, the system will process the file or ignore it otherwise.",
+ "operationId": "upload",
+ "parameters": [
+ {
+ "name": "dossierTemplateId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The identifier of the dossier template that is used for the dossier."
+ },
+ {
+ "name": "dossierId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The identifier of the dossier to where the file is to be uploaded."
+ },
+ {
+ "name": "keepManualChanges",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "boolean",
+ "default": false
+ },
+ "description": "A Toggle to keep manual changes: Manual changes are manually added annotations or manipulations on existing ones. If set to `true` the system keeps the manual changes on re-uploading (overwriting) the file."
+ }
+ ],
+ "requestBody": {
+ "content": {
+ "multipart/form-data": {
+ "schema": {
+ "required": [
+ "file"
+ ],
+ "type": "object",
+ "properties": {
+ "file": {
+ "$ref": "#/components/schemas/MultipartFile"
+ }
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "404": {
+ "description": "Not Found",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "Conflict",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Internal Server Error",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "File upload succeeded. Return the fileId of the uploaded file.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FileUploadResult"
+ }
+ }
+ }
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "file-controller"
+ ],
+ "summary": "Gets the status for all files of a specific dossier.",
+ "description": "The status contains information like ... By default, only the status of active files is returned. There are several parameters that can be combined to change the response scope.",
+ "operationId": "getDossierStatus",
+ "parameters": [
+ {
+ "name": "dossierTemplateId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The identifier of the dossier template that is used for the dossier."
+ },
+ {
+ "name": "dossierId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The identifier of the dossier containing the file of which the status is requested."
+ },
+ {
+ "name": "includeActive",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "boolean",
+ "default": true
+ },
+ "description": "A Toggle to include active files: If `true` (default) the response contains the status of files that are active, i.e. they are not soft-deleted."
+ },
+ {
+ "name": "includeArchived",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "boolean",
+ "default": false
+ },
+ "description": "A Toggle to include files of archived dossiers: If `true` the response contains the status of files that belong to an archived dossier. Set to `false` if you expect a `404 Not found` if the dossier is archived."
+ },
+ {
+ "name": "includeSoftDeleted",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "boolean",
+ "default": false
+ },
+ "description": "A Toggle to include soft-deleted dossiers and files: If `true` the response contains the status of files that have been soft-deleted, i.e. the files can still be restored."
+ }
+ ],
+ "responses": {
+ "404": {
+ "description": "Not Found",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "Conflict",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Internal Server Error",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "200": {
+ "description": "OK",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/FileStatusList"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/api/dossier-templates/{dossierTemplateId}/dossiers/{dossierId}/files/{fileId}": {
+ "get": {
+ "tags": [
+ "status-controller"
+ ],
+ "summary": "Gets the status of a single file.",
+ "description": "TODO",
+ "operationId": "getFileStatus",
+ "parameters": [
+ {
+ "name": "dossierTemplateId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The identifier of the dossier template that is used for the dossier."
+ },
+ {
+ "name": "dossierId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The identifier of the dossier that contains the file."
+ },
+ {
+ "name": "fileId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The identifier of the file of which the status is requested."
+ },
+ {
+ "name": "includeSoftDeleted",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "boolean",
+ "default": false
+ },
+ "description": "A Toggle to return the status of soft-deleted files: If `true` the response contains the status of files that have been soft-deleted, i.e. the files can still be restored. Otherwise the response would be a `404 Not found` error if the requested file has been soft-deleted or permanently deleted."
+ }
+ ],
+ "responses": {
+ "404": {
+ "description": "Not found",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "Conflict",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Internal Server Error",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FileStatus"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "file-management-controller"
+ ],
+ "summary": "Deletes a specific file.",
+ "description": "When deleting a file, it gets 'soft-deleted' by default, i.e. it can be restored within retention time configured in the dossier template. There is a toggle to also permanently delete the file.",
+ "operationId": "deleteFile",
+ "parameters": [
+ {
+ "name": "dossierTemplateId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The identifier of the dossier template that is used for the dossier."
+ },
+ {
+ "name": "dossierId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The identifier of the dossier that contains the file."
+ },
+ {
+ "name": "fileId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The identifier of the file that will be deleted."
+ },
+ {
+ "name": "deletePermanently",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "boolean",
+ "default": false
+ },
+ "description": "A Toggle to permanently delete the file: If `true` the file will be deleted permanently, i.e. in contrast to a soft-delete (value is `false`) the file cannot be restored anymore. This can be applied also on previously soft-deleted files."
+ }
+ ],
+ "responses": {
+ "404": {
+ "description": "Not Found",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "Conflict",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Internal Server Error",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "204": {
+ "description": "OK"
+ }
+ }
+ }
+ },
+ "/api/dossier-templates/{dossierTemplateId}/dossiers/{dossierId}/files/bulk/delete": {
+ "post": {
+ "tags": [
+ "file-management-controller"
+ ],
+ "summary": "Deletes a list of files of a specific dossier (DELETE with body payload)",
+ "description": "TODO",
+ "operationId": "deleteFiles",
+ "parameters": [
+ {
+ "name": "dossierTemplateId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The identifier of the dossier template that is used for the dossier."
+ },
+ {
+ "name": "dossierId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The identifier of the dossier that contains the files."
+ },
+ {
+ "name": "deletePermanently",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "boolean",
+ "default": false
+ },
+ "description": "A Toggle to permanently delete the files: If `true` the files will be deleted permanently, i.e. in contrast to a soft-delete (value is `false`) permanently deleted files cannot be restored anymore. This can be applied also on previously soft-deleted files."
+ }
+ ],
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FileDeleteRequest"
+ }
+ }
+ },
+ "required": true
+ },
+ "responses": {
+ "404": {
+ "description": "Not Found",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "Conflict",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Internal Server Error",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "204": {
+ "description": "OK"
+ }
+ }
+ }
+ },
+ "/api/dossier-templates/{dossierTemplateId}/dossiers/{dossierId}/files/{fileId}/attributes": {
+ "post": {
+ "tags": [
+ "file-attributes-controller"
+ ],
+ "summary": "Set file attributes of an existing file",
+ "description": "TODO",
+ "operationId": "setFileAttributes",
+ "parameters": [
+ {
+ "name": "dossierTemplateId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The identifier of the dossier template that is used for the dossier."
+ },
+ {
+ "name": "dossierId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The identifier of the dossier that contains the file."
+ },
+ {
+ "name": "fileId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The identifier of the file of which the file attributes are set."
+ }
+ ],
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FileAttributes"
+ }
+ }
+ },
+ "required": true
+ },
+ "responses": {
+ "404": {
+ "description": "Not Found",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "Conflict",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Internal Server Error",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "200": {
+ "description": "OK"
+ }
+ }
+ }
+ },
+ "/api/dossier-templates/{dossierTemplateId}/dossiers/{dossierId}/files/{fileId}/components": {
+ "get": {
+ "tags": [
+ "component-controller"
+ ],
+ "summary": "Returns the component for a file",
+ "description": "TODO",
+ "operationId": "getComponents",
+ "parameters": [
+ {
+ "name": "dossierTemplateId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The identifier of the dossier template that is used for the dossier."
+ },
+ {
+ "name": "dossierId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The identifier of the dossier that contains the file."
+ },
+ {
+ "name": "fileId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The identifier of the file of which the file attributes are set."
+ },
+ {
+ "name": "includeDetails",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "boolean",
+ "default": false
+ },
+ "description": "TODO"
+ }
+ ],
+ "responses": {
+ "404": {
+ "description": "Not Found",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "Conflict",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Internal Server Error",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FileComponents"
+ }
+ },
+ "application/xml": {
+ "schema": {
+ "$ref": "#/components/schemas/FileComponents"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/api/dossier-templates/{dossierTemplateId}/dossiers/{dossierId}/files/bulk/get-components": {
+ "get": {
+ "tags": [
+ "component-controller"
+ ],
+ "summary": "Returns the RSS response for all files of a dossier",
+ "description": "TODO",
+ "operationId": "getComponentsOfDossier",
+ "parameters": [
+ {
+ "name": "dossierTemplateId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The identifier of the dossier template that is used for the dossier."
+ },
+ {
+ "name": "dossierId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The identifier of the dossier that contains the file."
+ },
+ {
+ "name": "fileId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "The identifier of the file of which the file attributes are set."
+ },
+ {
+ "name": "includeDetails",
+ "in": "query",
+ "required": false,
+ "schema": {
+ "type": "boolean",
+ "default": false
+ },
+ "description": "TODO"
+ }
+ ],
+ "responses": {
+ "404": {
+ "description": "Not Found",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "Conflict",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Internal Server Error",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FileComponentsList"
+ }
+ },
+ "application/xml": {
+ "schema": {
+ "$ref": "#/components/schemas/FileComponentsList"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/api/license/active/usage": {
+ "post": {
+ "tags": [
+ "license-controller"
+ ],
+ "summary": "Creates and serves license report.",
+ "description": "TODO",
+ "operationId": "getReport",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/LicenseReportRequest"
+ }
+ }
+ },
+ "required": true
+ },
+ "responses": {
+ "404": {
+ "description": "Not Found",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "Conflict",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Internal Server Error",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorMessage"
+ }
+ }
+ }
+ },
+ "200": {
+ "description": "Successfully created and served a license report.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/LicenseReport"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "ErrorMessage": {
+ "type": "object",
+ "properties": {
+ "timestamp": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "message": {
+ "type": "string"
+ }
+ }
+ },
+ "MultipartFile": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "originalFilename": {
+ "type": "string"
+ },
+ "contentType": {
+ "type": "string"
+ },
+ "empty": {
+ "type": "boolean"
+ },
+ "size": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "bytes": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "format": "byte"
+ }
+ },
+ "inputStream": {
+ "type": "object"
+ },
+ "resource": {
+ "$ref": "#/components/schemas/Resource"
+ }
+ }
+ },
+ "Resource": {
+ "type": "object",
+ "properties": {
+ "readable": {
+ "type": "boolean"
+ },
+ "open": {
+ "type": "boolean"
+ },
+ "file": {
+ "type": "string",
+ "format": "binary"
+ },
+ "url": {
+ "type": "string",
+ "format": "url"
+ },
+ "uri": {
+ "type": "string",
+ "format": "uri"
+ },
+ "contentAsByteArray": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "format": "byte"
+ }
+ },
+ "filename": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "inputStream": {
+ "type": "object"
+ }
+ }
+ },
+ "FileUploadResult": {
+ "type": "object",
+ "properties": {
+ "fileIds": {
+ "type": "array",
+ "description": "List of fileIds generated for uploaded file(s).",
+ "items": {
+ "type": "string",
+ "description": "List of fileIds generated for uploaded file(s)."
+ }
+ },
+ "processedAttributes": {
+ "type": "array",
+ "description": "List processed file attributes, in case the upload contained a CSV.",
+ "items": {
+ "type": "string",
+ "description": "List processed file attributes, in case the upload contained a CSV."
+ }
+ },
+ "processedFileIds": {
+ "type": "array",
+ "description": "List processed fileIds, in case the upload contained a CSV.",
+ "items": {
+ "type": "string",
+ "description": "List processed fileIds, in case the upload contained a CSV."
+ }
+ }
+ },
+ "description": "Object containing information about a successfully uploaded file."
+ },
+ "FileAttributes": {
+ "type": "object",
+ "properties": {
+ "attributeIdToValue": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "example": {
+ "myFileAttribute": "This is a file attribute value",
+ "yetAnotherFileAttribute": "This is yet another file attribute value",
+ "numericValuesNeedToBeStrings": "1234"
+ },
+ "description": "Additional file attributes that can be set or imported"
+ },
+ "FileErrorInfo": {
+ "type": "object",
+ "properties": {
+ "cause": {
+ "type": "string"
+ },
+ "queue": {
+ "type": "string"
+ },
+ "service": {
+ "type": "string"
+ },
+ "timestamp": {
+ "type": "string",
+ "format": "date-time"
+ }
+ },
+ "description": "The error information for the error state of the file"
+ },
+ "FileStatusList": {
+ "type": "object",
+ "properties": {
+ "dossiers": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/FileStatus"
+ }
+ }
+ }
+ },
+ "FileStatus": {
+ "type": "object",
+ "properties": {
+ "dossierId": {
+ "type": "string",
+ "description": "The ID of the dossier the file belongs to."
+ },
+ "dossierTemplateId": {
+ "type": "string",
+ "description": "The ID of the dossier template of the dossier the file belongs to."
+ },
+ "dossierStatusId": {
+ "type": "string",
+ "description": "The ID of the dossier status of the dossier the file belongs to."
+ },
+ "fileId": {
+ "type": "string",
+ "description": "The ID of the file."
+ },
+ "filename": {
+ "type": "string",
+ "description": "The file's name."
+ },
+ "dossierArchived": {
+ "type": "boolean",
+ "description": "Tells if the dossier of this file is archived or not."
+ },
+ "processingStatus": {
+ "type": "string",
+ "description": "The processing status of a file",
+ "enum": [
+ "ANALYSE",
+ "ERROR",
+ "FULLREPROCESS",
+ "IMAGE_ANALYZING",
+ "INDEXING",
+ "NER_ANALYZING",
+ "OCR_PROCESSING_QUEUED",
+ "OCR_PROCESSING",
+ "PROCESSED",
+ "PROCESSING",
+ "REPROCESS",
+ "UNPROCESSED",
+ "FULL_PROCESSING",
+ "PRE_PROCESSING_QUEUED",
+ "PRE_PROCESSING",
+ "PRE_PROCESSED",
+ "FIGURE_DETECTION_ANALYZING",
+ "TABLE_PARSING_ANALYZING"
+ ]
+ },
+ "workflowStatus": {
+ "type": "string",
+ "description": "The workflow status of a file",
+ "enum": [
+ "NEW",
+ "UNDER_REVIEW",
+ "UNDER_APPROVAL",
+ "APPROVED"
+ ]
+ },
+ "numberOfPages": {
+ "type": "integer",
+ "description": "The number of pages of the file.",
+ "format": "int32"
+ },
+ "added": {
+ "type": "string",
+ "description": "Date and time when the file was added to the system.",
+ "format": "date-time"
+ },
+ "lastUpdated": {
+ "type": "string",
+ "description": "Date and time when the file was last updated.",
+ "format": "date-time"
+ },
+ "numberOfAnalyses": {
+ "type": "integer",
+ "description": "The number of times the file has been analyzed.",
+ "format": "int32"
+ },
+ "assignee": {
+ "type": "string",
+ "description": "The current assignee's (if any) user id."
+ },
+ "lastReviewer": {
+ "type": "string",
+ "description": "The last reviewer's (if any) user id."
+ },
+ "lastApprover": {
+ "type": "string",
+ "description": "The last approvers's (if any) user id."
+ },
+ "hasRedactions": {
+ "type": "boolean",
+ "description": "Shows if any redactions were found during the analysis."
+ },
+ "hasHints": {
+ "type": "boolean",
+ "description": "Shows if any hints were found during the analysis."
+ },
+ "hasRequests": {
+ "type": "boolean",
+ "description": "Shows if any requests were found during the analysis."
+ },
+ "hasUpdates": {
+ "type": "boolean",
+ "description": "Shows if there is any change between the previous and current analysis."
+ },
+ "hasImages": {
+ "type": "boolean",
+ "description": "Shows if any images were found during the analysis."
+ },
+ "ocrStartTime": {
+ "type": "string",
+ "description": "Shows if this file has been OCRed by us. Start time of OCR Process",
+ "format": "date-time"
+ },
+ "numberOfPagesToOCR": {
+ "type": "integer",
+ "description": "Number of pages to be OCRed by us",
+ "format": "int32"
+ },
+ "numberOfOCRedPages": {
+ "type": "integer",
+ "description": "Number of pages already OCRed by us",
+ "format": "int32"
+ },
+ "ocrEndTime": {
+ "type": "string",
+ "description": "Shows if this file has been OCRed by us. End time of OCR Process",
+ "format": "date-time"
+ },
+ "hasAnnotationComments": {
+ "type": "boolean",
+ "description": "Shows if this file has comments on annotations."
+ },
+ "uploader": {
+ "type": "string",
+ "description": "The ID of the user who uploaded the file."
+ },
+ "dictionaryVersion": {
+ "type": "integer",
+ "description": "Shows which dictionary versions was used during the analysis.",
+ "format": "int64"
+ },
+ "rulesVersion": {
+ "type": "integer",
+ "description": "Shows which rules versions was used during the analysis.",
+ "format": "int64"
+ },
+ "legalBasisVersion": {
+ "type": "integer",
+ "description": "Shows which legal basis versions was used during the analysis.",
+ "format": "int64"
+ },
+ "excluded": {
+ "type": "boolean",
+ "description": "Shows if the file was excluded from analysis."
+ },
+ "lastProcessed": {
+ "type": "string",
+ "description": "Shows the last date of a successful analysis.",
+ "format": "date-time"
+ },
+ "lastLayoutProcessed": {
+ "type": "string",
+ "description": "Shows the last date of a layout parsing.",
+ "format": "date-time"
+ },
+ "approvalDate": {
+ "type": "string",
+ "description": "Shows the date of approval, if approved.",
+ "format": "date-time"
+ },
+ "lastUploaded": {
+ "type": "string",
+ "description": "Shows last date the document was uploaded.",
+ "format": "date-time"
+ },
+ "analysisDuration": {
+ "type": "integer",
+ "description": "Shows how long the last analysis took",
+ "format": "int64"
+ },
+ "fileAttributes": {
+ "$ref": "#/components/schemas/FileAttributes"
+ },
+ "dossierDictionaryVersion": {
+ "type": "integer",
+ "description": "Shows which dossier dictionary versions was used during the analysis.",
+ "format": "int64"
+ },
+ "analysisRequired": {
+ "type": "boolean",
+ "description": "Shows if the file requires reanalysis."
+ },
+ "excludedPages": {
+ "uniqueItems": true,
+ "type": "array",
+ "description": "Set of excluded pages for this file.",
+ "items": {
+ "type": "integer",
+ "description": "Set of excluded pages for this file.",
+ "format": "int32"
+ }
+ },
+ "softDeletedTime": {
+ "type": "string",
+ "description": "Shows if the file is soft deleted.",
+ "format": "date-time"
+ },
+ "lastFileAttributeChange": {
+ "type": "string",
+ "description": "Date and time when the files attributes was last updated.",
+ "format": "date-time"
+ },
+ "hasSuggestions": {
+ "type": "boolean",
+ "description": "Shows if there are any Suggestions in this file."
+ },
+ "excludedFromAutomaticAnalysis": {
+ "type": "boolean",
+ "description": "Shows if the file is excluded from automatic analysis."
+ },
+ "redactionModificationDate": {
+ "type": "string",
+ "description": "Shows the last redaction modification date of this file.",
+ "format": "date-time"
+ },
+ "fileManipulationDate": {
+ "type": "string",
+ "description": "Shows the date of the last manipulation of this file.",
+ "format": "date-time"
+ },
+ "lastManualChangeDate": {
+ "type": "string",
+ "description": "Shows the date of the last manual change of an annotation of this file.",
+ "format": "date-time"
+ },
+ "hasHighlights": {
+ "type": "boolean",
+ "description": "Shows if there are highlights to remove or convert for this file."
+ },
+ "fileSize": {
+ "type": "integer",
+ "description": "Size of the optimized, internally stored file.",
+ "format": "int64"
+ },
+ "analysisVersion": {
+ "type": "integer",
+ "description": "Analysis Version.",
+ "format": "int32"
+ },
+ "lastIndexed": {
+ "type": "string",
+ "description": "Last time the file was indexed in ES.",
+ "format": "date-time"
+ },
+ "fileErrorInfo": {
+ "$ref": "#/components/schemas/FileErrorInfo"
+ },
+ "lastOCRTime": {
+ "type": "string",
+ "description": "Shows if this file has been OCRed by us. Last Time of OCR.",
+ "format": "date-time"
+ },
+ "id": {
+ "type": "string"
+ }
+ },
+ "description": "Object containing information on a specific file."
+ },
+ "FileDeleteRequest": {
+ "type": "object",
+ "properties": {
+ "fileIds": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "LicenseReportRequest": {
+ "type": "object",
+ "properties": {
+ "startDate": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "endDate": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "LicenseReport": {
+ "type": "object",
+ "properties": {
+ "totalFilesUploadedBytes": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "activeFilesUploadedBytes": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "trashFilesUploadedBytes": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "archivedFilesUploadedBytes": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "numberOfAnalyzedFiles": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "numberOfOcrFiles": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "numberOfDossiers": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "numberOfAnalyzedPages": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "analysedFilesBytes": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "numberOfOcrPages": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "startDate": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "endDate": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "monthlyData": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/MonthlyReportData"
+ }
+ }
+ }
+ },
+ "MonthlyReportData": {
+ "type": "object",
+ "properties": {
+ "startDate": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "endDate": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "totalFilesUploadedBytes": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "activeFilesUploadedBytes": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "trashFilesUploadedBytes": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "archivedFilesUploadedBytes": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "numberOfAnalyzedPages": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "analysedFilesBytes": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "numberOfOcrPages": {
+ "type": "integer",
+ "format": "int32"
+ }
+ }
+ },
+ "DossierRequest": {
+ "type": "object",
+ "properties": {
+ "dossierId": {
+ "type": "string",
+ "description": "The id of the dossier, can be null for create requests."
+ },
+ "dossierName": {
+ "type": "string",
+ "description": "The name of the dossier. Must be unique."
+ },
+ "description": {
+ "type": "string",
+ "description": "The dossier's description (optional)."
+ },
+ "dueDate": {
+ "type": "string",
+ "description": "The date when the dossier is due.",
+ "format": "date-time"
+ },
+ "ownerId": {
+ "type": "string",
+ "description": "The id of the owning user."
+ },
+ "memberIds": {
+ "uniqueItems": true,
+ "type": "array",
+ "description": "The id(s) of members associated to this dossier.",
+ "items": {
+ "type": "string",
+ "description": "The id(s) of members associated to this dossier."
+ }
+ },
+ "approverIds": {
+ "uniqueItems": true,
+ "type": "array",
+ "description": "The id(s) of approvers associated to this dossier.",
+ "items": {
+ "type": "string",
+ "description": "The id(s) of approvers associated to this dossier."
+ }
+ },
+ "downloadFileTypes": {
+ "uniqueItems": true,
+ "type": "array",
+ "description": "Download File Types for this dossiers submission package.",
+ "items": {
+ "type": "string",
+ "description": "Download File Types for this dossiers submission package.",
+ "enum": [
+ "ORIGINAL",
+ "PREVIEW",
+ "REDACTED",
+ "ANNOTATED",
+ "FLATTEN",
+ "DELTA_PREVIEW"
+ ]
+ }
+ },
+ "reportTemplateIds": {
+ "uniqueItems": true,
+ "type": "array",
+ "description": "Id(s) of the word report templates used to generate downloads",
+ "items": {
+ "type": "string",
+ "description": "Id(s) of the word report templates used to generate downloads"
+ }
+ },
+ "watermarkId": {
+ "type": "integer",
+ "description": "The watermark id to be applied to the redacted files.",
+ "format": "int64"
+ },
+ "previewWatermarkId": {
+ "type": "integer",
+ "description": "The preview watermark id that will be applied to the previewed files.",
+ "format": "int64"
+ },
+ "dossierStatusId": {
+ "type": "string",
+ "description": "The dossierStatusId for this dossier. can be null for update request."
+ }
+ },
+ "description": "Object containing information about a dossier."
+ },
+ "DossierList": {
+ "type": "object",
+ "properties": {
+ "dossiers": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Dossier"
+ }
+ }
+ }
+ },
+ "Dossier": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "dossierName": {
+ "type": "string"
+ },
+ "date": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "description": {
+ "type": "string"
+ },
+ "ownerId": {
+ "type": "string"
+ },
+ "memberIds": {
+ "uniqueItems": true,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "approverIds": {
+ "uniqueItems": true,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "downloadFileTypes": {
+ "uniqueItems": true,
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "ORIGINAL",
+ "PREVIEW",
+ "REDACTED",
+ "ANNOTATED",
+ "FLATTEN",
+ "DELTA_PREVIEW"
+ ]
+ }
+ },
+ "reportTemplateIds": {
+ "uniqueItems": true,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "watermarkId": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "previewWatermarkId": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "softDeletedTime": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "hardDeletedTime": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "startDate": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "dueDate": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "archivedTime": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "dossierTemplateId": {
+ "type": "string"
+ },
+ "dossierStatusId": {
+ "type": "string"
+ },
+ "visibility": {
+ "type": "string",
+ "enum": [
+ "PRIVATE",
+ "PUBLIC"
+ ]
+ },
+ "dossierId": {
+ "type": "string"
+ }
+ }
+ },
+ "DossierTemplateList": {
+ "type": "object",
+ "properties": {
+ "dossierTemplates": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/DossierTemplate"
+ }
+ }
+ }
+ },
+ "DossierTemplate": {
+ "type": "object",
+ "properties": {
+ "dossierTemplateId": {
+ "type": "string",
+ "description": "The Rule Set Id. Generated by the system on create."
+ },
+ "name": {
+ "type": "string",
+ "description": "The name of this dossierTemplate. Must be set on create / update requests"
+ },
+ "description": {
+ "type": "string",
+ "description": "The description of this dossierTemplate"
+ },
+ "dateAdded": {
+ "type": "string",
+ "description": "The date when this dossierTemplate was created. Set by System on create.",
+ "format": "date-time"
+ },
+ "dateModified": {
+ "type": "string",
+ "description": "The date when this dossierTemplate was last modified. Set by System on create.",
+ "format": "date-time"
+ },
+ "createdBy": {
+ "type": "string",
+ "description": "The userId of the user who created this DossierTemplate. Set by the system."
+ },
+ "modifiedBy": {
+ "type": "string",
+ "description": "The userId of the user who last modified this DossierTemplate. Set by the system."
+ },
+ "validFrom": {
+ "type": "string",
+ "description": "Validity of start this dossierTemplate.",
+ "format": "date-time"
+ },
+ "validTo": {
+ "type": "string",
+ "description": "Validity of end this dossierTemplate.",
+ "format": "date-time"
+ },
+ "downloadFileTypes": {
+ "uniqueItems": true,
+ "type": "array",
+ "description": "Download File Types for this dossierTemplate's dossiers submission package.",
+ "items": {
+ "type": "string",
+ "description": "Download File Types for this dossierTemplate's dossiers submission package. For RedactManager the values `ORIGINAL`, `PREVIEW`, `REDACTED`, and `DELTA_PREVIEW` are valid. For DocuMine, only `ORIGINAL` can be used.",
+ "enum": [
+ "ORIGINAL",
+ "PREVIEW",
+ "REDACTED",
+ "DELTA_PREVIEW"
+ ]
+ }
+ },
+ "dossierTemplateStatus": {
+ "type": "string",
+ "description": "Status of dossier template.",
+ "enum": [
+ "INCOMPLETE",
+ "INACTIVE",
+ "ACTIVE"
+ ]
+ },
+ "keepImageMetadata": {
+ "type": "boolean",
+ "description": "Representing the setting if the metadata of images in pdfs should get kept, or removed"
+ },
+ "keepHiddenText": {
+ "type": "boolean",
+ "description": "Representing the setting if the hidden text in pdfs should get kept, or removed"
+ },
+ "keepOverlappingObjects": {
+ "type": "boolean",
+ "description": "Representing the setting if the overlapping objects in pdfs should get kept or removed by flattening the pages"
+ },
+ "applyDictionaryUpdatesToAllDossiersByDefault": {
+ "type": "boolean",
+ "description": "Representing the setting if dictionary updates is applied to all dossiers"
+ },
+ "ocrByDefault": {
+ "type": "boolean",
+ "description": "Flag that specifies if OCR is automatically performed on upload for all dossiers of this template"
+ },
+ "removeWatermark": {
+ "type": "boolean",
+ "description": "Flag that specifies the watermark removal in documents will be performed before the OCR processing"
+ },
+ "id": {
+ "type": "string"
+ }
+ }
+ },
+ "FileComponents": {
+ "type": "object",
+ "properties": {
+ "dossierTemplateId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "dossierId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "fileId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "filename": {
+ "type": "string"
+ },
+ "components": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "componentDetails": {
+ "type": "object",
+ "nullable": true,
+ "additionalProperties": {
+ "$ref": "#/components/schemas/Component"
+ }
+ }
+ }
+ },
+ "FileComponentsList": {
+ "type": "object",
+ "properties": {
+ "files": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/FileComponents"
+ }
+ }
+ }
+ },
+ "Component": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "values": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "originalValues": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "entityReferences": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Entity"
+ }
+ },
+ "componentRule": {
+ "type": "string"
+ }
+ }
+ },
+ "Entity": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ },
+ "value": {
+ "type": "string"
+ },
+ "entityRule": {
+ "type": "string"
+ },
+ "pages": {
+ "uniqueItems": true,
+ "type": "array",
+ "items": {
+ "type": "integer",
+ "format": "int32"
+ }
+ }
+ }
+ }
+ },
+ "securitySchemes": {
+ "FF-OAUTH": {
+ "type": "oauth2",
+ "flows": {
+ "authorizationCode": {
+ "authorizationUrl": "/auth/realms/redaction/protocol/openid-connect/auth",
+ "tokenUrl": "/auth/realms/redaction/protocol/openid-connect/token",
+ "scopes": {}
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/test/java/com/iqser/red/service/persistence/service/v2/api/external/IdentityTest.java b/persistence-service-v1/persistence-service-external-api-v2/src/test/java/com/iqser/red/service/persistence/service/v2/api/external/IdentityTest.java
new file mode 100644
index 000000000..f3494d916
--- /dev/null
+++ b/persistence-service-v1/persistence-service-external-api-v2/src/test/java/com/iqser/red/service/persistence/service/v2/api/external/IdentityTest.java
@@ -0,0 +1,16 @@
+package com.iqser.red.service.persistence.service.v2.api.external;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+public class IdentityTest {
+
+ @Test
+ public void mockTest() {
+
+ int i = 1;
+ assertThat(i).isEqualTo(1);
+ }
+
+}
diff --git a/persistence-service-v1/persistence-service-server-v1/pom.xml b/persistence-service-v1/persistence-service-server-v1/pom.xml
index 04f582d7b..8cb35c186 100644
--- a/persistence-service-v1/persistence-service-server-v1/pom.xml
+++ b/persistence-service-v1/persistence-service-server-v1/pom.xml
@@ -72,12 +72,19 @@
${project.version}
compile
+
+ com.iqser.red.service
+ persistence-service-external-api-impl-v2
+ ${project.version}
+ compile
+
com.iqser.red.service
persistence-service-internal-api-impl-v1
${project.version}
compile
+
diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/Application.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/Application.java
index 1f6fac123..d42e3841e 100644
--- a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/Application.java
+++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/Application.java
@@ -1,5 +1,25 @@
package com.iqser.red.service.peristence.v1.server;
+import com.iqser.red.persistence.service.v1.external.api.impl.PersistenceServiceExternalApiConfiguration;
+import com.iqser.red.persistence.service.v2.external.api.impl.PersistenceServiceExternalApiConfigurationV2;
+import com.iqser.red.service.dictionarymerge.commons.DictionaryMergeService;
+import com.iqser.red.service.persistence.management.v1.processor.PersistenceServiceProcessorConfiguration;
+import com.iqser.red.service.persistence.management.v1.processor.cache.PersistenceServiceExternalApiCacheConfiguration;
+import com.iqser.red.service.persistence.management.v1.processor.configuration.MessagingConfiguration;
+import com.iqser.red.service.persistence.management.v1.processor.settings.FileManagementServiceSettings;
+import com.iqser.red.service.persistence.v1.internal.api.PersistenceServiceInternalApiConfiguration;
+import com.iqser.red.storage.commons.StorageAutoConfiguration;
+import com.knecon.fforesight.databasetenantcommons.DatabaseTenantCommonsAutoConfiguration;
+import com.knecon.fforesight.jobscommons.JobsAutoConfiguration;
+import com.knecon.fforesight.keycloakcommons.DefaultKeyCloakCommonsAutoConfiguration;
+import com.knecon.fforesight.swaggercommons.SpringDocAutoConfiguration;
+import com.knecon.fforesight.tenantcommons.AsyncConfig;
+import com.knecon.fforesight.tenantcommons.MultiTenancyAutoConfiguration;
+import com.knecon.fforesight.tenantcommons.MultiTenancyMessagingConfiguration;
+import com.knecon.fforesight.tenantcommons.MultiTenancyWebConfiguration;
+import io.micrometer.core.aop.TimedAspect;
+import io.micrometer.core.instrument.MeterRegistry;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
@@ -19,28 +39,6 @@ import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-import com.iqser.red.service.dictionarymerge.commons.DictionaryMergeService;
-
-import com.iqser.red.persistence.service.v1.external.api.impl.PersistenceServiceExternalApiConfiguration;
-import com.iqser.red.service.persistence.management.v1.processor.PersistenceServiceProcessorConfiguration;
-import com.iqser.red.service.persistence.management.v1.processor.cache.PersistenceServiceExternalApiCacheConfiguration;
-import com.iqser.red.service.persistence.management.v1.processor.configuration.MessagingConfiguration;
-import com.iqser.red.service.persistence.management.v1.processor.settings.FileManagementServiceSettings;
-import com.iqser.red.service.persistence.v1.internal.api.PersistenceServiceInternalApiConfiguration;
-import com.iqser.red.storage.commons.StorageAutoConfiguration;
-import com.knecon.fforesight.databasetenantcommons.DatabaseTenantCommonsAutoConfiguration;
-import com.knecon.fforesight.jobscommons.JobsAutoConfiguration;
-import com.knecon.fforesight.keycloakcommons.DefaultKeyCloakCommonsAutoConfiguration;
-import com.knecon.fforesight.swaggercommons.SpringDocAutoConfiguration;
-import com.knecon.fforesight.tenantcommons.AsyncConfig;
-import com.knecon.fforesight.tenantcommons.MultiTenancyAutoConfiguration;
-import com.knecon.fforesight.tenantcommons.MultiTenancyMessagingConfiguration;
-import com.knecon.fforesight.tenantcommons.MultiTenancyWebConfiguration;
-
-import io.micrometer.core.aop.TimedAspect;
-import io.micrometer.core.instrument.MeterRegistry;
-import lombok.extern.slf4j.Slf4j;
-
@Slf4j
@EnableAsync
@EnableRetry
@@ -49,7 +47,7 @@ import lombok.extern.slf4j.Slf4j;
@EnableConfigurationProperties({FileManagementServiceSettings.class})
@ImportAutoConfiguration({StorageAutoConfiguration.class, JobsAutoConfiguration.class, DatabaseTenantCommonsAutoConfiguration.class, MultiTenancyAutoConfiguration.class, SpringDocAutoConfiguration.class, DefaultKeyCloakCommonsAutoConfiguration.class})
@SpringBootApplication(exclude = {SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class, CassandraAutoConfiguration.class, DataSourceAutoConfiguration.class, LiquibaseAutoConfiguration.class})
-@Import({PersistenceServiceExternalApiConfiguration.class, PersistenceServiceInternalApiConfiguration.class, PersistenceServiceExternalApiCacheConfiguration.class, MultiTenancyWebConfiguration.class, PersistenceServiceProcessorConfiguration.class, MessagingConfiguration.class, AsyncConfig.class, MultiTenancyMessagingConfiguration.class})
+@Import({PersistenceServiceExternalApiConfigurationV2.class, PersistenceServiceExternalApiConfiguration.class, PersistenceServiceInternalApiConfiguration.class, PersistenceServiceExternalApiCacheConfiguration.class, MultiTenancyWebConfiguration.class, PersistenceServiceProcessorConfiguration.class, MessagingConfiguration.class, AsyncConfig.class, MultiTenancyMessagingConfiguration.class})
public class Application {
/**
diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/resources/application.yaml b/persistence-service-v1/persistence-service-server-v1/src/main/resources/application.yaml
index b3ade894a..136ecb21f 100644
--- a/persistence-service-v1/persistence-service-server-v1/src/main/resources/application.yaml
+++ b/persistence-service-v1/persistence-service-server-v1/src/main/resources/application.yaml
@@ -109,7 +109,8 @@ fforesight:
keycloak:
ignored-endpoints: [ '/redaction-gateway-v1','/actuator/health/**', '/redaction-gateway-v1/async/download/with-ott/**',
'/internal-api/**', '/redaction-gateway-v1/docs/swagger-ui',
- '/redaction-gateway-v1/docs/**','/redaction-gateway-v1/docs', ]
+ '/redaction-gateway-v1/docs/**','/redaction-gateway-v1/docs',
+ '/api','/api/docs/**','/api/docs','/api/docs/swagger-ui' ]
enabled: true
springdoc:
base-path: '/redaction-gateway-v1'
diff --git a/persistence-service-v1/pom.xml b/persistence-service-v1/pom.xml
index a0f1a01e3..ca609df80 100755
--- a/persistence-service-v1/pom.xml
+++ b/persistence-service-v1/pom.xml
@@ -22,9 +22,11 @@
persistence-service-shared-api-v1
persistence-service-internal-api-v1
persistence-service-external-api-v1
+ persistence-service-external-api-v2
persistence-service-processor-v1
persistence-service-server-v1
persistence-service-external-api-impl-v1
+ persistence-service-external-api-impl-v2
persistence-service-internal-api-impl-v1