🔗
Linker Studio
  • Welcome!!
  • 🚀GETTING STARTED
    • Set up your custom project from Linker Studio
    • How to run the project
    • Linker Features
      • Glossary
      • Web
      • Mobile
        • Aggregators
        • Analytics
        • Authentication
        • BaaS
        • Carousel
        • Client Support
        • Error and Crash Reporting
        • Info Onboarding
        • KYC
        • Payroll
        • Pii Onboarding
        • Push Notifications - OneSignal
        • Settings
        • Subscriptions
      • Backend
        • Authentication
        • MFA
        • BaaS
        • Aggregators
        • Notifications
        • Payments
        • Deposit Switching
        • Support
        • Vault
        • Storage
        • Monitoring
        • Analytics
  • 🖥️WEB FEATURES
    • Page 2
  • 📱Mobile App Features
    • Project File Structure
    • Figma Tokens Integration
    • Core Module
      • Core UI Components
        • Atoms
        • Molecules
        • Organisms
        • Templates
      • Core Elements
      • Hooks
        • Force update
      • Endpoints used
      • States And Selectors
        • contentsDocuments
    • Modules
      • [New Feature Template]- Feature Name
        • UI Components - Template
          • Atoms
          • Molecules
          • Organisms
          • Templates
        • Hooks - Template
        • Endpoints Used
        • States and Selectors - Template
      • 📥KYC
        • Alloy
        • Baas
          • UI Components
            • Templates
          • Hooks - Template
          • Endpoints Used
          • States and Selectors - Template
        • common
          • UI Components
            • Templates
          • Endpoints Used
      • 🤝Aggregators
        • Plaid
          • Plaid/Rize notification before disabling account
      • 🤖Analytics
        • Amplitude
      • 🔐Authentication
        • Hooks
        • Auth0
          • Hooks
            • Login
            • Forgot password
          • 📧Verify Email
            • Hooks
        • Biometrics
          • Hooks
        • Auto Logout
        • States And Selectors
          • Authentication
      • 💰BaaS
        • Common
          • BaaS Navigation
          • External Accounts
          • UI Components
            • Molecules
            • Organisms
            • Templates
          • Hooks
            • Statements
            • Recurrent Transfers
            • Cards
              • Get Full Card
              • Lock and Unlock
              • Request Physical Debit Card
              • Reissue Debit Card
              • Set / Reset Debit Card Pin
            • Transfer
          • States And Selectors
            • Customer
            • Accounts
            • Cards
            • Transactions
          • Endpoints used
          • Constants
            • ACH_SERVICES
        • treasury
          • Constants
            • CONFIG_VALUES
      • 🛂Client Support
      • 🐛Error and Crash Reporting
        • Crashlytics
      • ℹ️Info Onboarding
        • States and Selectors
        • Hooks
          • Physical Card Request
      • 🌯Linker Wrapper
        • Linker Wrapper Messages Structure
        • Linker Wrapper Features
          • Push Notifications
            • Braze
          • In-App Purchase
      • 🛗MFA Verification Code
        • UI Components
          • Molecules
          • Templates
        • Hooks
        • Endpoints used
        • Configurable Constants
      • 🗞️Payroll
        • UI Components
          • Organisms
          • Templates
        • Hooks
        • States and Selectors
      • 📋PII Onboarding
        • UI Components
          • Atoms
          • Molecules
          • Organisms
          • Templates
        • Hooks
        • States and Selectors
      • 🔔Push Notifications
        • OneSignal
      • 🔧Settings
      • 🗄️Vault
        • VGS Show
        • VGS Collect
    • Cookbook
      • 🏦Neobank
        • Linked Functionalities
          • Edit Personal Details Linking
          • Request Physical Debit Card Linking
          • Get customer Data after SignUp/Login
  • ⛓️Backend API
    • Environments
    • Migrations
      • Configuration
      • Migration Commands
      • Base Model
      • Migration Structure
    • Seeds and Factories
      • Configuration
      • Seeds And Factories
    • SoftDelete
    • DB Fields Encryption
    • DB Structure
    • DB Configuration Table
      • API Endpoints
    • Orchestrator
    • Swagger
      • Setup
      • Decorators for Requests and Responses
      • Decorators for Controllers and HTTP Responses
      • Auth Decorator
      • Multiple Decorators
  • 🪙Finance Integrations
    • Recurring Transfers
      • Architecture
      • Jobs Server
      • Functionality
      • BaaS
        • Rize API Endpoints
        • Treasury Prime API Endpoints
        • Business Treasury Prime API Endpoints
    • BaaS
      • Rize
        • Env Variables
        • Rize API authentication
        • Onboarding
          • Customer Enrollment
          • Get Compliance Workflow
          • Acknowledge Compliance Workflow
          • Customer Complete Enrollment
        • KYC - Know Your Customer
          • Get KYC Documents
          • Upload KYC Document
        • Accounts
          • Get Customer Accounts
          • Get Customer Account By ID
          • Create Customer Account
          • Archive Customer Account
          • Get ACH Customer Accounts
        • Debit Cards
          • Get Debit Cards
          • Get Debit Card Image
          • Lock Debit Card
          • Unlock Debit Card
          • Create Physical Card
          • Activate Debit Card
          • Get Debit Card Set-Pin URL
          • Reissue Debit Card
        • Transactions
          • Get Transactions
        • Transfers
          • Internal Transfers
          • ACH transfers
        • Statements
          • Get Statements
          • Get Statement Document
        • Fake Transactions
        • Message Queue
        • Web Sockets
        • API Endpoints
          • Account Enums
          • Debit Card Enums
          • Transaction Enums
          • KYC Enums
      • Galileo
        • Environment Variables
        • Onboarding
          • Get Customer
          • Customer Enrollment
          • Customer Complete Enrollment
        • Customer Management
          • Get Profile
          • Update Profile
        • Accounts
        • Add Accounts
        • Card Management
          • Get Debit Cards
          • Get Image Card
          • Card Statuses
          • Debit Card Activation
          • Request Physical Card
          • Set PIN
          • Lock/Unlock
        • Transfer
        • Transactions
          • Get Transactions
          • Filter Transactions
        • ACH
          • Add ACH Account
          • Get ACH Accounts
          • Remove ACH Account
          • ACH Transactions
        • Statements
        • Plaid Integration
      • Synapse
        • Environment Variables
        • Terminology
        • Resources
        • API Endpoints
    • Aggregators
      • Add Account Service and new DB Table
      • Plaid
        • Plaid Configuration
        • Application Creation
        • Custom Application
        • Configure Single or Multi Accounts
        • Security Settings
        • Verification of Environment Variables
        • API Endpoints
        • Resources
        • Integrations
          • Rize
      • MX
        • Env Configuration
        • API Endpoints
  • 🔐Authentication
    • Auth0
      • Configuration
      • Protecting an endpoint
      • Email verification
      • API Reference
    • Twilio
      • 2FA
        • Verify Service Configuration
        • Verification Workflow
        • API Endpoints
  • 🪪 KYC
    • Persona
      • Configuration
      • Environment Variables
      • KYC Flow
  • ✉️ Mailings
    • Sendgrid
      • Configuration
      • Environment Variables
      • Send Email with Attachments
  • 🆘Supports
    • Zendesk
      • Configuration
      • API Endpoints
  • 📳NOTIFICATIONS
    • OneSignal
      • Schema
      • Setup
      • Environment Variables
      • API Endpoints
  • 🔐Security
    • VGS
      • Configuration
      • Rize Route Configuration
      • VGS Vault Basics
      • VGS Show
  • 🖥️MONITORING
    • New Relic
      • Configuration
      • Interceptor
  • 🧑‍🔧CONTENT ADMINISTRATOR
    • Notifications
    • Onboardings
      • DB Schema
      • Admin - API Endpoints
      • Client - API Endpoints
    • Documents
      • Document Category
      • Document
      • Client - API Endpoints
      • Admin - API Endpoints
    • App Versions
      • Device App Versions
      • API - Administrator
      • API - Client
  • 💵Payments
    • Stripe
      • Configuration
      • Customers
      • Sources
      • Authorization
      • Charges
      • API Endpoints
