Files
sure/app/models/coinstats_account/processor.rb
Ethan 3b4ab735b0 Add (beta) CoinStats Crypto Wallet Integration with Balance and Transaction Syncing (#512)
* Feat(CoinStats): Scaffold implementation, not yet functional

* Feat(CoinStats): Implement crypto wallet balance and transactions

* Feat(CoinStats): Add tests, Minor improvements

* Feat(CoinStats): Utilize bulk fetch API endpoints

* Feat(CoinStats): Migrate strings to i8n

* Feat(CoinStats): Fix error handling in wallet link modal

* Feat(CoinStats): Implement hourly provider sync job

* Feat(CoinStats): Generate docstrings

* Fix(CoinStats): Validate API Key on provider update

* Fix(Providers): Safely handle race condition in merchance creation

* Fix(CoinStats): Don't catch system signals in account processor

* Fix(CoinStats): Preload before iterating accounts

* Fix(CoinStats): Add no opener / referrer to API dashboard link

* Fix(CoinStats): Use strict matching for symbols

* Fix(CoinStats): Remove dead code in transactions importer

* Fix(CoinStats): Avoid transaction fallback ID collisions

* Fix(CoinStats): Improve Blockchains fetch error handling

* Fix(CoinStats): Enforce NOT NULL constraint for API Key schema

* Fix(CoinStats): Migrate sync status strings to i8n

* Fix(CoinStats): Use class name rather than hardcoded string

* Fix(CoinStats): Use account currency rather than hardcoded USD

* Fix(CoinStats): Migrate from standalone to Provider class

* Fix(CoinStats): Fix test failures due to string changes
2026-01-07 15:59:04 +01:00

69 lines
2.2 KiB
Ruby

# Processes a CoinStats account to update balance and import transactions.
# Updates the linked Account balance and delegates to transaction processor.
class CoinstatsAccount::Processor
include CurrencyNormalizable
attr_reader :coinstats_account
# @param coinstats_account [CoinstatsAccount] Account to process
def initialize(coinstats_account)
@coinstats_account = coinstats_account
end
# Updates account balance and processes transactions.
# Skips processing if no linked account exists.
def process
unless coinstats_account.current_account.present?
Rails.logger.info "CoinstatsAccount::Processor - No linked account for coinstats_account #{coinstats_account.id}, skipping processing"
return
end
Rails.logger.info "CoinstatsAccount::Processor - Processing coinstats_account #{coinstats_account.id}"
begin
process_account!
rescue StandardError => e
Rails.logger.error "CoinstatsAccount::Processor - Failed to process account #{coinstats_account.id}: #{e.message}"
Rails.logger.error "Backtrace: #{e.backtrace.join("\n")}"
report_exception(e, "account")
raise
end
process_transactions
end
private
# Updates the linked Account with current balance from CoinStats.
def process_account!
account = coinstats_account.current_account
balance = coinstats_account.current_balance || 0
currency = parse_currency(coinstats_account.currency) || account.currency || "USD"
account.update!(
balance: balance,
cash_balance: balance,
currency: currency
)
end
# Delegates transaction processing to the specialized processor.
def process_transactions
CoinstatsAccount::Transactions::Processor.new(coinstats_account).process
rescue StandardError => e
report_exception(e, "transactions")
end
# Reports errors to Sentry with context tags.
# @param error [Exception] The error to report
# @param context [String] Processing context (e.g., "account", "transactions")
def report_exception(error, context)
Sentry.capture_exception(error) do |scope|
scope.set_tags(
coinstats_account_id: coinstats_account.id,
context: context
)
end
end
end