# Rule Engine

## Basic Concept

Since the rule logic of insurance business can be highly complex, it is essential that the rules are configured to be maintained quickly and flexibly for constant updates based on the changing business needs.

The Rule Engine is used to configure not only insurance underwriting or validation logic, but also other common logic such as auto-clause attachments or workflow assignments.

## Composition of Rule Engine

### What is Rule?

During insurance operations, there are many business rules that vary from client to client to control different system behaviors. 

Unlike ordinary program code, configuration requires code release, and the code is difficult to modify in many scenarios, so a rule configuration capability is needed, which should be comparatively simple and can be operated directly on the configuration page with the following characteristics:

* Easy to maintain and configure.
* Ability to modify and test results in real time.
* Ability to publish to other runtime environments for use in real time.

There is a continuous endeavor from the insureMO team to enhance rule configuration tools to optimize configuration experience as much as possible. 

### Rule Usage Scenario

The Rule Engine can be used in a variety of business scenarios, and the most common ones in our insurance business are as follows:

* Underwriting

Underwriting is one of the most common types of rules in terms of the insurance business. Once an underwriting rule is triggered, it generates a feedback message. The operator then decides whether the case can continue or needs to be escalated to an underwriter for approval.

* Validation

Validation rules are sometimes similar to underwriting rules in terms of business checks and message prompts, while the difference is that underwriting rules allow manual decisions to pass or fail, but validation rules are always hard to control, which do not allow a pass.

In other words, underwriting rules mostly have soft controls based on human judgment, while validation rules tend to be hard stopped.

In addition to the business usage, for some validation rules, it can also be system-related to ensure the integrity of the system data rather than implementing a business information check.

* Auto Additional Clause/Form

In some cases, different clauses need to be added to the policy based on specific field selections. For example, the selection of terrorism coverage may result in additional terrorism extensions to be sent out. 

* Endorsement Generation

If policy information alters during the endorsement, the endorsement needs to be automatically generated to demonstrate the difference in information before and after the endorsement. 

Different content may contain different business conditions to determine the type of wording or conditions that are triggered.

* Other Complex Check Rules

In summary, our Rule Engine can support all of the above scenarios. Our system analysts can use the Rule Engine for dynamic system configuration, which has the advantage of being flexible and adjustable.

Throughout the document, examples will be provided primarily around policy modules and domains. However, we can also use the rules engine for other purposes, such as claims.

### Rule Engine Component

The Rule Engine consists of five major elements, including Driver, Event, Group, Groovy Rule.

![engine](./image/rule/engine.png)

*  **Rule**

The rule is the basic unit to implement business logic.

In the case of homeowner's insurance, a typical rule is to check the type of building. Typically, buildings can be constructed of wood or reinforced concrete. Wood buildings have a higher risk of fire and may require some special underwriting considerations or a maximum sum insured of coverage. Sometimes there is a maximum amount of insurance that can be insured or underwritten. If the end user wants to change the sum insured of coverage at the time of approval, a cap verification can be mandatory and the limit boundary is not allowed to be exceeded.

Another example is the vehicle type, which also requires special treatment for high-end car brands or sports cars.

Since most rules are currently written in the Groovy script, they can also be referred to as Rule Management.

*  **Rule Group**

The rule group is a grouping of rules.

During the configuration process, some analysts may be responsible for the auto insurance configuration rules, while some may be responsible for the configuration of home-related rules. 

To avoid interfering with each other's tasks, our rule engine supports grouping these rules separately, putting auto insurance validation rules into one group and home validation rules into another. Likewise, their endorsement-related rules can be grouped differently.

Assuming that there are many rules to be configured, we can further categorize them based on several dimensions, including multiple types such as the motor or health insurance, issuance or endorsement transaction, and the underwriting or validation rule. 

Groovy rules and rule groups are associated many-to-many, and one rule can belong to multiple groups.

* **Rule Event**

The Event is the trigger point for rule execution.

If we need to make any rule run, it must ultimately be bound to a rule event, which can be regarded as the trigger point for system API calls. Therefore, not only must the rules be connected to rule groups, but also the rule groups have to be connected to rule events.

