Add warning for TwelveData plan-restricted tickers (#803)

* Add warning for TwelveData plan-restricted tickers

Fixes #800

- Add Security::PlanRestrictionTracker concern using Rails cache
- Detect plan upgrade errors during Security::Price::Importer sync
- Display amber warning on /settings/hosting with affected tickers
- Include unit tests for the new functionality

* Scope plan restriction cache by provider

Addresses review feedback:
- Cache key now includes provider name to support multiple data providers
- Methods now require provider parameter for proper scoping
- Added tests for provider-scoped restrictions
- Added documentation explaining instance-level API key architecture

* Fix RuboCop array bracket spacing

* Fix empty array bracket spacing

* Move plan upgrade detection to Provider::TwelveData

* Fix provider scoping tests to use direct cache writes

---------

Co-authored-by: mkdev11 <jaysmth689+github@users.noreply.github.com>
This commit is contained in:
MkDev11
2026-01-27 09:45:50 -05:00
committed by GitHub
parent aef582f553
commit eeff4edbea
9 changed files with 280 additions and 2 deletions

View File

@@ -111,9 +111,20 @@ class Security::Price::Importer
)
if response.success?
Security.clear_plan_restriction(security.id, provider: security_provider.class.name.demodulize)
response.data.index_by(&:date)
else
Rails.logger.warn("#{security_provider.class.name} could not fetch prices for #{security.ticker} between #{provider_fetch_start_date} and #{end_date}. Provider error: #{response.error.message}")
error_message = response.error.message
Rails.logger.warn("#{security_provider.class.name} could not fetch prices for #{security.ticker} between #{provider_fetch_start_date} and #{end_date}. Provider error: #{error_message}")
if Security.plan_upgrade_required?(error_message, provider: security_provider.class.name.demodulize)
Security.record_plan_restriction(
security_id: security.id,
error_message: error_message,
provider: security_provider.class.name.demodulize
)
end
Sentry.capture_exception(MissingSecurityPriceError.new("Could not fetch prices for ticker"), level: :warning) do |scope|
scope.set_tags(security_id: security.id)
scope.set_context("security", { id: security.id, start_date: start_date, end_date: end_date })