Powered by GitBook
On this page

Was this helpful?

  1. Finance Integrations
  2. Aggregators

Add Account Service and new DB Table

We will create a new account table where the ID of the connected external accounts will be stored. So we will generate a migration for this.

In addition to the account table, indexes are created to perform more optimized searches in the database.

import { MigrationInterface, QueryRunner } from 'typeorm';

export class createTableAccounts1659967614370 implements MigrationInterface {
  public async up(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(
      `CREATE TABLE "public"."account" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "external_id" character varying NULL, "baas_id" character varying NULL, "integration_id" uuid NOT NULL, "user_id" uuid NOT NULL, "created_at" TIMESTAMP NOT NULL DEFAULT now(), "updated_at" TIMESTAMP NOT NULL DEFAULT now(), "deleted_at" TIMESTAMP , CONSTRAINT "PK_9162znh8ld8tylna9z6odivqt8u" PRIMARY KEY ("id"))`,
    );
    await queryRunner.query(
      `ALTER TABLE "public"."account" ADD CONSTRAINT "FK_5i6mtodoa8fcqzujy1qg53nvxlh" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE CASCADE`,
    );
    await queryRunner.query(
      `ALTER TABLE "public"."account" ADD CONSTRAINT "FK_ugmbyl1vy7py0xhyx6qdx46w8a3" FOREIGN KEY ("integration_id") REFERENCES "public"."integration"("id") ON DELETE CASCADE`,
    );

    await queryRunner.query(
      `CREATE INDEX "IDX_twrqghqf5afgc0u5ejz3pb1oco" ON "public"."account" ("user_id")`,
    );

    await queryRunner.query(
      `CREATE INDEX "IDX_oyv3ypxovks0kioee3tk4nyvzq" ON "public"."account" ("integration_id")`,
    );

    await queryRunner.query(
      `CREATE INDEX "IDX_ueqv91y92rs0stsvoyegrhue14" ON "public"."account" ("external_id")`,
    );
  }