We can regard a rule group as a management unit, and a rule event as a system trigger unit. The rule group is used to facilitate the search or retrieval of specific rules during the configuration process, while the rule event is used for system triggering.

The group and event are associated in a many-to-many manner. There can be multiple groups under an event, and a group can correspond to multiple events. When an event is called, all groups under that event will be cycled through and the rules under the group will be executed sequentially.

* **Rule Driver**

The driver drives the execution of the Rule Engine, but it is not directly referenced while the rule engine is running. There are three categories of drivers, Customized Driver, Orchestration Driver and Service Driver. The first type of driver is used for direct program calls; the last two are used before and after orchestration and service (they are not supported so far).

Each event belongs to a driver. For example, the event UnderwritingRuleCheck that is used for the underwriting is part of UnderwritingRuleCheck, the generic driver. There are three types of Events (Direct, Before and After), where Direct is used for the generic driver counterpart, while Before and After are used to orchestrate the event corresponding to the service driver.

In general, rule groups and specific rules are most often changed during the business configuration, while events and drivers are more stable and defined during the design.

During the design of the system architecture, it is fundamental to lay out how many general categories, or what part of the system program code, will trigger the rules. After planning, developers embed event triggers into the service code and then system analysts can focus on rule groups and rules to achieve business goals.

[Version 21.0.12] Please note that the validation rule is formally deprecated from this version. User can use Groovy rules to configure validation rules instead.

### Other Important Configuration Modules

This document mainly deals with Rule Engine operation itself. In addition, the following modules are also important during rule configuration:

* Groovy & DSL

