Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions docs/howtos/solutions/index-solutions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,24 @@ Learn how to easily build, test and deploy code for common microservice and cach
</div>

</div>

## Mobile Banking

<div class="row">
<div class="col">
<RedisCard
title="Authentication and Session Storage"
description="Mobile Banking Authentication and Session Storage Using Redis"
page="/howtos/solutions/mobile-banking/session-management"
/>
</div>

<div class="col">
<RedisCard
title="Account Dashboard"
description="Mobile Banking Account Dashboard Using Redis"
page="/howtos/solutions/mobile-banking/account-dashboard"
/>
</div>

</div>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
---
id: index-mb-account-dashboard
title: Mobile Banking Account Dashboard Using Redis
sidebar_label: Mobile Banking Account Dashboard Using Redis
slug: /howtos/solutions/mobile-banking/account-dashboard
authors: [prasan, will]
---

import GeneralAdditionalResources from '../common-mb/additional-resources.mdx';
import MobileBankingSourceCode from '../common-mb/source-code-tip.mdx';
import MobileBankingDataSeeding from '../common-mb/data-seeding.mdx';

<MobileBankingSourceCode />

## What is a mobile banking account dashboard?

An account dashboard is a page in a mobile banking app that instantly renders account highlights to users. A customer can click on any of the accounts on the dashboard to see the real-time account details, such as latest transactions, mortgage amount they have left to pay, checking and savings, etc.

An account dashboard makes a customer's finances easily visible in one place. It reduces financial complexity for the customer and fosters customer loyalty.

The following diagram is an example data architecture for an account dashboard:

![dashboard](./images/dashboard.png)

1. Banks store information in a number of separate databases that support individual banking products
2. Key customer account details (balances, recent transactions) across the banks product portfolio are prefetched into Redis Enterprise using Redis Data Integration (RDI)
3. Redis Enterprise powers customer's account dashboards, enabling mobile banking users to view balances and other high-priority information immediately upon login

## Why you should use Redis for account dashboards in mobile banking

- **Resilience**: Redis Enterprise provides resilience with 99.999% uptime and Active-Active Geo Distribution to prevent loss of critical user profile data

- **Scalability**: Redis Enterprise provides < 1ms performance at incredibly high scale to ensure apps perform under peak loads

- **JSON Support**: Provides the ability to create and store account information as JSON documents with the < 1ms speed of Redis

- **Querying and Indexing**: Redis Enterprise can quickly identify and store data from multiple different databases and index data to make it readily searchable

:::note

