---
title: Risk Assessment
description: This example illustrates how to leverage Eventing Service in the
  Banking and Financial domain.
pubDate: 2026-08-17T09:53:44.266Z
antora:
  editUrl: https://github.com/couchbaselabs/docs-devex/edit/release/8.0/modules/eventing/pages/eventing-examples-high-risk.adoc
  xref: xref:server:eventing:eventing-examples-high-risk.adoc[]
---

[Consult the llms.txt file for a full list of contents](/llms.txt)
[View original HTML](/server/current/eventing/eventing-examples-high-risk.html)

# Risk Assessment

**Goal**: This example illustrates how to leverage Eventing Service in the Banking and Financial domain. When a credit card transaction either 1) exceeds the user's available credit limit or 2) is made in a foreign currency, a high-risk transaction alert can be generated.

**Implementation**:

Create a JavaScript Function that contains an **OnUpdate** handler. The handler listens to data-changes within a specified, **'register'** collection. When a document with type='transaction' within this source collection is mutated, (created or changed), the Eventing Function executes user-defined code to respond to the change in real time.

**The Eventing function will**:

1. Lookup details from the customers card information specifically: date, spending limits, location, and default currency. This data is from collection **'register'** with type='card'.
2. Lookup the exchange rates for the date from the transaction. This data is from collection **'register'** with type='exchange\_rates'.
3. Normalize the currencies from both the transaction and the spending limit into USD (at the correct day's exchange rate).
4. Determine if a spending threshold is exceeded (this is high risk).
5. Determine if the purchase is a foreign purchase (this is high risk).
6. For all high-risk transactions generate a new document containing both some transaction information and some calculated data.
7. Write the new document representing the suspect transaction to the **'review'** collection with type='transaction'.
8. \[OPTIONAL\] Use of cURL directly from Eventing, use of a custom application written in various Couchbase SDKs, or use of third-party integrations like Kafka to read the items written to the **'review'** collection (type='transaction') for further automated action.

**Preparations**:

For this example, two (2) buckets **'bulk'** and **'rr100'** are required where the latter is intended to be 100% resident. Create the buckets with a minimum size of 100MB. For information on buckets, see [Create a Bucket](../manage/manage-buckets/create-bucket.md). Within the buckets we need three (3) keyspaces **'bulk.data.register'**, **'bulk.data.review'**, and **'rr100.eventing.metadata'**(we loosely follow this [organization](eventing-buckets-to-collections.md#single-tenancy)).

For the Function Scope or RBAC grouping ,we will use the **'bulk.data'**, assuming you have the role of either "Full Admin" or "Eventing Full Admin". For standard or non-privileged users refer to [Eventing Role-Based Access Control](eventing-rbac.md).

_If you run a version of Couchbase prior to 7.0 you can just create the buckets **'register'**, **'review'**, and **'metadata'** and run this example. Furthermore if your cluster was subsequently upgraded from say 6.6.2 to 7.0 your data would be moved to **'register.\_default.\_default'**, **'review.\_default.\_default'**, and **'metadata.\_default.\_default'** and your Eventing Function would be seamlessly upgraded to use the new keyspaces and continue to run correctly._

For complete details on how to set up your keyspaces refer to [creating buckets](../manage/manage-buckets/create-bucket.md) and [creating scopes and collections](../manage/manage-scopes-and-collections/manage-scopes-and-collections.md).

> [!NOTE]
> The Eventing Storage keyspace, in this case **'rr100.eventing.metadata'**, is for the sole use of the Eventing system, do not add, modify, or delete documents from it. In addition do not drop or flush or delete the containing bucket (or delete this collection) while you have any deployed Eventing functions. In a single tenancy deployment this collection can be shared with other Eventing functions.

**Setup**:

1. Access the **Couchbase Web Console** \> **Buckets** page.

  * You should see the following once you have created your buckets:  
  ![high risk txns 01 buckets](_images/high_risk_txns_01_buckets.png)
2. \[Optional Step\] Verify we have our empty collections:

  * Click the **Scopes & Collections** link of the **bulk** bucket (on the right).
  * Click the **data** scope name to expand the section (on the left).
  * You should see no user records.  
  ![high risk txns 01 data in scope](_images/high_risk_txns_01_data_in_scope.png)
3. Click the **Documents** link of the **register** collection (on the right).

  * Again you should see no user records.  
  ![high risk txns 01 documents](_images/high_risk_txns_01_documents.png)
4. Change the keyspace from `bulk`.`data`.`register` to `bulk`.`data`.`review` to view the **review** collection.

  * Again you should see no user records.  
  ![high risk txns 01a documents](_images/high_risk_txns_01a_documents.png)

**Procedure**:

1. Modify the **'bulk'** bucket to enable the ability to "flush" the items from the UI (_do not do this for the other bucket_). Access the **Couchbase Web Console** \> **Buckets** page, and select the bucket '**bulk**' to expand the bucket view.  
![high risk txns 01 bucket edit](_images/high_risk_txns_01_bucket_edit.png)  
Now click on the **'Edit'** button to invoke the settings dialog for the '**bulk**' bucket.

  * Expand the 'Advanced bucket settings' control, then scroll to the bottom of the dialog and check the final control **'Flush \[X\] Enable'**.  
  ![high risk txns 03 bucket settings](_images/high_risk_txns_03_bucket_settings.png)  
  To save this change click the **'Save Changes'** button. Your **'bulk'** bucket can now be flushed (as there is now a new button available for the action).  
  ![high risk txns 04 bucket edit](_images/high_risk_txns_04_bucket_edit.png)  
  For more details on bucket settings and screen images refer to [Bucket Settings](../manage/manage-buckets/create-bucket.md#couchbase-bucket-settings).
2. From the **Couchbase Web Console** \> **Query** page, build an index for the **'register'** collection and an index for the '**review**' collection:  
```sqlpp  
CREATE INDEX `adv_type_rg` ON `bulk`.`data`.`register`(`type`);  
CREATE INDEX `adv_type_rv` ON `bulk`.`data`.`review`(`type`);  
CREATE PRIMARY INDEX `adv_prim_rv` ON `bulk`.`data`.`review`;  
```  
Copy and paste the three lines of text (above) into the Query Workbench and click **'Execute'**.  
![high risk txns 05 create indexes](_images/high_risk_txns_05_create_indexes.png)  
Although the above indexes are technically not needed for our Eventing function they will come in useful for exploring the documents imported to the **'register'** collection and inserted into the '**review**' collection by our Eventing Function using the SQL++ language in the Query Workbench.
3. From the **Couchbase Web Console** \> **Eventing** page, click **ADD FUNCTION**, to add a new Function. The **ADD FUNCTION** dialog appears.
4. In the **ADD FUNCTION** dialog, for individual Function elements provide the below information:

  * For the **Function Scope** drop-down, select **'bulk.data'** as the RBAC grouping.
  * For the **Listen To Location** drop-down, select **bulk**, **data**, **source** as the keyspace.
  * For the **Eventing Storage** drop-down, select **rr100**, **eventing**, **metadata** as the keyspace.
  * Enter **high\_risk\_txns** as the name of the Function you are creating in the **Function Name** text-box.
  * Leave the "Deployment Feed Boundary" as Everything.
  * \[Optional Step\] Enter text **Flag items over credit threshold or a foreign transaction**, in the **Description** text-box.
  * For the **Settings** option, use the default values.
  * For the **Bindings** option, add two bindings.

    * For the first binding, select "bucket alias", specify **register** as the "alias name" of the collection, select **bulk**, **data**, **register** as the associated keyspace, and select "read only" for the access mode.
    * For the second binding, select "bucket alias", specify **review** as the "alias name" of the collection, select **bulk**, **data**, and **review** as the associated keyspace, and select "read and write" for the access mode.
  * After configuring your settings the **ADD FUNCTION** dialog should look like this:  
  ![high risk txns 01 settings](_images/high_risk_txns_01_settings.png)
5. After providing all the required information in the **ADD FUNCTION** dialog, click **Next: Add Code**. The **high\_risk\_txns** dialog appears.

  * The **high\_risk\_txns** dialog initially contains a placeholder code block. You will substitute your actual **high\_risk\_txns code** in this block.  
  ![high risk txns 02 default code](_images/high_risk_txns_02_default_code.png)
  * Copy the following Function and paste it in the placeholder code block of **high\_risk\_txns** dialog.  
  ```javascript  
  function OnUpdate(doc, meta) {  
    if (doc.type != "transaction") return;  
    try {  
      var verbose = 0; // logging - 0: minimal, 1: moderate, 2: massive  
      if (verbose > 0) log(meta.id + ' Process transaction for doc.card: ' +  
        doc.card + ', doc.amount: ' + nformat(doc.amount, 0, 2));  
      // load the associated card info to this transaction  
      var card = register['card:' + doc.card];  
      if (!card) {  
        log(meta.id + ' warn card does not exist: ' + doc.card);  
        return;  
      }  
      // load the exchange rate table for the day of the transaction  
      var erid = 'exchange_rates:er-' + (doc.date).substr(0, 10);  
      var exchange_rates = register[erid];  
      if (!exchange_rates) {  
        log(meta.id + ' WARNING exchange_rates does not exist: ' + erid);  
        return;  
      }  
      var to_USD = exchange_rates['to_USD'];  
      var trxn_2_USD = to_USD[doc.currency];  
      var card_2_USD = to_USD[card['currency']];  
      if (!trxn_2_USD || !card_2_USD) {  
        log(meta.id + ' WARNING exchange_rates for either ' + card['currency'] +  
          ' or ' + doc.currency + ' does exist');  
        return;  
      }  
      // convert transaction charge and credit card limit into USD  
      var trxn_amount_USD = doc.amount / trxn_2_USD;  
      var card_thresh_USD = card['threshold'] / card_2_USD;  
      if (verbose > 1) {  
        log(meta.id + ' doc   ', doc);  
        log(meta.id + ' card  ', card);  
        log(meta.id + ' rates ', exchange_rates)  
      }  
      if (verbose > 0) {  
        log(meta.id + ' 1 doc.amount       ' + nformat(doc.amount, 8, 2) +  
          ', card_limit       ' + nformat(card['threshold'], 8, 2));  
        log(meta.id + ' 2 trxn_currency    ' + sformat(doc.currency, 8) +  
          ', card_currency    ' + sformat(card['currency'], 8));  
        log(meta.id + ' 3 trxn_2_USD       ' + nformat(trxn_2_USD, 8, 6) +  
          ', card_2_USD       ' + nformat(card_2_USD, 8, 6));  
        log(meta.id + ' 4 trxn_amount_USD  ' + nformat(trxn_amount_USD, 8, 2) +  
          ', card_thresh_USD  ' + nformat(card_thresh_USD, 8, 2));  
      }  
      // check if high risk due to over threshold limit  
      if (card_thresh_USD < trxn_amount_USD) {  
        var msg = 'High Risk Txn: amount: ' + nformat(doc.amount, 8, 2) + ' ' +  
          doc.currency + ' exceeds purchase threshold: ' +  
          nformat(card['threshold'], 8, 2) + ' ' + card['currency'];  
        log(meta.id + ' *** ' + msg);  
        doc["comments"] = msg; // append description to the document  
        doc["reason_code"] = 'X-CREDIT'; // append the code to the document  
        delete doc["city"]; // remove city sub document  
        review[meta.id] = doc; // save the modified document for review  
        return;  
      }  
      // check if high risk due to foreign purchase  
      if (doc.currency != card['currency']) {  
        var msg = 'High Risk Txn: currency mismatch card: ' +  
          card['currency'] + ' != txn: ' + doc.currency;  
        log(meta.id + ' *** ' + msg);  
        doc["comments"] = msg; // append description to the document  
        doc["reason_code"] = 'X-MISMATCH'; // append the code to the document  
        delete doc["city"]; // remove city sub document  
        review[meta.id] = doc; // save the modified document for review  
        return;  
      }  
      if (verbose > 0) log(meta.id + ' Charge by ' + card["firstname"] + ' ' +  
        card["lastname"] + ' appears normal in the amount of ' +  
        nformat(doc.amount, 0, 2) + ' ' + doc.currency);  
    } catch (e) {  
      // there was some sort of processing error or Exception, notify the user  
      log(meta.id + 'ERROR in OnUpdate:', e);  
    }  
  }  
  // right justify string with given width  
  function sformat(s, width) {  
    var str = s;  
    while (width > str.length) str = ' ' + str;  
    return str;  
  }  
  // right justify number with given width with given precision  
  function nformat(n, width, prec) {  
    return sformat(n.toFixed(prec), width, prec);  
  }  
  ```  
  After pasting, the screen appears as displayed below:  
  ![high risk txns 03 code](_images/high_risk_txns_03_code.png)
  * Click **Save and Return**.
6. The **OnUpdate** handler above is triggered for every transaction. The handler checks if the transaction amount is less than the user's available credit limit. When this condition is breached, then this transaction is flagged as a high-risk transaction. In addition, the handler checks if a foreign currency purchase has occurred, this is also flagged as a high-risk transaction.  
The Function **high\_risk\_txns** then copies the transaction to the **review** bucket (but it removes some unneeded data and adds some enriched data). The handler enriches the document with predefined _comments_ and also provides a _reason code_. In the last part, the handler performs a currency validation step.  
The handler also converts both the credit limit and the transaction amount to a common currency, in this case USD, based upon current exchange rates on the exact date of the given transaction.
7. Now we will seed the required sample data. There are a total of four (4) data files that need to be downloaded to your Couchbase instance. Right-click on each of the links below and choose **Save Link As** to download the files. For remote instances, right-click on each of the links below and choose **Copy Link Address**, then use either the cURL or wget utility to download the files.

| **Data Set / File Name** | **Description**         | **JSON type indicator** | **\# Records** | **Download link**                                                     |
| ------------------------ | ----------------------- | ----------------------- | -------------- | --------------------------------------------------------------------- |
| cards.json               | Credit card information | type='card'             | 7              | [Download](%5Fattachments/examples/high%5Frisk/cards.json)            |
| merchants.json           | Merchant information    | type='merchant'         | 5001           | [Download](%5Fattachments/examples/high%5Frisk/merchants.json)        |
| exchange\_rates.json     | Daily exchange rates    | type='exchange\_rates'  | 422            | [Download](%5Fattachments/examples/high%5Frisk/exchange%5Frates.json) |
| txns.json                | Credit Card charges     | type='transaction'      | 417            | [Download](%5Fattachments/examples/high%5Frisk/txns.json)             |  
An example record from the _cards.json_ file that you just downloaded encapsulates the information of a credit card:  
```json  
{  
  "type": "card",  
  "cardnumber": "4273-6623-8686-4599",  
  "firstname": "Winfred",  
  "lastname": "Raftery",  
  "street": "3965 I-80 E Off Ramp",  
  "mobile": "+1-617-555-1371",  
  "sms": true,  
  "city": {  
    "name": "Uxbridge",  
    "code": "MA",  
    "state": "Massachusetts",  
    "county": "Worcester",  
    "display": "Uxbridge"  
  },  
  "issued": "11/15",  
  "expiry": "6/19",  
  "ccv": 736,  
  "issuer": "Helena National Bank",  
  "maxcredit": 1000,  
  "threshold": 9500,  
  "country": "US",  
  "currency": "USD"  
}  
```  
An example record from the _merchants.json_ file that you just downloaded encapsulates the information of a merchant:  
```json  
{  
 "type": "merchant",  
 "merchantid": "merchant-501233450539197794-0",  
 "name": "FlightAware Inc",  
 "city": {  
  "name": "Bentonville",  
  "code": "IN",  
  "state": "Indiana",  
  "county": "Fayette",  
  "display": "Bentonville"  
 }  
}  
```  
An example record from the _exchange\_rates.json_ file that you just downloaded encapsulates the information of a set of exchange rates:  
```json  
{  
  "type": "exchange_rates",  
  "erid": "er-2017-09-01",  
  "to_USD": {  
    "CAD": 1.2441275168,  
    "INR": 64.0331375839,  
    "EUR": 0.8389261745,  
    "USD": 1,  
    "SGD": 1.3545302013,  
    "GBP": 0.7724412752,  
    "CNY": 6.5591442953,  
    "AUD": 1.2601510067  
  }  
}  
```
8. An example record from the _txns.json_ file that you just downloaded encapsulates the information of a transaction or a card charge:  
```json  
{  
  "type": "transaction",  
  "txnid": "tx-1526311379-002",  
  "amount": 15.99,  
  "product": "Thread Bore Brush: .22 Caliber, Centerfire",  
  "card": "4273-6623-8686-4599",  
  "merchant": "GoodGuide Inc",  
  "city": {  
    "name": "Waseca",  
    "code": "MN",  
    "state": "Minnesota",  
    "county": "Waseca",  
    "display": "Otisco"  
  },  
  "date": "2018-05-14T20:52:59+05:30",  
  "currency": "USD"  
}  
```
9. The downloaded files now need to all be loaded into the **register** bucket. This can be done as follows:

  * Linux
  * macOS
  * Windows  
Assuming that the downloaded files needed are in /tmp (note your username and password may differ)  
```console  
cd /opt/couchbase/bin/  
CB_USERNAME=Administrator  
CB_PASSWORD=password  
./cbimport json -c http://localhost:8091 -u $CB_USERNAME -p $CB_PASSWORD -b bulk \
    --scope-collection-exp data.register \
    -f list -g '%type%:%txnid%' -d file:///tmp/txns.json  
./cbimport json -c http://localhost:8091 -u $CB_USERNAME -p $CB_PASSWORD -b bulk \
    --scope-collection-exp data.register \
    -f list -g '%type%:%cardnumber%' -d file:///tmp/cards.json  
./cbimport json -c http://localhost:8091 -u $CB_USERNAME -p $CB_PASSWORD -b bulk \
    --scope-collection-exp data.register \
    -f list -g '%type%:%merchantid%' -d file:///tmp/merchants.json  
./cbimport json -c http://localhost:8091 -u $CB_USERNAME -p $CB_PASSWORD -b bulk \
    --scope-collection-exp data.register \
    -f list -g '%type%:%erid%' -d file:///tmp/exchange_rates.json  
```  
Assuming that the downloaded files needed are in /Users/$USER/Downloads (note your username and password may differ)  
```console  
cd /Applications/Couchbase\ Server.app/Contents/Resources/couchbase-core/bin/  
CB_USERNAME=Administrator  
CB_PASSWORD=password  
./cbimport json -c http://localhost:8091 -u $CB_USERNAME -p $CB_PASSWORD -b bulk \
    --scope-collection-exp data.register \
    -f list -g '%type%:%txnid%' -d file:///Users/$USER/Downloads/txns.json  
./cbimport json -c http://localhost:8091 -u $CB_USERNAME -p $CB_PASSWORD -b bulk \
    --scope-collection-exp data.register \
    -f list -g '%type%:%cardnumber%' -d file:///Users/$USER/Downloads/cards.json  
./cbimport json -c http://localhost:8091 -u $CB_USERNAME -p $CB_PASSWORD -b bulk \
    --scope-collection-exp data.register \
    -f list -g '%type%:%merchantid%' -d file:///Users/$USER/Downloads/merchants.json  
./cbimport json -c http://localhost:8091 -u $CB_USERNAME -p $CB_PASSWORD -b bulk \
    --scope-collection-exp data.register \
    -f list -g '%type%:%erid%' -d file:///Users/$USER/Downloads/exchange_rates.json  
```  
Assuming that the downloaded files needed are in "C:\\Users\\%USERNAME%\\Downloads" (note your username and password may differ)  
```console  
cd "C:\Program Files\Couchbase\Server\bin\"  
SET CB_USERNAME=Administrator  
SET CB_PASSWORD=password  
cbimport json -c http://localhost:8091 -u %CB_USERNAME% -p %CB_PASSWORD% -b bulk ^
    --scope-collection-exp data.register ^
    -f list -g '%type%:%txnid%' -d file:///C:/Users/%USERNAME%/Downloads/txns.json  
cbimport json -c http://localhost:8091 -u %CB_USERNAME% -p %CB_PASSWORD% -b bulk ^
    --scope-collection-exp data.register ^
    -f list -g '%type%:%cardnumber%' -d file:///C:/Users/%USERNAME%/Downloads/cards.json  
cbimport json -c http://localhost:8091 -u %CB_USERNAME% -p %CB_PASSWORD% -b bulk ^
    --scope-collection-exp data.register ^
    -f list -g '%type%:%merchantid%' -d file:///C:/Users/%USERNAME%/Downloads/merchants.json  
cbimport json -c http://localhost:8091 -u %CB_USERNAME% -p %CB_PASSWORD% -b bulk ^
    --scope-collection-exp data.register ^
    -f list -g '%type%:%erid%' -d file:///C:/Users/%USERNAME%/Downloads/exchange_rates.json  
```
10. Access the **Couchbase Web Console** \> **Buckets** page and notice that a total of 5,847 documents have been loaded into the bucket '**register**'.  
![high risk txns 06 json loaded](_images/high_risk_txns_06_json_loaded.png)
11. We are now ready to start the Eventing function. From the **Eventing** screen, click the **high\_risk\_txns** function to select it, then click **Deploy**.  
![high risk txns 06a deploy](_images/high_risk_txns_06a_deploy.png)  

  * Click **Deploy Function**.
12. The Eventing function is deployed and starts running within a few seconds. From this point, the defined Function is executed on all existing documents and on subsequent mutations. After sufficient time has elapsed, there will be 40 new documents created in the **'review'** collection as well as logs generated by the Handler's JavaScript code.
13. To review the Eventing Application Log for **high\_risk\_txns** access the **Couchbase Web Console** \> **Eventing** and click the **Log** link of the deployed **high\_risk\_txns** Eventing function.

  * Note the Function Log Dialog lists log statements in reverse order (newest items first).  
  ![high risk txns 07 log](_images/high_risk_txns_07_log.png)
  * The dialog should have data similar to the following (only a few selected lines are displayed below):  
  ```console  
  2021-07-18T16:00:58.953-07:00 [INFO] "transaction:tx-1511710690-182 *** High Risk Txn: amount: 12506.00 USD exceeds purchase threshold: 12000.00 USD"  
  2021-07-18T16:00:58.952-07:00 [INFO] "transaction:tx-1505402809-074 *** High Risk Txn: currency mismatch card: USD != txn: EUR"  
  2021-07-18T16:00:58.938-07:00 [INFO] "transaction:tx-1514648212-166 *** High Risk Txn: amount: 12506.00 USD exceeds purchase threshold: 12000.00 USD"  
  2021-07-18T16:00:58.934-07:00 [INFO] "transaction:tx-1505315650-406 *** High Risk Txn: currency mismatch card: USD != txn: GBP"  
  ```
  * Alternatively you can locate the log file for your Eventing function "high\_risk\_txns.log" in the file system and inspect the output (only the last 10 lines are displayed below). Below is a macOS logfile dump. _Note, that if you have more than one Eventing node the logs files will be split up as each eventing node only handles a portion of the documents._  
  ```console  
  cd /Users/a_windows_user/Library/Application\ Support/Couchbase/var/lib/couchbase/data/@eventing  
  tail -10 high_risk_txns.log  
  2021-07-18T16:00:58.927-07:00 [INFO] "transaction:tx-1515315650-412 *** High Risk Txn: currency mismatch card: USD != txn: GBP"  
  2021-07-18T16:00:58.929-07:00 [INFO] "transaction:tx-1519055003-127 *** High Risk Txn: amount: 12506.00 USD exceeds purchase threshold: 12000.00 USD"  
  2021-07-18T16:00:58.931-07:00 [INFO] "transaction:tx-1520387868-416 *** High Risk Txn: currency mismatch card: USD != txn: GBP"  
  2021-07-18T16:00:58.934-07:00 [INFO] "transaction:tx-1505315650-406 *** High Risk Txn: currency mismatch card: USD != txn: GBP"  
  2021-07-18T16:00:58.938-07:00 [INFO] "transaction:tx-1514648212-166 *** High Risk Txn: amount: 12506.00 USD exceeds purchase threshold: 12000.00 USD"  
  2021-07-18T16:00:58.952-07:00 [INFO] "transaction:tx-1505402809-074 *** High Risk Txn: currency mismatch card: USD != txn: EUR"  
  2021-07-18T16:00:58.953-07:00 [INFO] "transaction:tx-1511710690-182 *** High Risk Txn: amount: 12506.00 USD exceeds purchase threshold: 12000.00 USD"  
  2021-07-18T16:00:58.959-07:00 [INFO] "transaction:tx-1514388425-140 *** High Risk Txn: amount: 12506.00 USD exceeds purchase threshold: 12000.00 USD"  
  2021-07-18T16:00:58.960-07:00 [INFO] "transaction:tx-1520344750-416 *** High Risk Txn: currency mismatch card: USD != txn: GBP"  
  2021-07-18T16:00:58.978-07:00 [INFO] "transaction:tx-1505315650-403 *** High Risk Txn: currency mismatch card: USD != txn: GBP"  
  ```  
  The default directories for the Eventing Application Logs are as follows:

| Platform | Location                                                                                                            |
| -------- | ------------------------------------------------------------------------------------------------------------------- |
| Linux    | /opt/couchbase/var/lib/couchbase/data/@eventing/                                                                    |
| Windows  | C:\\Program Files\\Couchbase\\Server\\var\\lib\\couchbase\\data\\@eventing\\(Assumes default installation location) |
| Mac OS X | /Users/<user>/Library/Application\\ Support/Couchbase/var/lib/couchbase/data/@eventing/                             |
14. To check the resulting documents of the deployed Function, access the **Couchbase Web Console** \> **Documents** page then select the keyspace `bulk`.`data`.`review`. You should see 40 new documents in this collection. All documents written to this collection are transactions that are flagged as high-risk transactions.  
![high risk txns 08 bucket documents](_images/high_risk_txns_08_bucket_documents.png)  

  * You can select any document in the **review** collection. In addition you can select by a specific key, for example `transaction:tx-1505315650-403`, by cutting and pasting this ID into the **Document ID** text box and hitting Return.  
  ![high risk txns 08 bucket documents by id](_images/high_risk_txns_08_bucket_documents_by_id.png)  
  Edit the document, the resulting dialog indicates that a purchase of an iMac was flagged as the credit card's default currency was USD, but the purchase was in GBP, e.g. made with a merchant in a foreign country using a foreign currency.  
  ```json  
  {  
    "type": "transaction",  
    "txnid": "tx-1505315650-403",  
    "amount": 5383.35,  
    "product": "Computer, iMac 64GB 4TB Nvme",  
    "card": "4273-6623-8686-4599",  
    "merchant": "Apple Regent Street",  
    "date": "2018-09-14T20:46:10+05:30",  
    "currency": "GBP",  
    "comments": "High Risk Txn: currency mismatch card: USD != txn: GBP",  
    "reason_code": "X-MISMATCH"  
  }  
  ```  
  ![high risk txns 08 bucket documents edit](_images/high_risk_txns_08_bucket_documents_edit.png)
15. From the **Couchbase Web Console** \> **Query** page, run a few SQL++ queries on the new documents create in the **'review**' bucket:

**QUERY A**, see how many high-risk transactions we found.  
```sqlpp  
SELECT COUNT(*) num_high_risk FROM `bulk`.`data`.`review` WHERE type='transaction';  
```  
![high risk txns 09 n1ql a](_images/high_risk_txns_09_n1ql_a.png)  

**QUERY B**, look at all the data and with a specific order.  
```sqlpp  
SELECT * FROM `bulk`.`data`.`review` WHERE type='transaction'  
ORDER BY currency, amount DESC;  
```  
![high risk txns 09 n1ql b](_images/high_risk_txns_09_n1ql_b.png)  

**QUERY C**, look at the summarized data and with a specific order and grouping.  
```sqlpp  
SELECT COUNT(*) count, reason_code, SUM(amount) total_amount, currency  
FROM `bulk`.`data`.`review` WHERE type='transaction'  
GROUP BY reason_code, currency ORDER by count DESC;  
```  
![high risk txns 09 n1ql c](_images/high_risk_txns_09_n1ql_c.png)  

**QUERY D**, look at a transaction record or document by key.  
```sqlpp  
SELECT * FROM `bulk`.`data`.`register` USE KEYS ('transaction:tx-1505315650-403');  
```  
![high risk txns 09 n1ql d](_images/high_risk_txns_09_n1ql_d.png)  

**QUERY E**, look at a card record or document by key.  
```sqlpp  
SELECT * FROM `bulk`.`data`.`register` USE KEYS ('card:4273-6623-8686-4599');  
```  
![high risk txns 09 n1ql e](_images/high_risk_txns_09_n1ql_e.png)  

**QUERY F**, look at a flagged transaction record or document that we wrote by key.  
```sqlpp  
SELECT * FROM `bulk`.`data`.`review` USE KEYS ('transaction:tx-1505315650-403');  
```  
![high risk txns 09 n1ql f](_images/high_risk_txns_09_n1ql_f.png)
16. The next step is to follow the Function logic in detail. To do this we need to remove all of the generated documents in review collection. We will use SQL++ to do this.  
From the **Couchbase Web Console** \> **Query** page, run a the SQL++ statement  
```sqlpp  
DELETE FROM `bulk`.`data`.`review`;  
```  
You will get a warning about _"no WHERE clause or USE KEYS"_, ignore this and Click **Continue**.
17. From the **Couchbase Web Console** \> **Eventing** page, click **high\_risk\_txns** to expand the function, and then click **Pause**.  
![high risk txns 10 pause](_images/high_risk_txns_10_pause.png)  

  * In the **Confirm Pause Function** dialog, click **Pause Function**.  
  ![high risk txns 10 pause confirm](_images/high_risk_txns_10_pause_confirm.png)
  * The Eventing function is paused in a few seconds and can be edited. Click the **'Edit JavaScript'** button.
  * In the Editor dialog change the OnUpdate handler code from `var verbose = 0` to `var verbose = 3` — you are only modifying line four of the **high\_risk\_txns** function as below:  
  ```JavaScript  
  function OnUpdate(doc, meta) {  
    if (doc.type != "transaction") return;  
    try {  
      var verbose = 3; // logging - 0: minimal, 1: moderate, 2: massive  
      // *** many lines not shown ***  
  ```
  * Click **'Save and Return'**.
18. From the **Eventing** screen, click **Resume**.  
![high risk txns 10 resume](_images/high_risk_txns_10_resume.png)  

  * In the **Confirm Resume Function** dialog, click **Resume Function**.  
  ![high risk txns 10 resume confirm](_images/high_risk_txns_10_resume_confirm.png)
19. The Eventing function is resumed from the check point created when you paused the function and will start running within a few seconds. The defined function is resumed form a checkpoint created when you paused the function. The function will execute on all new documents and any mutations occurring after the checkpoint. Until a mutation is triggered there will be no processing at all by our modified handler's JavaScript code.
20. The next step is to create one mutation, to do this access the **Couchbase Web Console** \> **Documents** page then select the keyspace `bulk`.`data`.`register` (the source of the mutations that our Function watches).

  * Select the document `transaction:tx-1505315650-403` by cutting and pasting this ID into the **Document ID** text box and hitting Return.  
  ![high risk txns 10 bucket register id](_images/high_risk_txns_10_bucket_register_id.png)
  * This should display a single document. Edit it by clicking on it.
  * Adjust the document slightly from `"amount": 5383.35` to `"amount": 5383.36`.  
  ![high risk txns 10 modify](_images/high_risk_txns_10_modify.png)
  * Click **'Save'**.
  * Inspect the new data written to the "high\_risk\_txns.log" in the file system (or alternatively use the UI's Log link).  
  ```console  
  cd /Users/jon.strabala/Library/Application\ Support/Couchbase/var/lib/couchbase/data/@eventing  
  tail -9 high_risk_txns.log  
  2021-07-18T16:41:20.522-07:00 [INFO] "transaction:tx-1505315650-403 Process transaction for doc.card: 4273-6623-8686-4599, doc.amount: 5383.36"  
  2021-07-18T16:41:20.525-07:00 [INFO] "transaction:tx-1505315650-403 doc   " {"type":"transaction","txnid":"tx-1505315650-403","amount":5383.36,"product":"Computer, iMac 64GB 4TB Nvme","card":"4273-6623-8686-4599","merchant":"Apple Regent Street","city":{"name":"London","code":"W1B 2EL","county":"Westminster","display":"London Westminster"},"date":"2018-09-14T20:46:10+05:30","currency":"GBP"}  
  2021-07-18T16:41:20.525-07:00 [INFO] "transaction:tx-1505315650-403 card  " {"type":"card","cardnumber":"4273-6623-8686-4599","firstname":"Winfred","lastname":"Raftery","street":"3965 I-80 E Off Ramp","mobile":"+1-617-555-1371","sms":true,"city":{"name":"Uxbridge","code":"MA","state":"Massachusetts","county":"Worcester","display":"Uxbridge"},"issued":"11/15","expiry":"6/19","ccv":736,"issuer":"Helena National Bank","maxcredit":1000,"threshold":9500,"country":"US","currency":"USD"}  
  2021-07-18T16:41:20.525-07:00 [INFO] "transaction:tx-1505315650-403 rates " {"type":"exchange_rates","erid":"er-2018-09-14","to_USD":{"CAD":1.3008811703,"INR":71.8162374882,"EUR":0.8555051758,"USD":1,"SGD":1.3698348875,"GBP":0.7633501583,"CNY":6.8543074686,"AUD":1.3910514159}}  
  2021-07-18T16:41:20.525-07:00 [INFO] "transaction:tx-1505315650-403 1 doc.amount        5383.36, card_limit        9500.00"  
  2021-07-18T16:41:20.525-07:00 [INFO] "transaction:tx-1505315650-403 2 trxn_currency         GBP, card_currency         USD"  
  2021-07-18T16:41:20.525-07:00 [INFO] "transaction:tx-1505315650-403 3 trxn_2_USD       0.763350, card_2_USD       1.000000"  
  2021-07-18T16:41:20.525-07:00 [INFO] "transaction:tx-1505315650-403 4 trxn_amount_USD   7052.28, card_thresh_USD   9500.00"  
  2021-07-18T16:41:20.525-07:00 [INFO] "transaction:tx-1505315650-403 *** High Risk Txn: currency mismatch card: USD != txn: GBP"  
  ```  
  Above we see that for one mutation the Function **high\_risk\_txns** printed the following log messages:
  * The transaction document 'doc' that mutated (what you just changed).
  * The 'card' or credit card that the transaction was made with was looked up via the key _'card:' + doc.card_ from the bucket alias register.
  * A daily 'rates' or exchange rates for the date of the transaction which was looked up via the key _'exchange\_rates:er-' + (doc.date).substr(0, 10))_ from the bucket alias register.
  * Next a bit of information (4 lines) was emitted to show what was done in order to make the final decision.
  * Finally, the last log line is the decision line (if the transaction is considered 'High Risk'). The amount of information at this verbosity level would be excessive for millions of documents, however it can be very handy for developing and debugging Eventing handler JavaScript logic.

**Cleanup**:

Go to the Eventing portion of the UI and undeploy the Function **high\_risk\_txns**, this will remove the 1024 documents (64 for macOS) for the function from the 'rr100.eventing.metadata' collection (in the Bucket view of the UI). Remember you may only delete the 'rr100.eventing.metadata' keyspace if there are no deployed Eventing Functions.

From the **Eventing** screen, click **Undeploy**.

![high risk txns 11 undeploy](_images/high_risk_txns_11_undeploy.png) 

In the **Confirm Undeploy Function** dialog, click **high\_risk\_txns** to expand the function, and then click **Undeploy Function**.

![high risk txns 11 undeploy confirm](_images/high_risk_txns_11_undeploy_confirm.png) 

The Eventing function will be undeployed within a few seconds.

Now flush the 'bulk' bucket if you plan to run other examples (you may need to Edit the bucket 'bulk' and enable the flush capability).