To be able to use Rule Engine, it is also vitally important to grasp how to write rule scripts. Users can see our [DSL Guide](https://docs.insuremo.com/common/doc_00000019) for more information.

* Message Code

Sometimes, we need to throw out rule message in the rule body. Users can see our [Message Guide](https://docs.insuremo.com/common/doc_00000042) to learn how to maintain the message.

* Configuration Table

During the configuration, we often need to look up a dynamic table to judge whether the condition matches the expectation or not. The user can refer to our [Configuration Table Guide](https://docs.insuremo.com/common/doc_00000045) to learn how to maintain a dynamic table.


## Rule UI Operation Guide

<div class="docs-caution"><span class="docs-admonitions-text">caution</span>

*  All operations in this text need to be performed in the portal Master Configuration environment (MC env). They are not allowed in other environments unless for troubleshooting purposes.
*  Please make sure you have all read and write authority to make the operation beforehand.

</div> 


### Search Rule

Upon entering the Rule Maintenance, the system will display all available rules in the system for analysts to work with. Analysts can then add or edit a new rule or search for rules based on various categories.

![search_rule](./image/rule/search_rule.png)


### Rule Maintenance - V1

#### Create and Edit Rule

Once users enter the maintenance of the individual rule V1, the UI displays two sections, where the top is the general criteria, such as the general rule description, whether it belongs to the general or product level, or which rule group to attach for validation or underwriting, and the bottom is the text location where the rule body is configured. Some rules are simple, while others are more complex.

Users can add rule details.
*  **Rule Name**: Self define, name will be unique for all rules.
*  **Rule Level**: The applicable level of Policy Object. 
*  **Object Code**: The object code of the Policy Object. The **Rule Level** & **Object Code** will be taken as a filter to execute the rule.
*  **Filtering Condition**: The logic to execute the rule or not (true: will be executed; false: will NOT be executed).
*  **Status**: To enable or disable a rule.
*  **Start Date**: To define when rule should take effective.
*  **End Date**: To define when rule should expiry.
*  **Release Date**: To define when rule is released.
*  **Rule Script**: Set the logic of the rule by DSL Script (see [DSL Script](https://docs.insuremo.com/common/doc_00000019)).

![add_rule_definition](./image/rule/add_rule_definition.png)

Click **Rule Group and Conditions** to set the context and mapping group for rules.

![add_rule_context-group](./image/rule/add_rule_context-group.png)

Rules are mapped to groups by default without groups, and the user can set priority for rules under groups. Input the priority value, and the priority will be updated.

0 means highest priority and 1,2,3, onwards it will follow the order.

![set priority for the rule under the group](./image/rule/add_rule_context-group2.png)

It is only used to map rule under the group. Also system supports mapping rules to groups under the tab **Rule Group and Conditions**. 

#### Rule Helper

The system provides **Rule Helper** to get the common used information quickly when creating/editing a rule.

![Rule Helper](./image/rule/rule_helper001.png)


<div class="docs-tip"><span class="docs-admonitions-text">tip</span>

* In all helpers, after clicking **Attach Script**, the system will automatically copy the script to the rule. 
* If the required is NOT found, just Click the link **No Result Found?** in right upper corner to add for it.

</div>

##### Select DSL

  Select the DSL function you need, and it will be auto copied to the rule script.

![Select DSL](./image/rule/rule_helper_dsl.png)


##### Select Field

 The Select Field UI will get the DD structure by default according to the rule's **Context**. If the rule context is mapped to,
 * Market product, the default DD structure is for technical product of the market product.
 * Technical product, the default DD structure is for technical product.
 * Common, the default DD structure is for Common.
 
![Select Field](./image/rule/rule_helper_field.png)

 Select the **Filed** you need, and the script to get the field's value will be automatically copied to the rule script.

![Selected Field](./image/rule/rule_helper_field_s.png)

##### Select Rate Table

 The Select Field UI will get the rate tables by default according to the rule's **Context**. If the rule context is mapped to,
 * Market product, the default rate tables are for technical product of the market product.
 * Technical product, the default rate tables are for technical product.
 * Common, the default rate tables are for Common.

![Select RateTable](./image/rule/rule_helper_ratetable.png)

Select the rate table you need, and the script to lookup the rate table will be automatically copied to the rule script. Then update the parameters' values according to the truly required variables or values.


![Selected RateTable](./image/rule/rule_helper_ratetable_s.png)

##### Select Message

![Select Message](./image/rule/rule_helper_message.png)

Select the message code you need, and the script to use message code will be automatically copied to the rule script. Then update the variables according to the true requirement.

##### Select Snippet

![Select Snippet](./image/rule/rule_helper_snippet.png)

Select the snippet you need, and the script will be automatically copied to the rule script. Then change the script based on your requirement.

![Selected Snippet](./image/rule/rule_helper_snippet_s.png)



### Rule Group Maintenance

Rule groups are maintained in **Rule & Rating > Rule Group**.

Users can perform the following actions in the rule group UI:

* Search rule group via a fuzzy query by name.
* Create a new rule group and edit or delete an existing rule group. 
* Select the name, description, and module of the rule group and bind the rule group to an event. 
* Select the rule to attach to the rule group and define the order of execution of multiple rules to be run together.

![group](./image/rule/group.png)

#### Create or Edit Rule Group

![add_group](./image/rule/add_group.png)

![group_mapping_rule](./image/rule/group_mapping_rule.png)

From V22.08, the system supports to set **Filter Condition** for a rule group. If the condition is matched, the rules under the group will be executed, or otherwise they will NOT be executed.

![group_mapping_rule](./image/rule/group_filtercondition.png)


### Rule Event and Driver Maintenance

#### Create Driver

Rule Driver are maintained in **Rule & Rating > Rule Driver**.

Click **Add**.

![add_driver](./image/rule/add_driver.png)

In the pop-up box from the driver name (no spaces) and the driver description, select the driver type. Click **Save**.

If users need to undo the addition, close the pop-up box by clicking the **X** at the top right of the pop-up box.

#### Create Event

Rule Event are maintained in **Rule & Rating > Rule Event**.

Click **Add**. 
Under **Event Detail**, please input the event definition in detail.
Under **Rule Group**, you can map the rule groups to current event. Please select **Rule Group**, set **Priority**, then click **Add**, and the rule group will be mapped to current event with the set Priority.

![add_event](./image/rule/add_event.png)

Click **Save** at the bottom right.

The event code cannot have spaces, the event name cannot be empty, and the rule group can be bound to the rule group associated with the event.

### Rule Tracking

After each call to rule API, the user can view the details of the trigger in the rule tracking page.

![search tracking by traceid](./image/rule/rule_debug_002.png)

Click **View** to check the tracking details.

![rule tracking](./image/rule/rule_debug_004.png)

![rule tracking](./image/rule/rule_tracking_001.png)


### Rule Library Copy

  The system supports to copy rules from other tenants.
  You can choose some rules to copy or "**Copy All**" rules of other tenants to current tenants.
  
   ![rule copy](./image/rule/rule_copy.png)
   
   Choose the some rules to copy, and click "**Copy Selected**".
   
   ![rule copy selected](./image/rule/rule_copyselected.png)
   
   After the copying is done, you can check the copying result to confirm the rules copied and whether the system handled it successfully.
   
   ![rule copy result](./image/rule/rule_copy-result.png)



### Rule Configuration Deployment

For rule configuration data release, see [Guide](https://docs.insuremo.com/common/doc_00000016#rule-common).


## Rule Versioning

Currently we don't support multiple physical versions for the same rules (the same rule names). Instead, users can create multiple rules (different rule names) with multiple effective/expiry date to achieve versioning scenarios. Each rule will have its own version and effective/expiry date. Also, all the ratetable invoked in the rule will follow the same versioning logic as the rule script.

The following is the steps about how to achieve such versioning:

1. Set "**Effective Period Field**" or "**Release Date Field**" for a rule group.
2. Set "**Start Date**""**End Date**" and "**Release Date**" for the rule under a rule group.

As shown in the image below, the system will take policy's EffectiveDate field as rule Active duration check.

* If the policy's EffectiveDate field is between 2023-11-03 and 2023-11-31, the rule will be fired.
* If the policy's EffectiveDate field is before 2023-11-03, the rule will not be fired.
* If we remove the "**Release Date Field**" from rule group and the "**Release Date**" from rule, the Policy can be fired between 2023-11-01 and 2023-11-31 comparing with the system time.

![rule group Eff](./image/rule/rule_group_eff_field.png)

![rule POI](./image/rule/rule_eff_set.png)


## Rule Debugging and Troubleshooting

### Method

After the rule is configured, we need to run the rule to view whether it meets the business requirements. The process, also called debugging, virtually contains two modes to debug the rule. 

* Front-end Testing

This method assumes that the front-end application has been well-developed in advance. Then the system will return the result of the rule to front-end by clicking certain trigger points like button during the front-end insurance process or trigger process. It is regarded as the most user-friendly approach for functional testing of the system for end business users and business analysts.

* API Testing

Sometimes, front-and-middle-office based models, where the front-end office may not be available during configuration, increasingly rely on API validation for rule debugging.

To adopt this approach requires a technical underwriting of data model calls by system users in the first place, which can be used for developer unit testing or massive automated testing.

###  Online Testing

  From Version 22.03.X, the system supports to test rules by Events online.
  
 
1.  Open one rule, and click **Online Testing**.
2.  Choose the **URL** and **Event Code** of a rule is mapped to.
3.  Input the request JSON to test.
4.  Click **Test**.
  
  ![Online Testing](./image/rule/rule_debug_0001.png)

5. Then you can see **JSON Result** on the right.

  ![Online Testing  Result](./image/rule/rule_debug_0002.png)
  
6. Click one node of the rule, you can see the detailed tracking log of the node.
  
  ![Online Testing Tracking](./image/rule/rule_debug_0003.png)

### API Testing

Different rule types are triggered by distinct APIs. There are specific APIs for underwriting and others for validation, so they have slightly different API parameters. For example, validation rules may require different events to trigger different rules during insurance, underwriting, or policy submission and issuance. We can control the various stages with API parameters to validate different data.

After the API is called, if any rule fails, a failed validation message will be returned. An example of a failed validation is displayed in the figure. There may be common message information (e.g. validation date, current system time) and specific business information (e.g. business message code or business message name).

To facilitate rule debugging, the rule tracking is provided to view the history of all rule executions. Suppose there is a rule that has a function to obtain the sum insured, compare the sum insured with the limit, and then return a message. The traces of all these key steps can be recorded and viewed. This is an exceptionally useful feature that allows analysts to debug the rule.

The APIs that can fire the rules, see [API Description](#sample-reference-rule-event-and-driver-for-gi-business).

### Precondition for Execution

* The rule is activated.
* The rule is mapped to an expected market product.
* The rule is mapped to a group.
* The rule group is mapped to an event.


### Trace ID

Each time a Rule API is fired, a trace ID will be returned to indicate the trigger.

![response header](./image/rule/rule_debug_001.PNG)

Users can then obtain the trace ID from the response's header and search for it in the rule Tracking.

![search tracking by traceid](./image/rule/rule_debug_002.png)

![rule tracking](./image/rule/rule_debug_004.png)

### Tracking Log Performance Housekeeping

Nowadays, our tracking log is switched on in all environments by default including production to support development team in troubleshooting. In order to balance the production system performance, there will not be line number display and tracking is captured in an asynchronous way.

Since the tracking log is highly comprehensive which includes every aspect of rule execution, sometimes, if too many rules are triggered, the log table (`t_rm_tracking`) can become very large that it requires a regular clean-up.

As part of platform default setting, we offered a "ruleTrackingDeleteExpiredDataJob" batch which keeps running every night to clean up the log which was created more than 90 days ago. If the records increase too fast, users can also go to the batch module to run it with closer days.

Please pay special attention that if your client is very performance demanding, you can ask insureMO support team to disable the tracking entirely.

![rule tracking clear](./image/rule/rule_tracking_clear.png)


### Rating Tracking Configcenter Parameter (Private Cloud Only)

By default, in all environment, when debugging rule logic, we always need to check the rule logic details. Then we can use the rule tracking function.

Sometimes we might want to disable the tracking in other environments, especially in the case of private clouds, for the sake of best performance.

Users can go to config-server on the platform and check the following configuration items (if the configuration items do not exist, then it will take the default value.)

1. rule.tracking.flag
* true-enable (default)
* false-disable
       
2. dsl.tracking.flag
* true-enable (default)
* false-disable 
       
3. rule.tracking.async
* true-async (default for production)
* false-sync (default for non-production)
       
4. dsl.tracking.lineNumber.flag
* true-display (default for non-production)
* false-not display (default for production)


## Rule Development Guide

Once the rules are configured, we can test all rule-related APIs and embed them into application usage.
By default, the platform has a set of pre-defined domain APIs to facilitate rule usage. Also, our developers can extend these APIs with back-end calls.

The following is an example of general proposal related to rule validation API and rule groups. Users can also go to the insureMO portal to get the latest list of APIs.

* `{{server}}/quotation/v1/validate?eventCode={{eventCode}}&langId=en_US`
* `{{server}}/proposal/v1/validate?eventCode={{eventCode}}&langId=zh_CN`
* `{{server}}/pa/v1/invokeRuleEvent?eventCode={{eventCode}}&langId=en_US`

<div class="docs-tip"><span class="docs-admonitions-text">tip</span>

Set the parameter **langId** in URL param, then the returned message can be the target language. Also,  if you only wana set the target language in request header, then set the header **x-mo-lang-id**.

</div>

Please note that for the above-mentioned policy validation APIs, in addition to the rule validation, we have other data dictionary definitions to validate as well:

* The value of the field does not match the defined data type. 
* The value is not in code table (id column). 
  If a field's value is not input, the empty "" will be taken as an input value. So please do not use "", just set value to be **null**, or **remove** the field from JSON request.
* The length of the value does not match the defined one.
* The structure is not consistent with the market product. For example, the benefit is set to the incorrect coverage, or is not defined in the market product.
* The rule is required by the system. For example, PolicyLob is a must and Risk should be under the PolicyLob.

## FAQ

### 1. What is the best way to initiate rule configuration?

Practice is the most crucial part in rule configuration. 

For beginning rules, they may be difficult for users to get started with due to inevitable errors and notably human errors. However, after a few rule configurations, users will become familiar with common error patterns and then gradually develop a faster way to correct mistakes, especially by using the rule tracking provided by the system.

Our experience has witnessed things will be much easier later on, and users will comprehend its beauty of the simplicity and plainness.

### 2. Is the Rule Engine configured in the same way as the system was developed?

Rule configuration is indeed performed through the UI, not development. Development usually involves a complex process of compiling, deploying and debugging the console.

However, script configuration does require more demanding technical talents. Sometimes since business users or analysts are reluctant to learn a little more about the programming language, they may not find rule configuration easy to use.

In other words, we cannot force business users to learn programming; instead, there is another recommended approach called parametric promotion.

We can arrange for developers or programmers to configure rules. But during configuration process, we try to turn those parameters in the rule script into a configuration and then expose the configuration table to the business unit for configuration. Take a simple rule for maximum sum insured validation as an example. We can put the maximum sum insured in the rule script. Alternatively, we can also put the value in a decision table and then arrange for the business unit to maintain that table directly.

To truly implement a product factory, we recommend that our technical consultants meet with business users and jointly organize configuration requirements and work as a team. Our technical colleagues can then configure the body of rules through scripted configuration, while extracting all parameter values (e.g. coverage limits and house types) into the configuration table. Afterwards, during system maintenance and after the system goes live, the business team only needs to pay attention to all the extracted configuration tables, and then make adjustment and release. If new rules need to be added, which involves scripting adjustments, again the technical department needs to be involved to accomplish.

### 3. I do not quite comprehend the concept of parameterization. Could you please enlighten me more in this area?

Suppose we want to implement a rule that checks the maximum sum insured limit. 

There are two implementation options:

Option 1: Direct Implementation

```dsl  
if(SumInsured.val > 35000000){ 
 // Direct Judgment
 return uwResultWithUwLevel("TWBNP-ZERF-INSUREMO-W0007","0")
}
```

Option 2: Rule to Call Configuration Table

```dsl
def ActionResult = 0
ActionResult = lookup("ZERF_LIMIT",["CoverageCode": ProductElementCode.val,"Amount":SumInsured]).Result 
//Call Configuration Table to Get the Result for the Judgment
if(ActionResult == "2"){
  return uwResultWithUwLevel("TWBNP-ZERF-INSUREMO-W0007","0")
}
```

We can observe that for Option 1, the maximum limit is configured in the script itself. Therefore, if the business needs modification, system maintainers need to tackle the script modification. But the script for option 2 is relatively stable. All the changeable parameters have been maintained in a tabular structure that is easy to manage for business users.

All tools are available, and not much configuration efforts are taken to extract parameters. 

A positive mindset matters. 


### 4. If I want a certain rule to be triggered during the quote phase but not during the bind phase, how can I do it?

Basically, there are two ways:

1. Add proposal status as part of if condition in the rule body - this is ok if number of such cases is small.
2. Separate different even for quote and bind as two different event - since it requires calling application to change, it will be better if number of such cases is big. 
 


## Sample Reference Rule Event and Driver for GI Business

The default system rule Event & Driver are provided with our proposal and endorsement services as shown below. If users need to use the default Driver & Event, please create them under rule Event. If you use any customized event, just use it as param in URL such as "`/quotation/v1/validate?eventCode=xxx`" (xxx is the customized event code).

<div class="docs-caution"><span class="docs-admonitions-text">caution</span>

Please do not mix rules of different usages into one event. Please separate them by usage to separate events, and call the proper usage API.

</div>


| Service | API URL | Default Rule Driver | Default Rule Event |Mark |
| ------ | ------ | ------ | ------ | ------ |
| quotation | `/quotation/v1/underwriting` | UnderwritingRuleCheck | UnderwritingRuleCheck | - |
| quotation | `/quotation/v1/validate` | ValidationDriver | PolicyValidationVheck | - |
| quotation | `/quotation/v1/autoAttach` | AutoAttachFormService | AutoAttachFormEvent | Attach Forms | 
| quotation | `/quotation/v1/attachElement` | AutoAttachFormService | AttachElement4Quotation	 |Attach Elements (From Version 22.06.x)  |
| proposal | `/proposal/v1/underwriting` | UnderwritingRuleCheck | UnderwritigRuleCheck | - |
| proposal | `/proposal/v1/validate` | ValidationDriver | PolicyValidationVheck | - |
| proposal | `/proposal/v1/autoAttach` | AutoAttachFormService | AutoAttachFormEvent | Attach Forms |
| proposal | `/proposal/v1/attachElement`  | AutoAttachFormService | AttachElement4Proposal | Attach Elements (From Version 22.06.x) |
| proposal | `/proposal/v1/generateClauseContent`  | - | `EVENT_GEN_CLAUSE_CNT` | Generate Clause Content (From Version 23.06.x) |
| endorsement | `/endo/v1/underwriting` | UnderwritingRuleCheck | EndoUnderwritingRuleCheck | - |
| endorsement | `/endo/v1/validate` | ValidationDriver | PolicyValidationVheck | - |
| endorsement | `/endo/v1/autoAttach` | AutoAttachFormService | AutoAttachFormEvent | Attach Forms|
| endorsement | `/endo/v1/attachElement`  | AutoAttachFormService | AttachElement4Endorsement | Attach Elements (From Version 22.06.x) |
| endorsement | `/endo/v1/generateClauseContent`  | EndoContentDriver | `EVENT_GEN_CLAUSE_CNT_ENDO` | Generate Clause Content(From Version 23.06.x) |
| endorsement | `/endo/v1/generateContent`  | EndoContentDriver | EndoContentEvent  | Generate Endorsement Content |


<div class="docs-note"><span class="docs-admonitions-text">note</span>

The attachElement API backend logic as below,
1. Attach elements by rule event. And only attach elements for models existed in request. 
2. Attach elements according the product element Reference Relationship "**A Brings out B Always Automatically in API**".

If element A01 is attached by attachElement, and we want to attach element A001 for it. When calling the API attachElement, only the element A01 is attached. If we want to attach the element A001 for it, we need to use the first call's response as request to call the API attachElement again, and the element A001 will be attached.

</div>


### API for Validation Rule

* `/quotation/v1/validate?eventCode=`
* `/proposal/v1/validate?eventCode=`
* `/endo/v1/validate?eventCode=`

### API for UW Rule

* `/quotation/v1/underwriting?eventCode=`
* `/proposal/v1/underwriting?eventCode=`
* `/endo/v1/underwriting?eventCode=`

### API for Attach Element Rule

* `/quotation/v1/attachElement?eventCode=`
* `/proposal/v1/attachElement?eventCode=`
* `/endo/v1/attachElement?eventCode=`

### API for Generate Clause Content

* `/proposal/v1/generateClauseContent`
* `/endo/v1/generateClauseContent`

### API for Add Endorsement Content

*  (GET) `/endo/v1/generateContent?endoId=` 


#### Example Response for API Validation

* If validation passes, the system returns with code **204**.
* If validation fails, the system returns with code **500**, and the response example shows as below:

```json
{
    "timestamp": "2023-03-14T16:37:32",
    "timestampServer": "2023-03-14T08:37:31.523",
    "status": 500,
    "error": "Internal Server Error",
    "path": "/v1/validate",
    "traceId": "37061dd5da28b2d1",
    "traceIdContainer": null,
    // highlight-start
    "messages": [
        {
            "code": "TenantCode-PA-Validation-B5001",
            "message": "Please confirm that the following integration mandatory fields exist: AgentCode,OrgCode,PremiumCurrencyCode,BookCurrencyCode,LocalCurrencyCode,PremiumLocalExchangeRate,PremiumBookExchangeRate"
        }
    ],
    // highlight-end
    "exception": "...platform.foundation.exception.MultipleBusinessException",
    "code": "MO-PLATFORM-Rule-B4000",
    "message": "validation failed"
}
```

### Example Response for API UnderWriting


For **underwriting** API, its rule script is as below,

```
def age = Age.val
if(age<21){
 return uwResult("TenantCode-PA-UW-U1001")
}
```

To check whether UW passed or failed, the system returns with code **200**.  


* UW Check Pass 

The response example for success is as below,

```
{
    "Model": {//Policy Info
    },
    // highlight-next-line
    "Status": "Success"
}
```

* UW Check Failed

The response example for failed is as below,

{
    // highlight-start
    "MessageList": [
        {
            {
            "Code": "TenantCode-PA-UW-U1001",
            "Message": "Policyholder Age< 21 years old.",
            "RuleName": "Insured Age Check"
        }
        }
    ],
    // highlight-end
    "Model": {// Policy Info
    },
    // highlight-next-line
    "Status": "Fail"
}