Redis Stack supports the [<u>**JSON**</u>](/howtos/redisjson/) data type and allows you to index and querying JSON and [<u>**more**</u>](https://redis.io/docs/stack/). So your Redis data is not limited to simple key-value stringified data.

:::

## Building an account dashboard with Redis

<MobileBankingSourceCode />

Download the above source code and run following command to start the demo application

```sh
docker compose up -d
```

After docker up & running, open [http://localhost:8080/](http://localhost:8080/) url in browser to view application

### Data seeding

<MobileBankingDataSeeding />

### Balance over time

**Dashboard widget**

![Chart](./images/01-ui-balance-over-time.png)

**API endpoint**

| | |
| ------------- | --------------------------------- |
| Endpoint | `/transaction/balance` |
| Code Location | `/routers/transaction-router.js` |
| Parameters | none |
| Return value | `[{x: timestamp, y: value}, ...]` |

The balance endpoint leverages [**Time Series**](https://redis.io/docs/stack/timeseries/), It returns the range of all values from the time series object `balance_ts`. The resulting range is converted to an array of objects with each object containing an `x` property containing the timestamp and a `y` property containing the associated value. This endpoint supplies the time series chart with coordinates to plot a visualization of the balance over time.

```js title="app/routers/transaction-router.js"
const BALANCE_TS = 'balance_ts';

/* fetch transactions up to sometime ago */
transactionRouter.get('/balance', async (req, res) => {
//time series range
const balance = await redis.ts.range(
BALANCE_TS,
Date.now() - 1000 * 60 * 5, //from
Date.now(), //to
);

let balancePayload = balance.map((entry) => {
return {
x: entry.timestamp,
y: entry.value,
};
});

res.send(balancePayload);
});
```

### Biggest spenders

**Dashboard widget**

![Chart](./images/02-ui-biggest-spenders.png)

**API end point**

| | |
| ------------- | -------------------------------- |
| Endpoint | `/transaction//biggestspenders` |
| Code Location | `/routers/transaction-router.js` |
| Parameters | none |
| Return value | `{labels:[...], series:[...] }` |

The biggest spenders endpoint leverages [**sorted sets**](https://redis.io/docs/manual/patterns/indexes/) as a secondary index, It retrieves all members of the sorted set `bigspenders` that have scores greater than zero. The top five or fewer are returned to provide the UI pie chart with data. The labels array contains the names of the biggest spenders and the series array contains the numeric values associated with each member name.

```js title="app/routers/transaction-router.js"
const SORTED_SET_KEY = 'bigspenders';

/* fetch top 5 biggest spenders */
transactionRouter.get('/biggestspenders', async (req, res) => {
const range = await redis.zRangeByScoreWithScores(
SORTED_SET_KEY,
0,
Infinity,
);
let series = [];
let labels = [];

range.slice(0, 5).forEach((spender) => {
series.push(parseFloat(spender.score.toFixed(2)));
labels.push(spender.value);
});

res.send({ series, labels });
});
```

### Search existing transactions

**Dashboard widget**

![Search transactions](./images/03-ui-search-transactions.png)

**API end point**

| | |
| ---------------- | -------------------------------- |
| Endpoint | `/transaction/search` |
| Code Location | `/routers/transaction-router.js` |
| Query Parameters | term |
| Return value | array of results matching term |

The search endpoint leverages [**Search and Query**](https://redis.io/docs/stack/search/), It receives a `term` query parameter from the UI. A [Redis om Node](https://github.com/redis/redis-om-node) query for the fields `description`, `fromAccountName`, and `accountType` will trigger and return results.

```js title="app/routers/transaction-router.js"
transactionRouter.get('/search', async (req, res) => {
const term = req.query.term;

let results;

if (term.length >= 3) {
results = await bankRepo
.search()
.where('description')
.matches(term)
.or('fromAccountName')
.matches(term)
.or('transactionType')
.equals(term)
.return.all({ pageSize: 1000 });
}
res.send(results);
});
```

### Get recent transactions

**Dashboard widget**

![View recent transactions](./images/04-ui-recent-transactions.png)

**API end point**

| | |
| ------------- | -------------------------------- |
| Endpoint | `/transaction/transactions` |
| Code Location | `/routers/transaction-router.js` |
| Parameters | none |
| Return value | array of results |

Even the transactions endpoint leverages [**Search and Query**](https://redis.io/docs/stack/search/). A [Redis om Node](https://github.com/redis/redis-om-node) query will trigger and return ten most recent transactions.

```js title="app/routers/transaction-router.js"
/* return ten most recent transactions */
transactionRouter.get('/transactions', async (req, res) => {
const transactions = await bankRepo
.search()
.sortBy('transactionDate', 'DESC')
.return.all({ pageSize: 10 });

res.send(transactions.slice(0, 10));
});
```

## Ready to use Redis in account dashboard?

Hopefully, this tutorial has helped you visualize how to use Redis for account dashboard, specifically in the context of mobile banking. For additional resources related to this topic, check out the links below:

### Additional resources

- [Mobile Banking Session Management](/howtos/solutions/mobile-banking/session-management)

<GeneralAdditionalResources />
76 changes: 76 additions & 0 deletions docs/howtos/solutions/mobile-banking/common-mb/data-seeding.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
This application leverages **Redis core data structures, JSON, TimeSeries, Search and Query features**. The data seeded is later used to show a searchable transaction overview with realtime updates as well as a personal finance management overview with realtime balance and biggest spenders updates.

On application startup in `app/server.js`, a cron is scheduled to create random bank transactions at regular intervals and seed those transactions in to Redis.

```js title="app/server.js"
//cron job to trigger createBankTransaction() at regular intervals

cron.schedule('*/10 * * * * *', async () => {
const userName = process.env.REDIS_USERNAME;

createBankTransaction(userName);

//...
});
```

- The transaction generator creates a randomized banking debit or credit which will reflect on a (default) starting user balance of $100,000.00
- The **transaction data** is saved as a JSON document within Redis.
- To capture **balance over time**, the `balanceAfter` value is recorded in a TimeSeries with the key `balance_ts` for every transaction.
- To track **biggest spenders**, an associated **`fromAccountName`** member within the sorted set `bigspenders` is incremented by the transaction amount. Note that this amount can be positive or negative.

```js title="app/transactions/transactionsGenerator.js"
let balance = 100000.0;
const BALANCE_TS = 'balance_ts';
const SORTED_SET_KEY = 'bigspenders';

export const createBankTransaction = async () => {
//to create random bank transaction
let vendorsList = source.source; //app/transactions/transaction_sources.js
const random = Math.floor(Math.random() * 9999999999);

const vendor = vendorsList[random % vendorsList.length]; //random vendor from the list

const amount = createTransactionAmount(vendor.fromAccountName, random);
const transaction = {
id: random * random,
fromAccount: Math.floor((random / 2) * 3).toString(),
fromAccountName: vendor.fromAccountName,
toAccount: '1580783161',
toAccountName: 'bob',
amount: amount,
description: vendor.description,
transactionDate: new Date(),
transactionType: vendor.type,
balanceAfter: balance,
};

//redis json feature
const bankTransaction = await bankTransactionRepository.save(transaction);
console.log('Created bankTransaction!');
// ...
};

const createTransactionAmount = (vendor, random) => {
let amount = createAmount(); //random amount
balance += amount;
balance = parseFloat(balance.toFixed(2));

//redis time series feature
redis.ts.add(BALANCE_TS, '*', balance, { DUPLICATE_POLICY: 'first' });
//redis sorted set as secondary index
redis.zIncrBy(SORTED_SET_KEY, amount * -1, vendor);

return amount;
};
```

Sample `bankTransaction` data view using [RedisInsight](https://redis.com/redis-enterprise/redis-insight/)

![bank transaction data](./images/bank-transaction-data.png)

![bank transaction json](./images/bank-transaction-json.png)

:::tip
Download [<u>**RedisInsight**</u>](https://redis.com/redis-enterprise/redis-insight/) to view your Redis data or to play with raw Redis commands in the workbench. Learn more by reading the [<u>**RedisInsight tutorial**</u>](/explore/redisinsight/)
:::
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
id: index-session-management
id: index-mb-session-management
title: Mobile Banking Authentication and Session Storage Using Redis
sidebar_label: Mobile Banking Authentication and Session Storage Using Redis
slug: /howtos/solutions/mobile-banking/session-management
Expand All @@ -8,12 +8,13 @@ authors: [prasan, will]

import GeneralAdditionalResources from '../common-mb/additional-resources.mdx';
import MobileBankingSourceCode from '../common-mb/source-code-tip.mdx';
import MobileBankingDataSeeding from '../common-mb/data-seeding.mdx';

import MobileBankingDashboardBalance from './images/demo-dashboard-balance-widget.png';

<MobileBankingSourceCode />

## What is Authentication and Session Storage for Mobile Banking?
## What is authentication and session storage for mobile banking?

After a user has successfully entered their login credentials, mobile banking apps use a `token` and `sessionId` created by the server to represent a user's identity. The `token` is stored in Redis for the duration of a user session and also sent in the login response to the banking application client (mobile/ browser). The client application then sends the `token` with every request to server and server validates it before processing the request.

Expand Down Expand Up @@ -60,57 +61,7 @@ After docker up & running, open [http://localhost:8080/](http://localhost:8080/)

### Data seeding

On application startup in `app/server.js`, a cron is scheduled to create random bank transactions at regular intervals and seed those transactions in to Redis.

```js title="app/server.js"
//cron job to trigger createBankTransaction() at regular intervals

cron.schedule('*/10 * * * * *', async () => {
const userName = process.env.REDIS_USERNAME;

createBankTransaction(userName);

//...
});
```

```js title="app/transactions/transactionsGenerator.js"
export const createBankTransaction = async () => {
//to create random bank transaction
let vendorsList = source.source; //app/transactions/transaction_sources.js
const random = Math.floor(Math.random() * 9999999999);

const vendor = vendorsList[random % vendorsList.length]; //random vendor from the list

const amount = createTransactionAmount(vendor.fromAccountName, random); //random amount
const transaction = {
id: random * random,
fromAccount: Math.floor((random / 2) * 3).toString(),
fromAccountName: vendor.fromAccountName,
toAccount: '1580783161',
toAccountName: 'bob',
amount: amount,
description: vendor.description,
transactionDate: new Date(),
transactionType: vendor.type,
balanceAfter: balance,
};

const bankTransaction = await bankTransactionRepository.save(transaction);
console.log('Created bankTransaction!');
// ...
};
```

Sample `bankTransaction` data view using [RedisInsight](https://redis.com/redis-enterprise/redis-insight/)

![bank transaction data](./images/bank-transaction-data.png)

![bank transaction json](./images/bank-transaction-json.png)

:::tip
Download [<u>**RedisInsight**</u>](https://redis.com/redis-enterprise/redis-insight/) to view your Redis data or to play with raw Redis commands in the workbench. Learn more by reading the [<u>**RedisInsight tutorial**</u>](/explore/redisinsight/)
:::
<MobileBankingDataSeeding />

### Session configuration

Expand Down