The Litigation Management Service manages the relation between entities in the Content Repository Service and legal cases.

If an entity is relevant for a legal case, it must not be deleted until the case is resolved. The Content Repository Service provides the litigation-hold feature that prohibits deletion of entities in litigation-hold. The Litigation Management Service extends this feature by managing collections of legal cases that are related to one or more entities. Each entity related to a collection of legal cases will be put under litigation-hold until all cases in the collection are resolved.

Installation

The Litigation Management Service is an extension of the Content Repository Service. It consists of a standalone service application providing the API and type definitions used to store legal cases and case collections. These type definitions must be present in the libs directory of the Content Repository Service. A containerized version of the Content Repository Service, including the required type definitions, is available in an image called litigation-management-service-content-repository-service.

Access rights

The Litigation Management Service uses impersonation to authenticate its requests to the Content Repository Service. The impersonation feature must be enabled in the Content Repository Service using the property:

commons:
  security:
    oauth2:
      impersonation-enabled: true

To allow the Litigation Management Service to update the litigation-hold flags of entities, it needs the following authorities. These authorities must be assigned to the service account user of the OAuth2 client used by the service:

Authority Description

ECR_DSGVO_ADMIN

Allows the service to set the litigation-hold flag.

ECR_DSGVO_PRIVILEGED_DELETE

Allows the service to delete empty collections (which are retention-protected, too).

can-impersonate

Allows the service to impersonate the actual user.

impersonate-inherit-authorities

The authenticated request will inherit the service’s authorities in addition to the user’s own authorities.

Data model

The following diagram shows a simplified view of the data model used by the Litigation Management Service.

Diagram

Legal cases are assigned to case collections using an n:m relation. Each case collection keeps track of the current number of related legal cases and is never empty. When the collection is created, it must contain one or more legal cases. As soon as the last case is resolved or removed from the collection, the empty collection is deleted.

An entity can be assigned to one case collection. As long as this assignment exists, the litigation-hold flag of the entity will be true. When the collection is deleted because the last case was resolved, the litigation-hold flag is reset to null.

The referential integrity of the data is ensured by foreign keys.

Creating type definitions

The following paragraphs describe how to create type definitions with litigation management.

To be able to manage the relation of legal cases to entities in the Content Repository Service, the type definitions containing the entities must meet some requirements. The type definitions must:

  • Use retention protection

  • Contain an attribute named case_collection_id

  • Define the required foreign keys to the case collection type.

The easiest way to assure that the type definitions meet the expected requirements, is to use the de.eitco.ecr.lms.types.EntityWithLitigationManagement interface as shown in the following example:

Defining a type definition with litigation management
@Type(ObjectType.CONTAINER)
public interface TestRecord extends EntityWithLitigationManagement {

}

To use the interface, add the following dependency to your types module:

Maven dependency
<dependency>
    <groupId>de.eitco.ecr</groupId>
    <artifactId>litigation-management-service-type-definitions</artifactId>
    <version>1.0.0-SNAPSHOT</version>
</dependency>

Using inheritance for litigation management

The Litigation Management Service can make use of the inheritance feature of the Content Repository Service. The following example shows a simple record scenario with records, registers and documents. When the record is assigned to a case collection, all registers and documents of the record will be put under litigation-hold automatically. Once all legal cases are resolved, the litigation hold will be removed from the entire record including its documents and registers. This is achieved by inheriting the case collection ID and the litigation hold flag from the record.

Record type definition
@Type(ObjectType.CONTAINER)
public interface TestRecord extends EntityWithLitigationManagement {

}
Register type definition
@Type(ObjectType.CONTAINER)
public interface TestRegister extends EntityWithLitigationManagement {

    @ForeignKey(target = TestRecord.class, targetProperty = "id")
    @CascadeDelete
    ContainerId getRecordId();

    void setRecordId(ContainerId recordId);

    @SystemProperty(value = SystemPropertyName.RETENTION_DATE)
    @InheritedProperty(foreignKeyPropertyName = "record_id", sourcePropertyName = "retention_date")
    ZonedDateTime getRetentionDate();

    void setRetentionDate(ZonedDateTime retentionDate);

    @InheritedProperty(foreignKeyPropertyName = "record_id", sourcePropertyName = "case_collection_id")
    @Override
    ContainerId getCaseCollectionId();

    @InheritedProperty(foreignKeyPropertyName = "record_id", sourcePropertyName = "litigation_hold")
    @Override
    boolean isLitigationHold();
}
Document type definition
@Type(ObjectType.DOCUMENT)
public interface TestDocument extends EntityWithLitigationManagement {

    @ForeignKey(target = TestRegister.class, targetProperty = "id")
    @CascadeDelete
    ContainerId getRegisterId();
    void setRegisterId(ContainerId registerId);

    @SystemProperty(value = SystemPropertyName.RETENTION_DATE)
    @InheritedProperty(foreignKeyPropertyName = "register_id", sourcePropertyName = "retention_date")
    ZonedDateTime getRetentionDate();

    void setRetentionDate(ZonedDateTime retentionDate);

    @InheritedProperty(foreignKeyPropertyName = "register_id", sourcePropertyName = "case_collection_id")
    @Override
    ContainerId getCaseCollectionId();

    @InheritedProperty(foreignKeyPropertyName = "register_id", sourcePropertyName = "litigation_hold")
    @Override
    boolean isLitigationHold();
}

Usage

The following examples show the basic usage of the service’s API.

Legal cases contain an optional external ID that can be used to link the case to another entity or system containing more information about the case and an optional description.

Creating a legal case
CaseManagementResourceClient client = caseManagementResourceClientFactory.newClient();
String caseDesc = "test-case-" + UUIDGenerator.randomUUID();
CaseCreationResult result = client.createCase(new CaseInput(caseDesc, externalId, null, false, null));

The CaseInput model class accepts five parameters:

  1. The optional description

  2. The optional external ID

  3. The ID of the case collection to add the case to or null

  4. A boolean indicating whether to automatically create a new case collection containing the new case

  5. An optional description of the new case collection (only relevant if parameter 4 is true)

The returned result will contain the case’s ID and the collection’s ID if a new collection was created.

Adding and removing a case from a collection

Cases can be added to and removed from collections.

Adding a case to a collection
client.addCaseToCollection(caseId, collectionId);
Removing a case from a collection
client.removeCaseFromCollection(caseId, collectionId);
Removing a case from all collections
client.removeCaseFromAllCollections(caseId);

If a collection is empty after the case was removed, it will be deleted. The litigation-hold flag of entities assigned to this collection will be reset to null.

Assigning a collection to an entity

Assigning a collection (which will contain at least one legal case) to an entity causes the litigation-hold flag of the entity being set to true.

Assigning a collection
testDocumentId = documentClient.getIdentifier();

EntityId entityId = new EntityId(testDocumentId.value());

caseManagementResourceClientFactory.newClient().assignCollectionToEntity(testCollectionId, entityId);

Resolving a case

If a case is resolved, it is removed from all collections and deleted.

Resolving a case
CaseManagementResourceClient caseManagementResourceClient = caseManagementResourceClientFactory.newClient();
caseManagementResourceClient.resolveCase(assignedCaseId);

If a collection is empty after the case was removed, it will be deleted. The litigation-hold flag of entities assigned to this collection will be reset to null.