Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic Plaid Integration #1433

Merged
merged 26 commits into from
Nov 15, 2024
Merged

Basic Plaid Integration #1433

merged 26 commits into from
Nov 15, 2024

Conversation

zachgoll
Copy link
Collaborator

@zachgoll zachgoll commented Nov 7, 2024

This PR introduces a basic Plaid integration for our hosted app offering, which includes:

  • Bank linking
  • Automated transaction syncing
  • Automated investment trade syncing
  • Webhooks (with verification)

Below are some details of the changes and implementation.

Institution UI

Previously, we had an "Institutions" UI that allowed users to add accounts to "institutions" (which were really just "groups"). This feature was confusing (as reported by several users), and therefore, this PR removes it entirely. Now, users will see all manually tracked accounts in a single group and Plaid institutions in their own groups:

CleanShot 2024-11-15 at 09 06 09

Syncable Concern

I've reworked Syncable so that the Family, PlaidItem, and Account can all be "synced". Each "syncable" is expected to implement it's own implementation of sync_data:

# account.rb (example)
def sync_data(start_date: nil)
  update!(last_synced_at: Time.current)

  resolve_stale_issues
  Balance::Syncer.new(self, start_date: start_date).run
  Holding::Syncer.new(self, start_date: start_date).run
end

This method will be called by Sync, which is a generic model that performs a "sync" against a specific model and handles errors:

def perform
  start!

  syncable.sync_data(start_date: start_date)

  complete!
rescue StandardError => error
  fail! error
  raise error if Rails.env.development?
end

Initial Plaid Implementation

The Plaid domain consists of the following classes:

class PlaidItem < ApplicationRecord
  belongs_to :family
end

class PlaidAccount < ApplicationRecord
  belongs_to :plaid_item
  has_one :account, dependent: :destroy
end

# Existing model
class Account < Application 
  belongs_to :family 
  belongs_to :plaid_account, optional: true
end

A PlaidItem maps 1:1 with Plaid Items while a PlaidAccount maps 1:1 with Plaid Accounts. These classes use Provider::Plaid through the Plaidable concern in order to fetch Plaid data. These classes are then responsible for providing mappings and transformations required prior to loading data to the Account (Maybe domain).

An Account can optionally belong to a PlaidItem. In this case, it is a "linked account" and will be synced at both the PlaidItem level (fetching and storing Plaid data) and the Account level (syncing balances and holdings).

If an Account does not belong_to a PlaidItem, it is considered a "manually tracked account".

@zachgoll zachgoll marked this pull request as ready for review November 8, 2024 01:49
@zachgoll zachgoll marked this pull request as draft November 8, 2024 16:26
@zachgoll zachgoll marked this pull request as ready for review November 8, 2024 18:40
@zachgoll zachgoll marked this pull request as ready for review November 15, 2024 00:13
@zachgoll zachgoll merged commit cbba2ba into main Nov 15, 2024
5 checks passed
@zachgoll zachgoll deleted the zachgoll/plaid-integration branch November 15, 2024 18:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants