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. Within the buckets we need three (3) keyspaces 'bulk.data.register', 'bulk.data.review', and 'rr100.eventing.metadata' (we loosely follow this organization).

      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.

      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 and creating scopes and collections.

      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
      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
      3. Click the Documents link of the register collection (on the right).

        • Again you should see no user records.

          high risk txns 01 documents
      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

      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

        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

          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

          For more details on bucket settings and screen images refer to Bucket Settings.

      2. From the Couchbase Web Console > Query page, build an index for the 'register' collection and an index for the 'review' collection:

        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

        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
      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
        • Copy the following Function and paste it in the placeholder code block of high_risk_txns dialog.

          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
        • 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

        merchants.json

        Merchant information

        type='merchant'

        5001

        Download

        exchange_rates.json

        Daily exchange rates

        type='exchange_rates'

        422

        Download

        txns.json

        Credit Card charges

        type='transaction'

        417

        Download

        An example record from the cards.json file that you just downloaded encapsulates the information of a credit 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"
        }

        An example record from the merchants.json file that you just downloaded encapsulates the information of a merchant:

        {
         "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:

        {
          "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:

        {
          "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)

        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)

        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)

        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
      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
        • 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
        • The dialog should have data similar to the following (only a few selected lines are displayed below):

          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.

          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
        • 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

          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.

          {
            "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
      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.

        SELECT COUNT(*) num_high_risk FROM `bulk`.`data`.`review` WHERE type='transaction';
        high risk txns 09 n1ql a

        QUERY B, look at all the data and with a specific order.

        SELECT * FROM `bulk`.`data`.`review` WHERE type='transaction'
        ORDER BY currency, amount DESC;
        high risk txns 09 n1ql b

        QUERY C, look at the summarized data and with a specific order and grouping.

        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

        QUERY D, look at a transaction record or document by key.

        SELECT * FROM `bulk`.`data`.`register` USE KEYS ('transaction:tx-1505315650-403');
        high risk txns 09 n1ql d

        QUERY E, look at a card record or document by key.

        SELECT * FROM `bulk`.`data`.`register` USE KEYS ('card:4273-6623-8686-4599');
        high risk txns 09 n1ql e

        QUERY F, look at a flagged transaction record or document that we wrote by key.

        SELECT * FROM `bulk`.`data`.`review` USE KEYS ('transaction:tx-1505315650-403');
        high risk txns 09 n1ql f
      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

        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
        • In the Confirm Pause Function dialog, click Pause Function.

          high risk txns 10 pause confirm
        • 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:

          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
        • In the Confirm Resume Function dialog, click Resume Function.

          high risk txns 10 resume confirm
      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
        • 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
        • 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).

          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

      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

      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).