1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-08-09 15:35:22 +02:00

generate mock data for teller

This commit is contained in:
Tyler Myracle 2024-01-17 15:50:05 -06:00
parent e716f71bf9
commit 40f424b8fe
5 changed files with 244 additions and 4 deletions

View file

@ -12,13 +12,15 @@ export enum AccountType {
export type DepositorySubtypes = export type DepositorySubtypes =
| 'checking' | 'checking'
| 'savings' | 'savings'
| 'money market' | 'money_market'
| 'certificate of deposit' | 'certificate_of_deposit'
| 'treasury' | 'treasury'
| 'sweep' | 'sweep'
export type CreditSubtype = 'credit_card' export type CreditSubtype = 'credit_card'
export type AccountStatus = 'open' | 'closed'
interface BaseAccount { interface BaseAccount {
enrollment_id: string enrollment_id: string
links: { links: {
@ -34,7 +36,7 @@ interface BaseAccount {
currency: string currency: string
id: string id: string
last_four: string last_four: string
status: 'open' | 'closed' status: AccountStatus
} }
interface DepositoryAccount extends BaseAccount { interface DepositoryAccount extends BaseAccount {

View file

@ -165,6 +165,7 @@
"@babel/core": "7.17.5", "@babel/core": "7.17.5",
"@babel/preset-react": "^7.14.5", "@babel/preset-react": "^7.14.5",
"@babel/preset-typescript": "7.16.7", "@babel/preset-typescript": "7.16.7",
"@faker-js/faker": "^8.3.1",
"@fast-csv/parse": "^4.3.6", "@fast-csv/parse": "^4.3.6",
"@next/bundle-analyzer": "^13.1.1", "@next/bundle-analyzer": "^13.1.1",
"@nrwl/cli": "15.5.2", "@nrwl/cli": "15.5.2",

View file

@ -0,0 +1,232 @@
import { faker } from '@faker-js/faker'
import { TellerTypes } from '../../libs/teller-api/src'
function generateSubType(
type: TellerTypes.AccountTypes
): TellerTypes.DepositorySubtypes | TellerTypes.CreditSubtype {
if (type === 'depository') {
return faker.helpers.arrayElement([
'checking',
'savings',
'money_market',
'certificate_of_deposit',
'treasury',
'sweep',
]) as TellerTypes.DepositorySubtypes
} else {
return 'credit_card' as TellerTypes.CreditSubtype
}
}
type GenerateAccountsParams = {
count: number
enrollmentId: string
institutionName: string
institutionId: string
}
export function generateAccounts({
count,
enrollmentId,
institutionName,
institutionId,
}: GenerateAccountsParams) {
const accounts: TellerTypes.Account[] = []
for (let i = 0; i < count; i++) {
const accountId = faker.string.uuid()
const lastFour = faker.finance.creditCardNumber().slice(-4)
const type: TellerTypes.AccountTypes = faker.helpers.arrayElement(['depository', 'credit'])
let subType: TellerTypes.DepositorySubtypes | TellerTypes.CreditSubtype
subType = generateSubType(type)
const accountStub = {
enrollment_id: enrollmentId,
links: {
balances: `https://api.teller.io/accounts/${accountId}/balances`,
self: `https://api.teller.io/accounts/${accountId}`,
transactions: `https://api.teller.io/accounts/${accountId}/transactions`,
},
institution: {
name: institutionName,
id: institutionId,
},
name: faker.finance.accountName(),
currency: 'USD',
id: accountId,
last_four: lastFour,
status: faker.helpers.arrayElement(['open', 'closed']) as TellerTypes.AccountStatus,
}
if (faker.datatype.boolean()) {
accounts.push({
...accountStub,
type: 'depository',
subtype: faker.helpers.arrayElement([
'checking',
'savings',
'money_market',
'certificate_of_deposit',
'treasury',
'sweep',
]),
})
} else {
accounts.push({
...accountStub,
type: 'credit',
subtype: 'credit_card',
})
}
}
return accounts
}
export function generateBalance(account_id: string): TellerTypes.AccountBalance {
const amount = faker.finance.amount()
return {
available: amount,
ledger: amount,
links: {
account: `https://api.teller.io/accounts/${account_id}`,
self: `https://api.teller.io/accounts/${account_id}/balances`,
},
account_id,
}
}
type GenerateAccountsWithBalancesParams = {
count: number
enrollmentId: string
institutionName: string
institutionId: string
}
export function generateAccountsWithBalances({
count,
enrollmentId,
institutionName,
institutionId,
}: GenerateAccountsWithBalancesParams): TellerTypes.AccountWithBalances[] {
const accountsWithBalances: TellerTypes.AccountWithBalances[] = []
for (let i = 0; i < count; i++) {
const account = generateAccounts({
count,
enrollmentId,
institutionName,
institutionId,
})[0]
const balance = generateBalance(account.id)
accountsWithBalances.push({
...account,
balance,
})
}
return accountsWithBalances
}
export function generateTransactions(count: number, accountId: string): TellerTypes.Transaction[] {
const transactions: TellerTypes.Transaction[] = []
for (let i = 0; i < count; i++) {
const transactionId = `txn_${faker.string.uuid()}`
const transaction = {
details: {
processing_status: faker.helpers.arrayElement(['complete', 'pending']),
category: faker.helpers.arrayElement([
'accommodation',
'advertising',
'bar',
'charity',
'clothing',
'dining',
'education',
'electronics',
'entertainment',
'fuel',
'general',
'groceries',
'health',
'home',
'income',
'insurance',
'investment',
'loan',
'office',
'phone',
'service',
'shopping',
'software',
'sport',
'tax',
'transport',
'transportation',
'utilities',
]),
counterparty: {
name: faker.company.name(),
type: faker.helpers.arrayElement(['person', 'business']),
},
},
running_balance: null,
description: faker.word.words({ count: { min: 3, max: 10 } }),
id: transactionId,
date: faker.date.recent({ days: 30 }).toISOString().split('T')[0], // recent date in 'YYYY-MM-DD' format
account_id: accountId,
links: {
account: `https://api.teller.io/accounts/${accountId}`,
self: `https://api.teller.io/accounts/${accountId}/transactions/${transactionId}`,
},
amount: faker.finance.amount(),
type: faker.helpers.arrayElement(['transfer', 'deposit', 'withdrawal']),
status: faker.helpers.arrayElement(['pending', 'posted']),
} as TellerTypes.Transaction
transactions.push(transaction)
}
return transactions
}
export function generateEnrollment(): TellerTypes.Enrollment & { institutionId: string } {
const institutionName = faker.company.name()
const institutionId = institutionName.toLowerCase().replace(/\s/g, '_')
return {
accessToken: `token_${faker.string.alphanumeric(15)}`,
user: {
id: `usr_${faker.string.alphanumeric(15)}`,
},
enrollment: {
id: `enr_${faker.string.alphanumeric(15)}`,
institution: {
name: institutionName,
},
},
signatures: [faker.string.alphanumeric(15)],
institutionId,
}
}
export function generateConnections(count: number) {
const enrollments: (TellerTypes.Enrollment & { institutionId: string })[] = []
const accountsWithBalances: TellerTypes.AccountWithBalances[] = []
const transactions: TellerTypes.Transaction[] = []
for (let i = 0; i < count; i++) {
enrollments.push(generateEnrollment())
}
enrollments.forEach((enrollment) => {
const accountCount: number = faker.number.int({ min: 1, max: 5 })
const transactionsCount: number = faker.number.int({ min: 1, max: 50 })
const enrollmentId = enrollment.enrollment.id
const institutionName = enrollment.enrollment.institution.name
const institutionId = enrollment.institutionId
accountsWithBalances.push(
...generateAccountsWithBalances({
count: accountCount,
enrollmentId,
institutionName,
institutionId,
})
)
accountsWithBalances.forEach((account) => {
transactions.push(...generateTransactions(transactionsCount, account.id))
})
})
}

View file

@ -405,7 +405,7 @@
}, },
"test": { "test": {
"executor": "@nrwl/jest:jest", "executor": "@nrwl/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"], "outputs": ["/coverage/libs/teller-api"],
"options": { "options": {
"jestConfig": "libs/teller-api/jest.config.ts", "jestConfig": "libs/teller-api/jest.config.ts",
"passWithNoTests": true "passWithNoTests": true

View file

@ -1730,6 +1730,11 @@
minimatch "^3.1.2" minimatch "^3.1.2"
strip-json-comments "^3.1.1" strip-json-comments "^3.1.1"
"@faker-js/faker@^8.3.1":
version "8.3.1"
resolved "https://registry.yarnpkg.com/@faker-js/faker/-/faker-8.3.1.tgz#7753df0cb88d7649becf984a96dd1bd0a26f43e3"
integrity sha512-FdgpFxY6V6rLZE9mmIBb9hM0xpfvQOSNOLnzolzKwsE1DH+gC7lEKV1p1IbR0lAYyvYd5a4u3qWJzowUkw1bIw==
"@fast-csv/format@^4.3.5": "@fast-csv/format@^4.3.5":
version "4.3.5" version "4.3.5"
resolved "https://registry.yarnpkg.com/@fast-csv/format/-/format-4.3.5.tgz#90d83d1b47b6aaf67be70d6118f84f3e12ee1ff3" resolved "https://registry.yarnpkg.com/@fast-csv/format/-/format-4.3.5.tgz#90d83d1b47b6aaf67be70d6118f84f3e12ee1ff3"