The overdraft workflow implementation is one of more complex workflow examples that can last for more than 2 months. Yet, apart from some user input handling, the flow is generally linear. This page describes the execution steps of an overdraft, and provides some technical details on it.

Overdraft Workflow State

Like all other workflows, the overdraft one shares some common features:

  1. overdraft - the actual overdraft state and business related parameters (ids, principal, fees, agreement, status, etc.)

  2. state - the execution state as in a state machine that corresponds to different overdraft periods with specific handling logic (grace, after grace, and in default)

  3. idle/ready - synchronization flags that prevent handling user initiated operations while some other process is in action, e.g. do repayment when a fee is being applied, or before an overdraft is properly initialized

  4. ospResult - a flag for a check risk result

  5. replies - a map of requestId to reply entries that is used for the implementation of a request-reply pattern to communicate with TM

Overdraft Life-Cycle

In general, the overdraft passes through several stages of its life-cycle:

  1. Initialize/open

  2. Grace period

  3. After grace period

  4. In default period

  5. Close

Some of them can be skipped depending on the user input, interaction with TM, and the main account state. The further sections cover the execution of each stage.

NOTE: Almost all operations with an overdraft are recorded in history, that is each record has a Change Reason field that describes what operation was attempted, and its result as Change Status - accepted or rejected. Besides storing this data in the DB, we also publish it in several ways: as notifications with Kafka messages, as events, and as customer messages using Ably. Since usually these are sent simultaneously, we will omit these steps further for the sake of simplicity.

Initialize Overdraft

The initialization step consists in running init() activity that creates an accountId to overdraftId mapping in the DB. Only one overdraft can be open for a single main account, and that restriction is tracked with such a dict table. This table is also used for resolving a workflow by accountId using a WorkflowIdResolver.

If initialization cannot be completed, then the whole workflow is considered as failed, and it is not retried automatically.

After an overdraft is initialized, a request to open is processed.

Open Overdraft

To open an overdraft we first perform a risk check to validate the requested overdraft parameters, and see if a customer is allowed to have such an overdraft. First, a request is sent to the OSP (OneStop Platform). This request is asynchronous, like most of others, and upon receiving a response via Kafka, a listener provides it to the workflow using a corresponding signal method. However, this communication turned out to be unreliablel, and sometimes response messages are lost, which is why we perform an extra synchronous call to OSP to get the result if it was not delivered in time.

If the OSP result is success, we then check if requested overdraft parameters match available products that are configured in product-recommendation-manager. This completes the risk check step, and we proceed with sending a request to TM to open an overdraft. Failing to do so on TM side results in the termination of the workflow.

Grace Period

After an overdraft is opened, it transits to the grace period state that lasts for 30 days. The exact duration can be changed by setting safi-services.loan-manager.overdraft.grace-period property. However, this change would affect only new overdrafts.

This period is idle, meaning that a user can trigger some operations with the overdraft, like doing a top-up or repaying. And if the auto-repayment option is enabled (it is on by default), in the end of this period a repayment flow is executed. If a customer has enough money on his main account, and is able to repay the overdraft, then money is deduced, the overdraft is closed, and the workflow completes. Otherwise, the overdraft transits to the after grace period.

NOTE: There remains functionality for sending a user notification about coming periods ends, however this responsibility was transferred to an external service, and is no longer relevant.

After Grace Period

If the principal could not be deducted in the end of the grace period, a fee is applied right afterwards. However, if a customer does not have enough money to pay the fee immediately, then we claim fee debt, and all further handling of this debt is done by debt-manager. Namely, the debt is collected from any other account as soon as there is some money for that.

Once the fee is paid or marked, the overdraft becomes idle again for another 30 days. Just like in the previous case, this duration is configurable with safi-services.loan-manager.overdraft.after-grace-period property, and the period ends with an attempt to deduce the principal. And if it cannot be deducted, then the overdraft goes into the in default state with a marked principal debt.

In Default State

This is an state in which an overdraft ends if there are is unpaid debt after the previous period. Now, a user cannot trigger any operations with the overdraft, like top-up or repay, and the overdraft is basically managed by debt-manager. That is as soon as there is some money on any account, it is used to pay the debt - fee, principal or penalty one. All kinds of debt are processed on the TM side, and penalties are tracked by an external service.

The duration of this period is indefinite, and it lasts until there is no debt remaining. After that the overdraft is closed, and the workflow is completed.

Destroy

The overdraft life-cycle ends with this clean-up method to deactivate the accountId to overdraftId mapping in the DB prior to completing the workflow.

Overdraft Signal Methods

Interaction between TM/external services, and the workflow is based on sending signals to the latter. Besides the common methods like provideReply() and setOSPResult() used for implementing request-reply pattern, and registering OSP check results respectively, there are several other methods that are used for specific business use cases.

Repay

A user can trigger repayment at any time when the workflow is idle in the grace or the after grace periods. This operation attempts to transfer the principal amount from the main account, or from another account if provided in the request, and close the overdraft in case of success. The flow is the same as in money deduction in the end of the overdraft periods.

Top Up

A user can also request a greater principal than the original one while in the grace period. This flow is roughly the same as in opening an overdraft, and involves the same risk checks.

Adjust Fee Debt

This signal changes the fee debt state, and is triggered by a posting instruction from TM/debt-manager. If the debt is rebalanced after it was claimed, then the overdraft fee debt (fees field) is increased by a given amount. If the debt is repaid, then the paid fees value is increased (paidFees field). There is no fee debt if condition fees == paidFees holds.

Adjust Principal Debt

The same as Adjust Fee Debt except that there is no business use case for a principal debt rebalance - it can only be marked once as a whole and then repaid in parts.

Adjust Penalty Debt

The same as Adjust Fee Debt, and the debt is managed by an external services that uses an API to send this signal.

Set Auto-Repayment

Sets an overdraft property whether there must be an automatic money deduction in the end of the grace period.

See also:

Overdraft changes list

Temporal Workflow Tips