  public async down(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(
      `ALTER TABLE "public"."account" DROP CONSTRAINT "FK_5i6mtodoa8fcqzujy1qg53nvxlh"`,
    );
    await queryRunner.query(
      `ALTER TABLE "public"."account" DROP CONSTRAINT "FK_ugmbyl1vy7py0xhyx6qdx46w8a3"`,
    );
    await queryRunner.query(
      `DROP INDEX IF EXISTS "public"."IDX_twrqghqf5afgc0u5ejz3pb1oco"`,
    );
    await queryRunner.query(
      `DROP INDEX IF EXISTS "public"."IDX_oyv3ypxovks0kioee3tk4nyvzq"`,
    );
    await queryRunner.query(
      `DROP INDEX IF EXISTS "public"."IDX_ueqv91y92rs0stsvoyegrhue14"`,
    );

    await queryRunner.query('DROP TABLE "public"."account"');
  }
}

Inside the feature folder, we will create a folder named account and with the following files:

account.entity.ts

In this file we will add the following configuration where we declare the properties and relationships that the accounts table will have.

import { Entity, Column, ManyToOne } from 'typeorm';
import { BaseModel } from 'src/common/database/base-model';
import { Integration } from 'src/features/integration/integration.entity';
import { User } from 'src/features/user/user.entity';
import { encryptionTransformer } from 'src/common/transformers/typeorm-encrypted.transformer';
@Entity()
export class Account extends BaseModel {
  @Column({
    nullable: true,
    transformer: encryptionTransformer,
  })
  public externalId!: string;

 @Column({
    name: 'service_external_id',
    nullable: true,
    transformer: encryptionTransformer,
  })
  public serviceExternalId!: string;

  @Column({ name: 'user_id' })
  public userId!: string;

