Add CoinStats exchange portfolio sync and normalize linked investment charts (#1308)

* [FEATURE] Add CoinStats exchange portfolios and normalize linked investment charts

* [BUGFIX] Fix CoinStats PR regressions

* [BUGFIX] Fix CoinStats PR review findings

* [BUGFIX] Address follow-up CoinStats PR feedback

* [REFACTO] Extract CoinStats exchange account helpers

* [BUGFIX] Batch linked CoinStats chart normalization

* [BUGFIX] Fix CoinStats processor lint

---------

Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
This commit is contained in:
Anas Limouri
2026-04-01 20:25:06 +02:00
committed by GitHub
parent f63630c0fa
commit a90f9b7317
44 changed files with 2857 additions and 225 deletions

View File

@@ -7,15 +7,7 @@ class AccountableSparklinesController < ApplicationController
# Use HTTP conditional GET so the client receives 304 Not Modified when possible.
if stale?(etag: etag_key, last_modified: family.latest_sync_completed_at)
@series = Rails.cache.fetch(etag_key, expires_in: 24.hours) do
builder = Balance::ChartSeriesBuilder.new(
account_ids: account_ids,
currency: family.currency,
period: Period.last_30_days,
favorable_direction: @accountable.favorable_direction,
interval: "1 day"
)
builder.balance_series
build_series
end
render layout: false
@@ -35,7 +27,37 @@ class AccountableSparklinesController < ApplicationController
family.accounts.visible.where(accountable_type: accountable.name).pluck(:id)
end
def accounts
@accounts ||= family.accounts.visible.where(accountable_type: accountable.name)
end
def build_series
return aggregate_normalized_series if requires_normalized_aggregation?
Balance::ChartSeriesBuilder.new(
account_ids: account_ids,
currency: family.currency,
period: Period.last_30_days,
favorable_direction: @accountable.favorable_direction,
interval: "1 day"
).balance_series
end
def requires_normalized_aggregation?
accounts.any? { |account| account.linked? && account.balance_type == :investment }
end
def aggregate_normalized_series
Balance::LinkedInvestmentSeriesNormalizer.aggregate_accounts(
accounts: accounts,
currency: family.currency,
period: Period.last_30_days,
favorable_direction: @accountable.favorable_direction,
interval: "1 day"
)
end
def cache_key
family.build_cache_key("#{@accountable.name}_sparkline", invalidate_on_data_updates: true)
family.build_cache_key("#{@accountable.name}_sparkline_#{Account::Chartable::SPARKLINE_CACHE_VERSION}", invalidate_on_data_updates: true)
end
end