4 October 2022
Documents are everywhere — not even the smallest of companies can avoid them. Every invoice, contract, insurance application, operational manual — the list goes on and on — must be stored and retrieved at some point. Overseeing all this can take a massive amount of effort and money.
Modern cloud vendors offer nearly infinite storage at a low cost. However, storing documents is the easy part. More challenging is ensuring they are organized, searchable, and secure for compliance and legal purposes. This is a job for a document management system (DMS).
yuuvis® Momentum provides a solid foundation to develop and grow a custom DMS for your enterprise. In this article, we’ll look into the challenge of managing insurance documents and how easy it is to build a custom, fully-featured DMS using yuuvis® Momentum and some JSON.
Most organizations have built up documents over the years using various applications and formats. Having to deal with many content types, and searching for these documents, is time-consuming.
It gets more complicated when dealing with large data sets and corporate environments with legal requirements around retention, audit, versioning, and security. When you are legally required to keep documents for three years, five years, seven years, or even permanently, they really pile up.
Things become even more inefficient because users must search and retrieve much of this content, and all those “one-time” requests for a document created years ago add up. Plus, you must ensure only the right people access sensitive documents.
Security and data loss is another big issue requiring planning. Lost or leaked documents can trigger financial and reputation disaster, especially for insurance companies, so they need a solution that provides security, auditability, and redundancy, keeping documents safe yet still available when needed.
Your management system may need to integrate with third-party services, custom microservices, or an existing front end, further complicating the situation.
How would you even go about handling all this? Let’s look at two approaches.
Let’s see what it takes to design, from the ground up, a custom insurance company DMS. The requirements are as follows:
We haven’t even begun to consider features like analytics, reporting, audit logs, and compliance, including retaining documents until a certain time, requiring even more development effort and tool integration. As you can see, we have our hands full already!
Doing everything from scratch might take more development time than you can spare. Instead, let’s see how we can use yuuvis® Momentum to kickstart the new project.
The first step is to get yuuvis® Momentum up and running. You’ll need a Kubernetes cluster, which can be hosted on-premises or in any cloud service provider. For testing purposes, you can start a single-node development version of yuuvis® Momentum using Minikube.
With yuuvis® Momentum running, we can start importing documents into the DMS. A single yuuvis® Momentum instance handles billions of records with ease.
A document consists of two parts:
yuuvis® Momentum exposes a RESTful API to access both the document and its metadata. Here’s a generic metadata JSON snippet:
{
"objects": [{
"properties": {
"system:objectTypeId": {
"value": "system:document"
},
},
"contentStreams": [{
"cid": "cid_insuranceDocument"
}]
}]
}
You can upload the file and its metadata at once with a POST
request to /api/dms/objects
. The following Java snippet uses OkHttp3 to build a multi-part HTTP request:
String baseUrl = "https://:";
String username = "clouduser";
String userpassword = "secret";
String tenant = "default";
String auth = Credentials.basic(username, userpassword);
OkHttpClient.Builder builder = new OkHttpClient.Builder();
OkHttpClient client = builder.build();
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("data", "metadata.json",
RequestBody.create(MediaType.parse("application/json; charset=utf-8"),
new File("./metaData.json")))
.addFormDataPart("cid_insuranceDocument", "insuranceClaimApplication.pdf",
RequestBody.create(MediaType.parse("application/pdf; charset=utf-8"),
new File("./insuranceClaimApplication.pdf")))
.build();
Request request = new Request.Builder()
.header("X-ID-TENANT-NAME", tenant)
.header("Authorization", auth)
.url(baseUrl+ "/api/dms/objects")
.post(requestBody)
.build();
Response reponse = client.newCall(request).execute();
Each document is assigned a unique objectId within the DMS.
yuuvis® Momentum works best when we have rich metadata for the documents. To take advantage of advanced searching and business processing capabilities, it’s a good idea to define custom schemas.
A schema is an XML file that defines properties for a given document type. We can have any number of document classes (the default class is document) with arbitrary fields. The supported property types are:
You can mark properties as mandatory when required: true
and as a list of values with cardinality: multi
. Continuing from the previous example, we may want to add some special properties for the claim form application document:
<schema xmlns="http://optimal-systems.org/ns/dmscloud/schema/v5.0/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://optimal-systems.org/ns/dmscloud/schema/v5.0/dmsCloud-schema.xsd">
<propertyStringDefinition>
<id>fullLegalName</id>
<propertyType>string</propertyType>
<cardinality>single</cardinality>
<required>true</required>
</propertyStringDefinition>
<propertyDateTimeDefinition>
<id>dateOfBirth</id>
<propertyType>datetime</propertyType>
<cardinality>single</cardinality>
<required>true</required>
</propertyDateTimeDefinition>
<propertyBooleanDefinition>
<id>formIsApproved</id>
<propertyType>boolean</propertyType>
<cardinality>single</cardinality>
<required>false</required>
</propertyBooleanDefinition>
<propertyDecimalDefinition>
<id>amountClaimed</id>
<propertyType>decimal</propertyType>
<cardinality>single</cardinality>
<required>true</required>
</propertyDecimalDefinition>
<typeDocumentDefinition>
<id>insuranceClaim</id>
<baseId>system:document</baseId>
<propertyReference>fullLegalName</propertyReference>
<propertyReference>dateOfBirth</propertyReference>
<propertyReference>formIsApproved</propertyReference>
<propertyReference>amountClaimed</propertyReference>
<contentStreamAllowed>allowed</contentStreamAllowed>
</typeDocumentDefinition>
</schema>
This schema enables you to create an insurance claims app based on yuuvis® Momentum. Therefore, all properties will be automatically prefixed with “appInsurance:”. To upload the schema and automatically create the app, you have to send the xml with a POST HTTP request to the /api/system/apps/insurance/schema
endpoint. With the new schema, the metadata.json is now:
{
"objects": [{
"properties": {
"system:objectTypeId": {
"value": "appInsurance:insuranceClaim"
},
"appInsurance:fullLegalName": {
"value": "Richard Roe"
},
"appInsurance:dateOfBirth": {
"value": "1984-04-02"
},
"appInsurance:formIsApproved": {
"value": <strong>false</strong>
},
"appInsurance:amountClaimed": {
"value": 2386.21
}
},
"contentStreams": [{
"cid": "cid_insuranceDocument"
}]
}]
}
You can change and update schema definitions at any time. See managing the schema for more use cases and examples.
Your users will expect a full-fledged, modern application to manage and search documents. yuuvis® Momentum supports a Node.js client reference implementation and contains a collection of Angular UI components to bootstrap your new project quickly.
The yuuvis® Momentum client contains two parts:
To get your new project going, first install Node.js. Once you’re all set, create a new yuuvis/project with:
ng new new-project
cd new-project
ng add @yuuvis/project --type=framework --project=new-project
The client uses a proxy to communicate with the yuuvis® Momentum backend. Prepare the configuration file by copying the example connection file:
cp proxy/_proxy.connections.json proxy/proxy.connections.json
Then edit the proxy/proxy.connections.json and add your connection details. Start the proxy with
npm run proxy
and finally, type
npm start
to get the Angular CLI dev server. The new website is available at localhost:4400
.
Once everything is ready, it’s time to start coding. Go to the client API documentation page to learn what’s next.
Access roles give you reusable templates to control who can access the resources. To grant a user access, we must first create a role, if we have not done so already, then assign that role to the user.
Roles are defined in an XML format like:
<role>
<name>RoleClaimReader</name>
<permission>
<action>read</action>
<condition>system:objectTypeId = 'insuranceClaim'</condition>
</permission>
</role>
The available actions are:
So, for example, we can create two roles, claimReader and claimWriter, with:
<!-- roleset.xml -->
<?xml version="1.0" encoding="utf-8"?>
<roleSet xmlns="http://optimal-systems.org/ns/dmscloud/roleset/">
<role>
<name>claimReader</name>
<permission>
<action>read</action>
<action>delete</action>
<condition>system:objectTypeId = 'insuranceClaim'</condition>
</permission>
</role>
<role>
<name>claimWriter</name>
<permission>
<action>read</action>
<action>write</action>
<condition>system:objectTypeId = 'insuranceClaim'</condition>
</permission>
</role>
</roleSet>
We’ll use the identity provider to assign the previously defined roles to the users.
There is a RESTful configuration endpoint at /api/admin/permissions
that allows you to configure roles and users.
yuuvis® Momentum features searching capabilities for all stored documents using the CMIS query language, an SQL language extended with full-text syntax. Each of your document types is mapped to a virtual table you can run SELECT
statements against.
SELECT * FROM appInsurance:insuranceClaim;
SELECT * FROM appInsurance:insuranceClaim WHERE amount_claimed >100 and CONTAINS('deductible');
Special system:object
and system:audit
tables enable you to search for document metadata and audit trails:
SELECT * FROM system:object WHERE system:creationDate < dateadd('year',-1,now());
SELECT * FROM system:audit WHERE system:creationDate IN YESTERDAY();
The built-in SQL query capabilities will let us easily track and find documents in the DMS.
Speaking of audit trails, yuuvis® Momentum keeps the history of every object passing through it. Audit records are available at the /api/dms/objects/{object_id}/history
endpoint.
Our insurance company DMS will certainly require auditing and document retention.
Retention policies ensure documents cannot be modified or deleted until a specified date. The retention feature protects documents even from users with appropriate write and delete roles.
You can set the retention date on existing documents with a metadata update. For instance, to lock the document until the first day of 2022, you can set the system:rmExpirationDate
property like this:
{
"properties": {
"system:rmExpirationDate ": {
"value": "2022-01-01T00:00:00Z"
}
}
}
And send the JSON content in a PATCH HTTP
request to /api/dms/objects/{object_id}
.
A process engine enables us to enforce business rules on stored documents. We may want to reject applications that are not correctly filled or mark duplicated claims in our insurance records. Likewise, we want to protect claim forms that have already been approved and paid out.
yuuvis® Momentum ships with a Business Process Management Engine (BPM Engine) , offering business processing capabilities. The engine implements rules for processing documents in the background. To learn more, check the BPM documentation page.
Picking the best solution to manage our documents is a careful decision, and building a custom solution from the ground up is a serious undertaking. yuuvis® Momentum gives you the foundational services for a fully-featured DMS.
Now that you see how easy it is to incorporate yuuvis® Momentum’s ready-made tools into your DMS, you’re ready to create your own custom solution for document management in the insurance industry and beyond. The applications are endless.
To learn more about yuuvis® Momentum, read these documents next: