mirror of
https://github.com/we-promise/sure.git
synced 2026-04-25 06:54:07 +00:00
Provider optimisation (#375)
* Implement a provider configured account type * Fix for SimpleFIN * FIX tests and linter
This commit is contained in:
@@ -31,6 +31,27 @@ class Provider::Base
|
||||
raise NotImplementedError, "#{self.class} must implement #provider_name"
|
||||
end
|
||||
|
||||
# Defines which account types this provider supports
|
||||
# Override in subclasses to specify supported account types
|
||||
# @return [Array<String>] Array of account type class names (e.g., ["Depository", "CreditCard"])
|
||||
def self.supported_account_types
|
||||
[]
|
||||
end
|
||||
|
||||
# Returns provider connection configurations
|
||||
# Override in subclasses to provide connection metadata for UI
|
||||
# @param family [Family] The family to check connection availability for
|
||||
# @return [Array<Hash>] Array of connection configurations with keys:
|
||||
# - key: Unique identifier (e.g., "lunchflow", "plaid_us")
|
||||
# - name: Display name (e.g., "Lunch Flow", "Plaid")
|
||||
# - description: User-facing description
|
||||
# - can_connect: Boolean, whether family can connect to this provider
|
||||
# - new_account_path: Proc that generates path for new account flow
|
||||
# - existing_account_path: Proc that generates path for linking existing account
|
||||
def self.connection_configs(family:)
|
||||
[]
|
||||
end
|
||||
|
||||
# Returns the provider type (class name)
|
||||
# @return [String] The provider account class name
|
||||
def provider_type
|
||||
|
||||
@@ -63,6 +63,39 @@ class Provider::Factory
|
||||
find_adapter_class(provider_type).present?
|
||||
end
|
||||
|
||||
# Get all registered adapter classes
|
||||
# @return [Array<Class>] List of registered adapter classes
|
||||
def registered_adapters
|
||||
ensure_adapters_loaded
|
||||
registry.values.uniq
|
||||
end
|
||||
|
||||
# Get adapters that support a specific account type
|
||||
# @param account_type [String] The account type class name (e.g., "Depository", "CreditCard")
|
||||
# @return [Array<Class>] List of adapter classes that support this account type
|
||||
def adapters_for_account_type(account_type)
|
||||
registered_adapters.select do |adapter_class|
|
||||
adapter_class.supported_account_types.include?(account_type)
|
||||
end
|
||||
end
|
||||
|
||||
# Check if any provider supports a given account type
|
||||
# @param account_type [String] The account type class name
|
||||
# @return [Boolean]
|
||||
def supports_account_type?(account_type)
|
||||
adapters_for_account_type(account_type).any?
|
||||
end
|
||||
|
||||
# Get all available provider connection configs for a given account type
|
||||
# @param account_type [String] The account type class name (e.g., "Depository")
|
||||
# @param family [Family] The family to check connection availability for
|
||||
# @return [Array<Hash>] Array of connection configurations from all providers
|
||||
def connection_configs_for_account_type(account_type:, family:)
|
||||
adapters_for_account_type(account_type).flat_map do |adapter_class|
|
||||
adapter_class.connection_configs(family: family)
|
||||
end
|
||||
end
|
||||
|
||||
# Clear all registered adapters (useful for testing)
|
||||
def clear_registry!
|
||||
@registry = {}
|
||||
|
||||
@@ -5,6 +5,34 @@ class Provider::LunchflowAdapter < Provider::Base
|
||||
# Register this adapter with the factory
|
||||
Provider::Factory.register("LunchflowAccount", self)
|
||||
|
||||
# Define which account types this provider supports
|
||||
def self.supported_account_types
|
||||
%w[Depository CreditCard Loan]
|
||||
end
|
||||
|
||||
# Returns connection configurations for this provider
|
||||
def self.connection_configs(family:)
|
||||
return [] unless family.can_connect_lunchflow?
|
||||
|
||||
[ {
|
||||
key: "lunchflow",
|
||||
name: "Lunch Flow",
|
||||
description: "Connect to your bank via Lunch Flow",
|
||||
can_connect: true,
|
||||
new_account_path: ->(accountable_type, return_to) {
|
||||
Rails.application.routes.url_helpers.select_accounts_lunchflow_items_path(
|
||||
accountable_type: accountable_type,
|
||||
return_to: return_to
|
||||
)
|
||||
},
|
||||
existing_account_path: ->(account_id) {
|
||||
Rails.application.routes.url_helpers.select_existing_account_lunchflow_items_path(
|
||||
account_id: account_id
|
||||
)
|
||||
}
|
||||
} ]
|
||||
end
|
||||
|
||||
def provider_name
|
||||
"lunchflow"
|
||||
end
|
||||
|
||||
@@ -17,6 +17,63 @@ class Provider::PlaidAdapter < Provider::Base
|
||||
# Register this adapter with the factory for ALL PlaidAccount instances
|
||||
Provider::Factory.register("PlaidAccount", self)
|
||||
|
||||
# Define which account types this provider supports (US region)
|
||||
def self.supported_account_types
|
||||
%w[Depository CreditCard Loan Investment]
|
||||
end
|
||||
|
||||
# Returns connection configurations for this provider
|
||||
# Plaid can return multiple configs (US and EU) depending on family setup
|
||||
def self.connection_configs(family:)
|
||||
configs = []
|
||||
|
||||
# US configuration
|
||||
if family.can_connect_plaid_us?
|
||||
configs << {
|
||||
key: "plaid_us",
|
||||
name: "Plaid",
|
||||
description: "Connect to your US bank via Plaid",
|
||||
can_connect: true,
|
||||
new_account_path: ->(accountable_type, return_to) {
|
||||
Rails.application.routes.url_helpers.new_plaid_item_path(
|
||||
region: "us",
|
||||
accountable_type: accountable_type
|
||||
)
|
||||
},
|
||||
existing_account_path: ->(account_id) {
|
||||
Rails.application.routes.url_helpers.select_existing_account_plaid_items_path(
|
||||
account_id: account_id,
|
||||
region: "us"
|
||||
)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
# EU configuration
|
||||
if family.can_connect_plaid_eu?
|
||||
configs << {
|
||||
key: "plaid_eu",
|
||||
name: "Plaid (EU)",
|
||||
description: "Connect to your EU bank via Plaid",
|
||||
can_connect: true,
|
||||
new_account_path: ->(accountable_type, return_to) {
|
||||
Rails.application.routes.url_helpers.new_plaid_item_path(
|
||||
region: "eu",
|
||||
accountable_type: accountable_type
|
||||
)
|
||||
},
|
||||
existing_account_path: ->(account_id) {
|
||||
Rails.application.routes.url_helpers.select_existing_account_plaid_items_path(
|
||||
account_id: account_id,
|
||||
region: "eu"
|
||||
)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
configs
|
||||
end
|
||||
|
||||
# Mutex for thread-safe configuration loading
|
||||
# Initialized at class load time to avoid race conditions on mutex creation
|
||||
@config_mutex = Mutex.new
|
||||
|
||||
@@ -5,6 +5,33 @@ class Provider::SimplefinAdapter < Provider::Base
|
||||
# Register this adapter with the factory
|
||||
Provider::Factory.register("SimplefinAccount", self)
|
||||
|
||||
# Define which account types this provider supports
|
||||
def self.supported_account_types
|
||||
%w[Depository CreditCard Loan Investment]
|
||||
end
|
||||
|
||||
# Returns connection configurations for this provider
|
||||
def self.connection_configs(family:)
|
||||
return [] unless family.can_connect_simplefin?
|
||||
|
||||
[ {
|
||||
key: "simplefin",
|
||||
name: "SimpleFIN",
|
||||
description: "Connect to your bank via SimpleFIN",
|
||||
can_connect: true,
|
||||
new_account_path: ->(accountable_type, return_to) {
|
||||
Rails.application.routes.url_helpers.new_simplefin_item_path(
|
||||
accountable_type: accountable_type
|
||||
)
|
||||
},
|
||||
existing_account_path: ->(account_id) {
|
||||
Rails.application.routes.url_helpers.select_existing_account_simplefin_items_path(
|
||||
account_id: account_id
|
||||
)
|
||||
}
|
||||
} ]
|
||||
end
|
||||
|
||||
def provider_name
|
||||
"simplefin"
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user