Files
sure/app/models/provider/plaid_eu_adapter.rb
soky srm e8f935bc6f Remove plaid initialiser (#317)
* Remove plaid initialiser

The initializer can be safely removed because:
  - Config is lazily loaded via Provider::Registry
  - reload_configuration is called after settings updates
  - All calling code handles nil configs gracefully
  - Initial nil state is fine - config loads on first use

* Fix for missing config

* Actually don't pollute application.rb

* Add currency loading for balances

* Fix race condition on lazy load

* Allow loans to be imported in lunch flow also

* Fix currency processor
2025-11-12 16:01:19 +01:00

81 lines
3.2 KiB
Ruby

# PlaidEuAdapter is a configuration-only manager for Plaid EU credentials.
#
# It does NOT register as a provider type because:
# - There's no separate "PlaidEuAccount" model
# - All PlaidAccounts (regardless of region) use PlaidAdapter as their instance adapter
#
# This class only manages Rails.application.config.plaid_eu, which
# Provider::Registry.plaid_provider_for_region(:eu) uses to create Provider::Plaid instances.
#
# This separation into a distinct adapter class provides:
# - Clear UI separation: "Plaid" vs "Plaid Eu" sections in settings
# - Better UX: Users only configure the region they need
class Provider::PlaidEuAdapter
include Provider::Configurable
# Mutex for thread-safe configuration loading
# Initialized at class load time to avoid race conditions on mutex creation
@config_mutex = Mutex.new
# Configuration for Plaid EU
configure do
description <<~DESC
Setup instructions:
1. Visit the [Plaid Dashboard](https://dashboard.plaid.com/team/keys) to get your API credentials
2. Your Client ID and Secret Key are required to enable Plaid bank sync for European banks
3. For production use, set environment to 'production', for testing use 'sandbox'
DESC
field :client_id,
label: "Client ID",
required: false,
env_key: "PLAID_EU_CLIENT_ID",
description: "Your Plaid Client ID from the Plaid Dashboard for EU region"
field :secret,
label: "Secret Key",
required: false,
secret: true,
env_key: "PLAID_EU_SECRET",
description: "Your Plaid Secret from the Plaid Dashboard for EU region"
field :environment,
label: "Environment",
required: false,
env_key: "PLAID_EU_ENV",
default: "sandbox",
description: "Plaid environment: sandbox, development, or production"
end
# Thread-safe lazy loading of Plaid EU configuration
# Ensures configuration is loaded exactly once even under concurrent access
def self.ensure_configuration_loaded
# Fast path: return immediately if already loaded (no lock needed)
return if Rails.application.config.plaid_eu.present?
# Slow path: acquire lock and reload if still needed
@config_mutex.synchronize do
# Double-check after acquiring lock (another thread may have loaded it)
return if Rails.application.config.plaid_eu.present?
reload_configuration
end
end
# Reload Plaid EU configuration when settings are updated
def self.reload_configuration
client_id = config_value(:client_id).presence || ENV["PLAID_EU_CLIENT_ID"]
secret = config_value(:secret).presence || ENV["PLAID_EU_SECRET"]
environment = config_value(:environment).presence || ENV["PLAID_EU_ENV"] || "sandbox"
if client_id.present? && secret.present?
Rails.application.config.plaid_eu = Plaid::Configuration.new
Rails.application.config.plaid_eu.server_index = Plaid::Configuration::Environment[environment]
Rails.application.config.plaid_eu.api_key["PLAID-CLIENT-ID"] = client_id
Rails.application.config.plaid_eu.api_key["PLAID-SECRET"] = secret
else
Rails.application.config.plaid_eu = nil
end
end
end