# Insurance product data model and concepts

**URL:** <https://community.novulo.com/t/insurance-product-data-model-and-concepts/659>\
**Category:** Insurance\
**Tags:** getting-started, insurance\
**Created:** [November 12, 2025, 2:33pm UTC](https://community.novulo.com/t/insurance-product-data-model-and-concepts/659 "2025-11-12T14:33:16Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Reinier](https://avatars.discourse-cdn.com/v4/letter/r/f08c70/32.png) [@Reinier](https://community.novulo.com/u/Reinier)\
**Post date:** [November 12, 2025, 2:33pm UTC](https://community.novulo.com/t/insurance-product-data-model-and-concepts/659/1 "2025-11-12T14:33:16Z")

</div>

# Insurance data model and concepts

The insurance software branch uses a lot of generic Novulo concepts and applies them in the context of insurances. This article aims to give an overview of the tables that are used in insurance components, and to which purpose.

In insurance software, the most basic goal is to register an insurance contract: a _policy_, containing _coverages_, and sometimes part of a _package_. We start by explaining the concept N\_Product.

## N\_Product

N\_Product is the concept used for products. Depending on your composition, a product can be used in a variety of ways. It could be sold, purchased, billed, produced, delivered, kept in stock, used in an insurance contract, and so on. It always has a name, a code and a type.

In insurance, the product configuration determines the composition and properties of the eventual insurance contract.

> A product has one of three ‘Insurance types’: Package, Policy or Coverage
> 
> - For **packages** , the generic type of the product must be ‘kit’, so you can make compositions with policy products underneath them
> - For **policies** , the generic type is also ‘kit’, for compositions with coverage products
> - For **coverages** , the generic type is ‘product’

## N\_SalesPriceListLineitem

After configuring your product, you want to configure _how you sell it_. A product can be sold in multiple ways, with multiple prices. This is configured in the concept N\_SalesPriceListLineitem. This table links a product to the N\_SalesPriceList table, so you can determine a separate price for your product for each price list. You could have a price list for private sales or business to business sales, for instance. Look _here_ for more info on N\_SalesPriceListLineitem.

> In insurance, the distinction between price lists is usually the insurer. **One policy can be offered by multiple insurers** , and each insurer determines their own premium rate (=price).

Now, it becomes relevant what role your company plays in the insurance branch, because the configuration of an insurance sales price list item is highly dependent on this role.

> Three types of insurance companies are _insurers_, _agents_ and _proxies_. There are more, but these three paint a clear picture of product configuration differences.
> 
> - An **insurer** is in full control of the pricing of their products and configures the required calculations for their premiums.
> - Usually, an insurer has only one sales price list item per product; themselves being the insurer of that item.
> 
> - An **agent** is a company that sells insurances for multiple insurers.
> - For each product they sell, they have a list of sales price list items corresponding to all insurers they work with. They don’t calculate premiums themselves, but follow the insurers, resulting in a simpler “bare-bones” configuration.
> 
> - A **proxy** is a company that, like agents, sells insurances for multiple insurers, but where an insurance sold by an agent always needs to be approved by the insurer, a proxy has received the authorization to independently sell an insurer’s products.
> - This results in a list of sales price list items per product, correspondig to all insurers they work with, including premium calculations.

## N\_System and N\_SystemChange

Now that we know how to configure the composition and premium determination of our product, we can start registering insurances.

An important aspect of insurances is that each insurance is unique and has a unique identifier: a (package number,) policy number and coverage number. If a customer has 4 insurances of the same sales price list item, you still want to seperately register each of those insurances, as they all have their own starting date, length, payment terms, etc.

For registering unique instances of a product, we use N\_System. In it’s most basic form, N\_System is a record that belongs to an N\_Product and has a unique identifier.

However, one more important aspect of insurances is that their details can change. An insurance may start the first year with a premium rate of €100,- per month, but the second year could have a raised premium rate of €105,-. Because we want to keep track of every detail of every change, we introduced the concept N\_SystemChange.

> We use the concept **N\_SystemChange** to actually register a policy contract.

To visualize the relations between N\_SystemChange and N\_Product, have a look at the following graph:

digraph { rankdir=BT; // bottom-to-top (arrows point upward) graph [splines=true, overlap=false, fontname="Helvetica"]; node [shape=plain, fontname="Helvetica"]; // --- Product Layer --- subgraph cluster\_product { label="Product Layer"; style=filled; color="#e6e6e6"; N\_Product [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>N\_Product\</b\>\</td\>\</tr\> \</table\> \>]; } // --- Pricing Layer --- subgraph cluster\_price { label="Pricing Layer"; style=filled; color="#ffe0b2"; N\_SalesPriceListitem [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>N\_SalesPriceListItem\</b\>\</td\>\</tr\> \</table\> \>]; } // --- System Layer --- subgraph cluster\_system { label="System Layer"; style=filled; color="#d0e3ff"; N\_System [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>N\_System\</b\>\</td\>\</tr\> \</table\> \>]; N\_SystemChange [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>N\_SystemChange\</b\>\</td\>\</tr\> \</table\> \>]; } // --- Relationships (with labels) --- N\_System -\> N\_Product [label="instance of"]; N\_SystemChange -\> N\_System [label="version of"]; N\_SystemChange -\> N\_SalesPriceListitem [label="premium calculated by"]; N\_SalesPriceListitem -\> N\_Product [label="premium calculation of"]; }

## Bundles

In practice, a policy contract always has multiple _levels_ of products. A _policy_ is always accompanied by at least one _coverage_, and sometimes, multiple policies are bundled in one _package_. Packages, policies and coverages are all separately configured products, along with their sales price list items, bundeled together.

The following graph gives a simplified overview of how the N\_SystemChange, N\_SalesPriceListItem and N\_Product tables are connected when taking these bundles in account.

digraph { // Make graph go bottom → top (so arrows point upward) rankdir=BT; graph [splines=true, overlap=false, fontname="Helvetica"]; node [shape=plain, fontname="Helvetica"]; // --- Products --- subgraph cluster\_product { label="Products"; style=filled; color="#e6e6e6"; Package [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>Package\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_Product\</td\>\</tr\> \</table\> \>]; Policy [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>Policy\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_Product\</td\>\</tr\> \</table\> \>]; Coverage [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>Coverage\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_Product\</td\>\</tr\> \</table\> \>]; } // --- Price Items --- subgraph cluster\_price { label="Price Items"; style=filled; color="#ffe0b2"; PackagePrice [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>PackagePrice\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_SalesPriceListItem\</td\>\</tr\> \</table\> \>]; PolicyPrice [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>PolicyPrice\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_SalesPriceListItem\</td\>\</tr\> \</table\> \>]; CoveragePrice [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>CoveragePrice\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_SalesPriceListItem\</td\>\</tr\> \</table\> \>]; } // --- Contracts --- subgraph cluster\_contract { label="Contracts"; style=filled; color="#d0e3ff"; PackageContract [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>PackageContract\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_SystemChange\</td\>\</tr\> \</table\> \>]; PolicyContract [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>PolicyContract\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_SystemChange\</td\>\</tr\> \</table\> \>]; CoverageContract [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>CoverageContract\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_SystemChange\</td\>\</tr\> \</table\> \>]; } // Process hierarchies PackagePrice -\> Package; PolicyPrice -\> Policy; CoveragePrice -\> Coverage; PackageContract -\> PackagePrice; PolicyContract -\> PolicyPrice; CoverageContract -\> CoveragePrice; // Family hierarchies Policy -\> Package [label="\*simplified"]; Coverage -\> Policy [label="\*simplified"]; PolicyPrice -\> PackagePrice [label="\*simplified"]; CoveragePrice -\> PolicyPrice [label="\*simplified"]; PolicyContract -\> PackageContract [label="\*simplified"]; CoverageContract -\> PolicyContract [label="\*simplified"]; }

This graph is simplified, because the relation between multiple products, sales price list items and system changes are not directly connected, but through linking tables; resulting in many-to-many relations. This allows you to have packages with multiple policies, but also to re-use policies in multiple packages.

The following graph zooms in on these linking tables.

digraph { rankdir=BT; // bottom-to-top (arrows point upward) graph [splines=true, overlap=false, fontname="Helvetica"]; node [shape=plain, fontname="Helvetica"]; // --- Product Layer --- subgraph cluster\_product { label="Product Layer"; style=filled; color="#e6e6e6"; Package [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>Package\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_Product\</td\>\</tr\> \</table\> \>]; Policy [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>Policy\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_Product\</td\>\</tr\> \</table\> \>]; N\_ProductComposition [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>N\_ProductComposition\</b\>\</td\>\</tr\> \</table\> \>]; } // --- Pricing Layer --- subgraph cluster\_price { label="Pricing Layer"; style=filled; color="#ffe0b2"; PackagePrice [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>PackagePrice\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_SalesPriceListItem\</td\>\</tr\> \</table\> \>]; PolicyPrice [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>PolicyPrice\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_SalesPriceListItem\</td\>\</tr\> \</table\> \>]; N\_SalesPriceListItemComposition [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>N\_SalesPriceListItemComposition\</b\>\</td\>\</tr\> \</table\> \>]; } // --- System Layer --- subgraph cluster\_system { label="System Layer"; style=filled; color="#d0e3ff"; PackageContract [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>PackageContract\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_SystemChange\</td\>\</tr\> \</table\> \>]; PolicyContract [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>PolicyContract\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_SystemChange\</td\>\</tr\> \</table\> \>]; N\_SystemChangeElement [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>N\_SystemChangeElement\</b\>\</td\>\</tr\> \</table\> \>]; } // --- Relationships (labels removed) --- N\_ProductComposition -\> Package [label="parent product"]; Policy -\> N\_ProductComposition [dir=back][label="child product"]; N\_SalesPriceListItemComposition -\> PackagePrice [label="parent price"]; PolicyPrice -\> N\_SalesPriceListItemComposition [dir=back][label="child price"]; N\_SystemChangeElement -\> PackageContract [label="parent contract"]; PolicyContract -\> N\_SystemChangeElement [dir=back][label="child contract"]; PolicyContract -\> PolicyPrice; PolicyPrice -\> Policy; PackageContract -\> PackagePrice; PackagePrice -\> Package; }

> - With **N\_ProductComposition** you create bundles of packages, policies and contracts. These make up the _possible bundles you can sell_;
> - With **N\_SalesPriceListItemComposition** you create _priced propositions of bundles to sell;_
> - With **N\_SystemChangeElement** you register contracts based on those prices bundles.

For example: you can have a health insurance policy without a dental coverage, with a “basic” dental coverage, or a “premium” dental coverage.

## N\_Question and N\_QuestionLink

Now that we can register an vast variety of contracts based on our product configuration, one remaining topic is registering the correct _properties_ of those products. Two products can be significantly different in which information is required to store.

For example: a life insurance policy wants to register whether the insured person smokes or not, where-as this is completely irrelevant for a car insurance policy.

To ensure you can store the correct information for all products, we use the N\_Question and N\_QuestionLink tables.

> - **N\_Question** defines a property. It contains the name of the property, how it should be answered (is it a number, text, yes/no, etc.), and more;
> - **N\_QuestionLink** links a property to a product _or sales price_. This again creates a many-to-many relation, so we can reuse a question in multiple products or sales prices.

We also make a difference between properties linked to products _versus properties linked to sales prices_. Initially, you can configure all the properties that are relevant to a product at the product level, but usually every insurance company has their own _subset of properties_ that are relevant to their propositions, so you also link the properties at the sales price level.

> - To properly separate the links between questions and products vs. questions and sales prices, we introduced the inheriting tables **N\_QuestionLinkForProduct** and **N\_QuestionLinkForSalesPriceListItem**

digraph { rankdir=LR; // arrows point upward graph [splines=true, overlap=false, fontname="Helvetica"]; node [shape=plain, fontname="Helvetica"]; // --- Properties Layer --- subgraph cluster\_properties { label="Properties"; style=filled; color="#d0ffd0"; PropertyA [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>PropertyA\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_Question\</td\>\</tr\> \</table\> \>]; PropertyB [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>PropertyB\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_Question\</td\>\</tr\> \</table\> \>]; } // --- Question links Layer --- subgraph cluster\_links { label="Product-Property Links"; style=filled; color="#efffc0"; ProductProperty1 [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>ProductAPropertyA\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_QuestionLinkForProduct\</td\>\</tr\> \</table\> \>]; ProductProperty2 [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>ProductBPropertyA\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_QuestionLinkForProduct\</td\>\</tr\> \</table\> \>]; ProductProperty3 [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>ProductBPropertyB\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_QuestionLinkForProduct\</td\>\</tr\> \</table\> \>]; ProductProperty4 [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>ProductCPropertyB\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_QuestionLinkForProduct\</td\>\</tr\> \</table\> \>]; } // --- Policy Products Layer --- subgraph cluster\_products { label="Policy Products"; style=filled; color="#e6e6e6"; PolicyProductA [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>PolicyProductA\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_Product\</td\>\</tr\> \</table\> \>]; PolicyProductB [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>PolicyProductB\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_Product\</td\>\</tr\> \</table\> \>]; PolicyProductC [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>PolicyProductC\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_Product\</td\>\</tr\> \</table\> \>]; } // --- Relationships --- PropertyA -\> ProductProperty1 [dir="back"]; ProductProperty1 -\> PolicyProductA; PropertyA -\> ProductProperty2 [dir="back"]; ProductProperty2 -\> PolicyProductB; PropertyB -\> ProductProperty3 [dir="back"]; ProductProperty3 -\> PolicyProductB; PropertyB -\> ProductProperty4 [dir="back"]; ProductProperty4 -\> PolicyProductC; }

digraph { rankdir=LR; // arrows point upward graph [splines=true, overlap=false, fontname="Helvetica"]; node [shape=plain, fontname="Helvetica"]; // --- PropertyA Layer --- subgraph cluster\_propertya { label="Links of PropertyA"; style=""; PropertyA [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4" bgcolor="#d0ffd0"\> \<tr\>\<td\>\<b\>PropertyA\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_Question\</td\>\</tr\> \</table\> \>]; ProductProperty1 [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4" bgcolor="#efffc0"\> \<tr\>\<td\>\<b\>ProductProperty1\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_QuestionConnectionForProduct\</td\>\</tr\> \</table\> \>]; PriceProperty1 [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4" bgcolor="#efffc0"\> \<tr\>\<td\>\<b\>PriceProperty1\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_QuestionLinkForSalesPriceListItem\</td\>\</tr\> \</table\> \>]; } // --- PropertyB Layer --- subgraph cluster\_propertyb { label="Links of PropertyB"; style=""; PropertyB [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4" bgcolor="#d0ffd0"\> \<tr\>\<td\>\<b\>PropertyB \</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_Question\</td\>\</tr\> \</table\> \>]; ProductProperty2 [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4" bgcolor="#efffc0"\> \<tr\>\<td\>\<b\>ProductProperty2 \</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_QuestionConnectionForProduct\</td\>\</tr\> \</table\> \>]; PriceProperty2 [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4" bgcolor="#efffc0"\> \<tr\>\<td\>\<b\>PriceProperty2 \</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_QuestionLinkForSalesPriceListItem\</td\>\</tr\> \</table\> \>]; } // --- Policy Products Layer --- subgraph cluster\_products { style=filled; color="#e6e6e6"; // grey PolicyProduct [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>PolicyProduct\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_Product\</td\>\</tr\> \</table\> \>]; } // --- Pricing Layer --- subgraph cluster\_pricing { style=filled; color="#ffe0b2"; // orange PolicyPriceA [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>PolicyPriceA\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_SalesPriceListItem\</td\>\</tr\> \</table\> \>]; PolicyPriceB [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>PolicyPriceB\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_SalesPriceListItem\</td\>\</tr\> \</table\> \>]; } // --- Relationships --- ProductProperty1 -\> PropertyA; ProductProperty1 -\> PolicyProduct; PriceProperty1 -\> PolicyPriceA; ProductProperty2 -\> PropertyB; ProductProperty2 -\> PolicyProduct; PriceProperty2 -\> PolicyPriceB; PolicyPriceA -\> PolicyProduct; PolicyPriceB -\> PolicyProduct; // Enforce left-to-right order PriceProperty1 -\> ProductProperty1 [style=invis]; PriceProperty2 -\> ProductProperty2 [style=invis]; }

## N\_Answer and N\_SystemChangeActualAnswer

With questions you define _which_ properties are included in a product and its contracts. Now the properties still need a place to store their values: the N\_Answer concept, and more specifically, N\_SystemChangeActualAnswer when we store the values that belong to contract.

> - When a contract is generated, we generate **a N\_SystemChangeActualAnswer record for each N\_QuestionLinkForSalesPriceListItem**

The answers table has various fields to store the correct value: a text field, a number field, a date field, etc.; the applicable field is chosen based on the configuration of the question.

digraph { rankdir=BT; // bottom-to-top (arrows point upward) graph [splines=true, overlap=false, fontname="Helvetica"]; node [shape=plain, fontname="Helvetica"]; // --- Product Layer --- subgraph cluster\_product { label="Product Layer"; style=filled; color="#e6e6e6"; PolicyProduct [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>PolicyProduct\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_Product\</td\>\</tr\> \</table\> \>]; N\_QuestionLinkForProduct [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4" bgcolor="#efffc0"\> \<tr\>\<td\>\<b\>N\_QuestionLinkForProduct\</b\>\</td\>\</tr\> \</table\> \>]; } // --- Pricing Layer --- subgraph cluster\_price { label="Pricing Layer"; style=filled; color="#ffe0b2"; PolicyPrice [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>PolicyPrice\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_SalesPriceListItem\</td\>\</tr\> \</table\> \>]; N\_QuestionLinkForSalesPriceListItem [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4" bgcolor="#efffc0"\> \<tr\>\<td\>\<b\>N\_QuestionLinkForSalesPriceListItem\</b\>\</td\>\</tr\> \</table\> \>]; } // --- System Layer --- subgraph cluster\_system { label="System Layer"; style=filled; color="#d0e3ff"; PolicyContract [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>PolicyContract\</b\>\</td\>\</tr\> \<tr\>\<td\>Datatype: N\_SystemChange\</td\>\</tr\> \</table\> \>]; N\_SystemChangeActualAnswer [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4" bgcolor="#d1ffff"\> \<tr\>\<td\>\<b\>N\_SystemChangeActualAnswer\</b\>\</td\>\</tr\> \</table\> \>]; } // --- Question Layer --- subgraph cluster\_questions { style=filled; color="#d0ffd0"; N\_Question [label=\< \<table border="1" cellborder="0" cellspacing="0" cellpadding="4"\> \<tr\>\<td\>\<b\>N\_Question\</b\>\</td\>\</tr\> \</table\> \>]; } // --- Relationships --- N\_SystemChangeActualAnswer -\> PolicyContract; N\_QuestionLinkForSalesPriceListItem -\> PolicyPrice; N\_QuestionLinkForProduct -\> PolicyProduct; N\_SystemChangeActualAnswer -\> N\_QuestionLinkForSalesPriceListItem; N\_QuestionLinkForSalesPriceListItem -\> N\_Question; N\_QuestionLinkForProduct -\> N\_Question; PolicyContract -\> PolicyPrice; PolicyPrice -\> PolicyProduct; }

With this set-up, a contract can store all general information (like a contract’s effective date, the owner, etc.) in it’s own N\_SystemChange table, and all product-specific information in the N\_SystemChangeActualAnswer table.