  @Column({ name: 'integration_id' })
  public integrationId!: string;

  @ManyToOne(() => Integration, (integration) => integration.accounts, {
    nullable: true,
  })
  public integration?: Integration;

  @ManyToOne(() => User, (user) => user.accounts, { nullable: true })
  public user?: User;
}

account.service.ts

This file will have all the methods needed to enter, get, and delete records from the accounts table.

  • addAccount: this method is used to add a new record to the account table.

  • getAccount: this method is used to get an account by its external ID and the integration it belongs to.

  • getAccountsByIntegrationId: this method is used to get all the accounts based on the ID of an integration.

  • getAccountByExternalId: this method is used to get an account using your external ID.

  • removeAccountById: this method is used to delete a record from the accounts table based on the database ID.

  • removeAllAccountsByIngratationId: this method is used to remove all records from the account table based on the ID of an integration.

  • removeAccountByExternalId: this method is used to delete an account based on its external ID.

  • exitsAccountByUser: this method will be used to check if the user already has an account based on an integration and external ID of an account. Returns a boolean value.

  • verifyAccountByUser: this method is used to verify a user's account. If the account does not exist, an exception occurs with a custom message that is passed as a parameter.

import { Injectable, UnprocessableEntityException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { IsNull, Repository } from 'typeorm';
import { Account } from './account.entity';

@Injectable()
export class AccountService {
  public constructor(
    @InjectRepository(Account)
    private readonly accountRepository: Repository<Account>,
  ) {}

  public async addAccount(
    accountId: string,
    userId: string,
    integrationId: string,
    serviceExternalId?: string,
  ): Promise<void> {
    await this.accountRepository.save({
      externalId: accountId,
      userId: userId,
      integrationId: integrationId,
      serviceExternalId: serviceExternalId,
    });
  }

  public async getAccount(
    accountId: string,
    integrationId: string,
  ): Promise<Account> {
    return await this.accountRepository.findOne({
      where: {
        externalId: accountId,
        integrationId: integrationId,
        deletedAt: IsNull(),
      },
    });
  }

  public async getAccountsByIntegrationId(
    userId: string,
    integrationId: string,
  ): Promise<Account[]> {
    return await this.accountRepository.find({
      where: {
        userId: userId,
        integrationId: integrationId,
      },
    });
  }

  public async getAccountByExternalId(externalId: string): Promise<Account> {
    return await this.accountRepository.findOne({
      withDeleted: true,
      where: {
        externalId: externalId,
      },
    });
  }

  public async removeAccountById(id: string): Promise<void> {
    await this.accountRepository.softDelete(id);
  }

  public async removeAllAccountsByIngratationId(
    integrationId: string,
  ): Promise<void> {
    await this.accountRepository.softDelete({ integrationId });
  }

  public async removeAccountByExternalId(externalId: string): Promise<void> {
    await this.accountRepository.softDelete({ externalId });
  }

  public async exitsAccountByUser(
    userId: string,
    externalId: string,
  ): Promise<boolean> {
    const account = await this.accountRepository.findOne({
      where: { userId, externalId, deletedAt: IsNull() },
    });
    return account != undefined;
  }

  public async verifyAccountByUser(
    userId: string,
    externalId: string,
    errorMessage: string,
  ): Promise<void> {
    const account = await this.accountRepository.findOne({
      where: { userId, externalId, deletedAt: IsNull() },
    });
    if (!account) {
      throw new UnprocessableEntityException(errorMessage);
    }
  }
}

accounts.module.ts

This file will make the connection between the service and the account entity. We will also import the integration module that will be used in the account service.

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { IntegrationsModule } from '../integration/integrations.module';
import { Account } from './account.entity';
import { AccountService } from './account.service';

@Module({
  imports: [TypeOrmModule.forFeature([Account]), IntegrationsModule],
  providers: [AccountService],
  controllers: [],
  exports: [AccountService],
})
export class AccountsModule {}
PreviousAggregatorsNextPlaid

Last updated 2 years ago

Was this helpful?

🪙
Account folder.