diff --git a/.cursor/rules/project-conventions.mdc b/.cursor/rules/project-conventions.mdc index 2ac70891a..835451c28 100644 --- a/.cursor/rules/project-conventions.mdc +++ b/.cursor/rules/project-conventions.mdc @@ -18,8 +18,7 @@ This rule serves as high-level documentation for how you should write code for t - Jobs: Sidekiq + Redis - External - Payments: Stripe - - User bank data syncing: Plaid - - Market data: Synth (our custom API) + - User bank data syncing: Plaid ## Project conventions diff --git a/.cursor/rules/project-design.mdc b/.cursor/rules/project-design.mdc index 4b60f2f9e..3c4ea3471 100644 --- a/.cursor/rules/project-design.mdc +++ b/.cursor/rules/project-design.mdc @@ -158,20 +158,11 @@ app/models/ registry.rb <- Defines available providers by concept concepts/ exchange_rate.rb <- defines the interface required for the exchange rate concept - synth.rb # <- Concrete provider implementation ``` ### One-off data -For data that does not fit neatly into a "concept", an interface is not required and the concrete provider may implement ad-hoc methods called directly in code. For example, the [synth.rb](mdc:app/models/provider/synth.rb) provider has a `usage` method that is only applicable to this specific provider. This should be called directly without any abstractions: - -```rb -class SomeModel < Application - def synth_usage - Provider::Registry.get_provider(:synth)&.usage - end -end -``` +For data that does not fit neatly into a "concept", an interface is not required and the concrete provider may implement ad-hoc methods called directly in code. ## "Provided" Concerns diff --git a/.env.example b/.env.example index ab12d9077..00bde4ad0 100644 --- a/.env.example +++ b/.env.example @@ -17,10 +17,6 @@ SECRET_KEY_BASE=secret-value # Optional self-hosting vars # -------------------------------------------------------------------------------------------------------- -# Optional: Synth API Key for exchange rates + stock prices -# (you can also set this in your self-hosted settings page) -# Get it here: https://synthfinance.com/ -SYNTH_API_KEY= # Optional: Twelve Data API Key for exchange rates + stock prices # (you can also set this in your self-hosted settings page) diff --git a/.env.local.example b/.env.local.example index 88ce74ded..abe6c2d91 100644 --- a/.env.local.example +++ b/.env.local.example @@ -1,6 +1,5 @@ # To enable / disable self-hosting features. SELF_HOSTED=false -# Enable Synth market data (careful, this will use your API credits) -SYNTH_API_KEY=yourapikeyhere +# Enable Twelve market data (careful, this will use your API credits) TWELVE_DATA_API_KEY=yourapikeyhere diff --git a/.env.test.example b/.env.test.example index 37fb9ef92..f42af1685 100644 --- a/.env.test.example +++ b/.env.test.example @@ -6,7 +6,6 @@ SELF_HOSTED=false # Uncomment and fill in live keys when you need to generate a VCR cassette fixture # ================ -# SYNTH_API_KEY= # ================ # Miscellaneous diff --git a/CLAUDE.md b/CLAUDE.md index ed57f55c8..e67a52e61 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -115,7 +115,6 @@ Sidekiq handles asynchronous tasks: ### Multi-Currency Support - All monetary values stored in base currency (user's primary currency) -- Exchange rates fetched from Synth API - `Money` objects handle currency conversion and formatting - Historical exchange rates for accurate reporting diff --git a/app/controllers/settings/hostings_controller.rb b/app/controllers/settings/hostings_controller.rb index 6702bbb94..beda30f75 100644 --- a/app/controllers/settings/hostings_controller.rb +++ b/app/controllers/settings/hostings_controller.rb @@ -6,9 +6,6 @@ class Settings::HostingsController < ApplicationController before_action :ensure_admin, only: :clear_cache def show - synth_provider = Provider::Registry.get_provider(:synth) - @synth_usage = synth_provider&.usage - twelve_data_provider = Provider::Registry.get_provider(:twelve_data) @twelve_data_usage = twelve_data_provider&.usage end @@ -22,10 +19,6 @@ class Settings::HostingsController < ApplicationController Setting.require_email_confirmation = hosting_params[:require_email_confirmation] end - if hosting_params.key?(:synth_api_key) - Setting.synth_api_key = hosting_params[:synth_api_key] - end - if hosting_params.key?(:twelve_data_api_key) Setting.twelve_data_api_key = hosting_params[:twelve_data_api_key] end @@ -43,7 +36,7 @@ class Settings::HostingsController < ApplicationController private def hosting_params - params.require(:setting).permit(:require_invite_for_signup, :require_email_confirmation, :synth_api_key, :twelve_data_api_key) + params.require(:setting).permit(:require_invite_for_signup, :require_email_confirmation, :twelve_data_api_key) end def ensure_admin diff --git a/app/models/family/auto_merchant_detector.rb b/app/models/family/auto_merchant_detector.rb index 39e58a3ad..bea5dab32 100644 --- a/app/models/family/auto_merchant_detector.rb +++ b/app/models/family/auto_merchant_detector.rb @@ -36,9 +36,7 @@ class Family::AutoMerchantDetector source: "ai", name: auto_detection.business_name, website_url: auto_detection.business_url, - ) do |pm| - pm.logo_url = "#{default_logo_provider_url}/#{auto_detection.business_url}" - end + ) end merchant_id = merchant_id || ai_provider_merchant&.id @@ -65,9 +63,6 @@ class Family::AutoMerchantDetector Provider::Registry.get_provider(:openai) end - def default_logo_provider_url - "https://logo.synthfinance.com" - end def user_merchants_input family.merchants.map do |merchant| diff --git a/app/models/provider/registry.rb b/app/models/provider/registry.rb index 9d6de82f3..aeb77a81a 100644 --- a/app/models/provider/registry.rb +++ b/app/models/provider/registry.rb @@ -32,14 +32,6 @@ class Provider::Registry Provider::Stripe.new(secret_key:, webhook_secret:) end - def synth - api_key = ENV.fetch("SYNTH_API_KEY", Setting.synth_api_key) - - return nil unless api_key.present? - - Provider::Synth.new(api_key) - end - def twelve_data api_key = ENV.fetch("TWELVE_DATA_API_KEY", Setting.twelve_data_api_key) @@ -100,13 +92,13 @@ class Provider::Registry def available_providers case concept when :exchange_rates - %i[synth twelve_data] + %i[twelve_data] when :securities - %i[synth twelve_data] + %i[twelve_data] when :llm %i[openai] else - %i[synth plaid_us plaid_eu github openai] + %i[plaid_us plaid_eu github openai] end end end diff --git a/app/models/provider/synth.rb b/app/models/provider/synth.rb deleted file mode 100644 index ed2514ace..000000000 --- a/app/models/provider/synth.rb +++ /dev/null @@ -1,250 +0,0 @@ -class Provider::Synth < Provider - include ExchangeRateConcept, SecurityConcept - - # Subclass so errors caught in this provider are raised as Provider::Synth::Error - Error = Class.new(Provider::Error) - InvalidExchangeRateError = Class.new(Error) - InvalidSecurityPriceError = Class.new(Error) - - def initialize(api_key) - @api_key = api_key - end - - def healthy? - with_provider_response do - response = client.get("#{base_url}/user") - JSON.parse(response.body).dig("id").present? - end - end - - def usage - with_provider_response do - response = client.get("#{base_url}/user") - - parsed = JSON.parse(response.body) - - remaining = parsed.dig("api_calls_remaining") - limit = parsed.dig("api_limit") - used = limit - remaining - - UsageData.new( - used: used, - limit: limit, - utilization: used.to_f / limit * 100, - plan: parsed.dig("plan"), - ) - end - end - - # ================================ - # Exchange Rates - # ================================ - - def fetch_exchange_rate(from:, to:, date:) - with_provider_response do - response = client.get("#{base_url}/rates/historical") do |req| - req.params["date"] = date.to_s - req.params["from"] = from - req.params["to"] = to - end - - rates = JSON.parse(response.body).dig("data", "rates") - - Rate.new(date: date.to_date, from:, to:, rate: rates.dig(to)) - end - end - - def fetch_exchange_rates(from:, to:, start_date:, end_date:) - with_provider_response do - data = paginate( - "#{base_url}/rates/historical-range", - from: from, - to: to, - date_start: start_date.to_s, - date_end: end_date.to_s - ) do |body| - body.dig("data") - end - - data.paginated.map do |rate| - date = rate.dig("date") - rate = rate.dig("rates", to) - - if date.nil? || rate.nil? - Rails.logger.warn("#{self.class.name} returned invalid rate data for pair from: #{from} to: #{to} on: #{date}. Rate data: #{rate.inspect}") - Sentry.capture_exception(InvalidExchangeRateError.new("#{self.class.name} returned invalid rate data"), level: :warning) do |scope| - scope.set_context("rate", { from: from, to: to, date: date }) - end - - next - end - - Rate.new(date: date.to_date, from:, to:, rate:) - end.compact - end - end - - # ================================ - # Securities - # ================================ - - def search_securities(symbol, country_code: nil, exchange_operating_mic: nil) - with_provider_response do - response = client.get("#{base_url}/tickers/search") do |req| - req.params["name"] = symbol - req.params["dataset"] = "limited" - req.params["country_code"] = country_code if country_code.present? - # Synth uses mic_code, which encompasses both exchange_mic AND exchange_operating_mic (union) - req.params["mic_code"] = exchange_operating_mic if exchange_operating_mic.present? - req.params["limit"] = 25 - end - - parsed = JSON.parse(response.body) - - parsed.dig("data").map do |security| - Security.new( - symbol: security.dig("symbol"), - name: security.dig("name"), - logo_url: security.dig("logo_url"), - exchange_operating_mic: security.dig("exchange", "operating_mic_code"), - country_code: security.dig("exchange", "country_code") - ) - end - end - end - - def fetch_security_info(symbol:, exchange_operating_mic:) - with_provider_response do - response = client.get("#{base_url}/tickers/#{symbol}") do |req| - req.params["operating_mic"] = exchange_operating_mic - end - - data = JSON.parse(response.body).dig("data") - - SecurityInfo.new( - symbol: symbol, - name: data.dig("name"), - links: data.dig("links"), - logo_url: data.dig("logo_url"), - description: data.dig("description"), - kind: data.dig("kind"), - exchange_operating_mic: exchange_operating_mic - ) - end - end - - def fetch_security_price(symbol:, exchange_operating_mic: nil, date:) - with_provider_response do - historical_data = fetch_security_prices(symbol:, exchange_operating_mic:, start_date: date, end_date: date) - - raise ProviderError, "No prices found for security #{symbol} on date #{date}" if historical_data.data.empty? - - historical_data.data.first - end - end - - def fetch_security_prices(symbol:, exchange_operating_mic: nil, start_date:, end_date:) - with_provider_response do - params = { - start_date: start_date, - end_date: end_date, - operating_mic_code: exchange_operating_mic - }.compact - - data = paginate( - "#{base_url}/tickers/#{symbol}/open-close", - params - ) do |body| - body.dig("prices") - end - - currency = data.first_page.dig("currency") - exchange_operating_mic = data.first_page.dig("exchange", "operating_mic_code") - - data.paginated.map do |price| - date = price.dig("date") - price = price.dig("close") || price.dig("open") - - if date.nil? || price.nil? - Rails.logger.warn("#{self.class.name} returned invalid price data for security #{symbol} on: #{date}. Price data: #{price.inspect}") - Sentry.capture_exception(InvalidSecurityPriceError.new("#{self.class.name} returned invalid security price data"), level: :warning) do |scope| - scope.set_context("security", { symbol: symbol, date: date }) - end - - next - end - - Price.new( - symbol: symbol, - date: date.to_date, - price: price, - currency: currency, - exchange_operating_mic: exchange_operating_mic - ) - end.compact - end - end - - private - attr_reader :api_key - - def base_url - ENV["SYNTH_URL"] || "https://api.synthfinance.com" - end - - def app_name - "maybe_app" - end - - def app_type - Rails.application.config.app_mode - end - - def client - @client ||= Faraday.new(url: base_url) do |faraday| - faraday.request(:retry, { - max: 2, - interval: 0.05, - interval_randomness: 0.5, - backoff_factor: 2 - }) - - faraday.response :raise_error - faraday.headers["Authorization"] = "Bearer #{api_key}" - faraday.headers["X-Source"] = app_name - faraday.headers["X-Source-Type"] = app_type - end - end - - def fetch_page(url, page, params = {}) - client.get(url, params.merge(page: page)) - end - - def paginate(url, params = {}) - results = [] - page = 1 - current_page = 0 - total_pages = 1 - first_page = nil - - while current_page < total_pages - response = fetch_page(url, page, params) - - body = JSON.parse(response.body) - first_page = body unless first_page - page_results = yield(body) - results.concat(page_results) - - current_page = body.dig("paging", "current_page") - total_pages = body.dig("paging", "total_pages") - - page += 1 - end - - PaginatedData.new( - paginated: results, - first_page: first_page, - total_pages: total_pages - ) - end -end diff --git a/app/models/security.rb b/app/models/security.rb index b6e852956..ca5b38c4b 100644 --- a/app/models/security.rb +++ b/app/models/security.rb @@ -18,7 +18,7 @@ class Security < ApplicationRecord end def to_combobox_option - SynthComboboxOption.new( + ComboboxOption.new( symbol: ticker, name: name, logo_url: logo_url, diff --git a/app/models/security/combobox_option.rb b/app/models/security/combobox_option.rb new file mode 100644 index 000000000..822fc635f --- /dev/null +++ b/app/models/security/combobox_option.rb @@ -0,0 +1,13 @@ +class Security::ComboboxOption + include ActiveModel::Model + + attr_accessor :symbol, :name, :logo_url, :exchange_operating_mic, :country_code + + def id + "#{symbol}|#{exchange_operating_mic}" + end + + def to_combobox_display + "#{symbol} - #{name} (#{exchange_operating_mic})" + end +end diff --git a/app/models/security/synth_combobox_option.rb b/app/models/security/synth_combobox_option.rb deleted file mode 100644 index 15e769204..000000000 --- a/app/models/security/synth_combobox_option.rb +++ /dev/null @@ -1,13 +0,0 @@ -class Security::SynthComboboxOption - include ActiveModel::Model - - attr_accessor :symbol, :name, :logo_url, :exchange_operating_mic, :country_code - - def id - "#{symbol}|#{exchange_operating_mic}" # submitted by combobox as value - end - - def to_combobox_display - "#{symbol} - #{name} (#{exchange_operating_mic})" # shown in combobox input when selected - end -end diff --git a/app/models/setting.rb b/app/models/setting.rb index 522ddb7c8..fa3dba1b4 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -2,7 +2,6 @@ class Setting < RailsSettings::Base cache_prefix { "v1" } - field :synth_api_key, type: :string, default: ENV["SYNTH_API_KEY"] field :twelve_data_api_key, type: :string, default: ENV["TWELVE_DATA_API_KEY"] field :openai_access_token, type: :string, default: ENV["OPENAI_ACCESS_TOKEN"] diff --git a/app/models/trade/create_form.rb b/app/models/trade/create_form.rb index ed26d9b65..b07cc87d8 100644 --- a/app/models/trade/create_form.rb +++ b/app/models/trade/create_form.rb @@ -18,7 +18,7 @@ class Trade::CreateForm end private - # Users can either look up a ticker from our provider (Synth) or enter a manual, "offline" ticker (that we won't fetch prices for) + # Users can either look up a ticker from a provider or enter a manual, "offline" ticker (that we won't fetch prices for) def security ticker_symbol, exchange_operating_mic = ticker.present? ? ticker.split("|") : [ manual_ticker, nil ] diff --git a/app/views/accounts/_logo.html.erb b/app/views/accounts/_logo.html.erb index 1da8e0bcf..40d9d4d0a 100644 --- a/app/views/accounts/_logo.html.erb +++ b/app/views/accounts/_logo.html.erb @@ -7,9 +7,7 @@ "full" => "w-full h-full" } %> -<% if account.plaid_account_id? && account.institution_domain.present? %> - <%= image_tag "https://logo.synthfinance.com/#{account.institution_domain}", class: "shrink-0 rounded-full #{size_classes[size]}" %> -<% elsif account.logo.attached? %> +<% if account.logo.attached? %> <%= image_tag account.logo, class: "shrink-0 rounded-full #{size_classes[size]}" %> <% else %> <%= render DS::FilledIcon.new(variant: :text, hex_color: color || account.accountable.color, text: account.name, size: size, rounded: true) %> diff --git a/app/views/holdings/_holding.html.erb b/app/views/holdings/_holding.html.erb index 5fe0e4c94..3b58fe284 100644 --- a/app/views/holdings/_holding.html.erb +++ b/app/views/holdings/_holding.html.erb @@ -3,7 +3,9 @@ <%= turbo_frame_tag dom_id(holding) do %>
- <%= image_tag "https://logo.synthfinance.com/ticker/#{holding.ticker}", class: "w-9 h-9 rounded-full", loading: "lazy" %> + <% if holding.security.logo_url.present? %> + <%= image_tag holding.security.logo_url, class: "w-9 h-9 rounded-full", loading: "lazy" %> + <% end %>
<%= link_to holding.name, holding_path(holding), data: { turbo_frame: :drawer }, class: "hover:underline" %> diff --git a/app/views/holdings/show.html.erb b/app/views/holdings/show.html.erb index d53e5c52b..1a612643d 100644 --- a/app/views/holdings/show.html.erb +++ b/app/views/holdings/show.html.erb @@ -6,7 +6,9 @@ <%= tag.p @holding.ticker, class: "text-sm text-secondary" %>
- <%= image_tag "https://logo.synthfinance.com/ticker/#{@holding.ticker}", loading: "lazy", class: "w-9 h-9 rounded-full" %> + <% if @holding.security.logo_url.present? %> + <%= image_tag @holding.security.logo_url, loading: "lazy", class: "w-9 h-9 rounded-full" %> + <% end %>
<% end %> diff --git a/app/views/settings/hostings/_synth_settings.html.erb b/app/views/settings/hostings/_synth_settings.html.erb deleted file mode 100644 index d8f718396..000000000 --- a/app/views/settings/hostings/_synth_settings.html.erb +++ /dev/null @@ -1,49 +0,0 @@ -
-
-

<%= t(".title") %>

- <% if ENV["SYNTH_API_KEY"].present? %> -

You have successfully configured your Synth API key through the SYNTH_API_KEY environment variable.

- <% else %> -

<%= t(".description") %>

- <% end %> -
- - <%= styled_form_with model: Setting.new, - url: settings_hosting_path, - method: :patch, - data: { - controller: "auto-submit-form", - "auto-submit-form-trigger-event-value": "blur" - } do |form| %> - <%= form.text_field :synth_api_key, - label: t(".label"), - type: "password", - placeholder: t(".placeholder"), - value: ENV.fetch("SYNTH_API_KEY", Setting.synth_api_key), - disabled: ENV["SYNTH_API_KEY"].present?, - container_class: @synth_usage.present? && !@synth_usage.success? ? "border-red-500" : "", - data: { "auto-submit-form-target": "auto" } %> - <% end %> - - <% if @synth_usage.present? && @synth_usage.success? %> -
-
-

- <%= t(".api_calls_used", - used: number_with_delimiter(@synth_usage.data.used), - limit: number_with_delimiter(@synth_usage.data.limit), - percentage: number_to_percentage(@synth_usage.data.utilization, precision: 1)) %> -

-
-
-
-
-
-

- <%= t(".plan", plan: @synth_usage.data.plan) %> -

-
-
- <% end %> -
diff --git a/app/views/settings/hostings/show.html.erb b/app/views/settings/hostings/show.html.erb index 0b2a19164..adea00382 100644 --- a/app/views/settings/hostings/show.html.erb +++ b/app/views/settings/hostings/show.html.erb @@ -1,9 +1,6 @@ <%= content_for :page_title, t(".title") %> <%= settings_section title: t(".general") do %> -
- <%= render "settings/hostings/synth_settings" %> -
<%= render "settings/hostings/twelve_data_settings" %>
diff --git a/config/locales/views/settings/hostings/en.yml b/config/locales/views/settings/hostings/en.yml index c93647646..4289abe65 100644 --- a/config/locales/views/settings/hostings/en.yml +++ b/config/locales/views/settings/hostings/en.yml @@ -21,13 +21,6 @@ en: confirm_clear_cache: title: Clear data cache? body: Are you sure you want to clear the data cache? This will remove all exchange rates, security prices, account balances, and other data. This action cannot be undone. - synth_settings: - api_calls_used: "%{used} / %{limit} API calls used (%{percentage})" - description: Input the API key provided by Synth - label: API Key - placeholder: Enter your API key here - plan: "%{plan} plan" - title: Synth Settings twelve_data_settings: api_calls_used: "%{used} / %{limit} API daily calls used (%{percentage})" description: Input the API key provided by Twelve Data diff --git a/config/locales/views/settings/hostings/nb.yml b/config/locales/views/settings/hostings/nb.yml index 6088e055d..f58758206 100644 --- a/config/locales/views/settings/hostings/nb.yml +++ b/config/locales/views/settings/hostings/nb.yml @@ -20,13 +20,6 @@ nb: confirm_clear_cache: title: Tøm cache? body: Er du sikker på at du vil tømme cache? Dette vil fjerne alle valutakurser, verdipapirpriser, kontobalanser og andre data. Denne handlingen kan ikke angres. - synth_settings: - api_calls_used: "%{used} / %{limit} API-kall brukt (%{percentage})" - description: Angi API-nøkkelen som er gitt av Synth - label: API-nøkkel - placeholder: Angi API-nøkkelen din her - plan: "%{plan} plan" - title: Synth-innstillinger update: failure: Ugyldig innstillingsverdi success: Innstillinger oppdatert diff --git a/lib/tasks/securities.rake b/lib/tasks/securities.rake index 4254b8c64..808df1924 100644 --- a/lib/tasks/securities.rake +++ b/lib/tasks/securities.rake @@ -1,64 +1,6 @@ # frozen_string_literal: true namespace :securities do - desc "Backfill exchange_operating_mic for securities using Synth API" - task backfill_exchange_mic: :environment do - puts "Starting exchange_operating_mic backfill..." - - api_key = Rails.application.config.app_mode.self_hosted? ? Setting.synth_api_key : ENV["SYNTH_API_KEY"] - unless api_key.present? - puts "ERROR: No Synth API key found. Please set SYNTH_API_KEY env var or configure it in Settings for self-hosted mode." - exit 1 - end - - securities = Security.where(exchange_operating_mic: nil).where.not(ticker: nil) - total = securities.count - processed = 0 - errors = [] - - securities.find_each do |security| - processed += 1 - print "\rProcessing #{processed}/#{total} (#{(processed.to_f/total * 100).round(1)}%)" - - begin - response = Faraday.get("https://api.synthfinance.com/tickers/#{security.ticker}") do |req| - req.params["country_code"] = security.country_code if security.country_code.present? - req.headers["Authorization"] = "Bearer #{api_key}" - end - - if response.success? - data = JSON.parse(response.body).dig("data") - exchange_data = data["exchange"] - - # Update security with exchange info and other metadata - security.update!( - exchange_operating_mic: exchange_data["operating_mic_code"], - exchange_mic: exchange_data["mic_code"], - exchange_acronym: exchange_data["acronym"], - name: data["name"], - logo_url: data["logo_url"], - country_code: exchange_data["country_code"] - ) - else - errors << "#{security.ticker}: HTTP #{response.status} - #{response.body}" - end - rescue => e - errors << "#{security.ticker}: #{e.message}" - end - - # Add a small delay to not overwhelm the API - sleep(0.1) - end - - puts "\n\nBackfill complete!" - puts "Processed #{processed} securities" - - if errors.any? - puts "\nErrors encountered:" - errors.each { |error| puts " - #{error}" } - end - end - desc "De-duplicate securities based on ticker + exchange_operating_mic" task :deduplicate, [ :dry_run ] => :environment do |_t, args| dry_run = args[:dry_run].present? diff --git a/test/controllers/settings/hostings_controller_test.rb b/test/controllers/settings/hostings_controller_test.rb index ef672d3d7..cb18866f8 100644 --- a/test/controllers/settings/hostings_controller_test.rb +++ b/test/controllers/settings/hostings_controller_test.rb @@ -8,7 +8,6 @@ class Settings::HostingsControllerTest < ActionDispatch::IntegrationTest sign_in users(:family_admin) @provider = mock - Provider::Registry.stubs(:get_provider).with(:synth).returns(@provider) Provider::Registry.stubs(:get_provider).with(:twelve_data).returns(@provider) @usage_response = provider_success_response( OpenStruct.new( @@ -32,7 +31,6 @@ class Settings::HostingsControllerTest < ActionDispatch::IntegrationTest test "should get edit when self hosting is enabled" do @provider.expects(:usage).returns(@usage_response) - @provider.expects(:usage).returns(@usage_response) with_self_hosting do get settings_hosting_url @@ -42,9 +40,9 @@ class Settings::HostingsControllerTest < ActionDispatch::IntegrationTest test "can update settings when self hosting is enabled" do with_self_hosting do - patch settings_hosting_url, params: { setting: { synth_api_key: "1234567890" } } + patch settings_hosting_url, params: { setting: { twelve_data_api_key: "1234567890" } } - assert_equal "1234567890", Setting.synth_api_key + assert_equal "1234567890", Setting.twelve_data_api_key end end diff --git a/test/interfaces/security_provider_interface_test.rb b/test/interfaces/security_provider_interface_test.rb index a994bb73b..2d133683d 100644 --- a/test/interfaces/security_provider_interface_test.rb +++ b/test/interfaces/security_provider_interface_test.rb @@ -27,7 +27,7 @@ module SecurityProviderInterfaceTest assert response.success? assert response.data.first.date.is_a?(Date) - assert_equal 147, response.data.count # Synth won't return prices on weekends / holidays, so less than total day count of 213 + assert_equal 147, response.data.count end end diff --git a/test/models/family/auto_merchant_detector_test.rb b/test/models/family/auto_merchant_detector_test.rb index 69c8e3cd5..21f9f4e15 100644 --- a/test/models/family/auto_merchant_detector_test.rb +++ b/test/models/family/auto_merchant_detector_test.rb @@ -29,8 +29,8 @@ class Family::AutoMerchantDetectorTest < ActiveSupport::TestCase assert_equal "McDonalds", txn1.reload.merchant.name assert_equal "Chipotle", txn2.reload.merchant.name - assert_equal "https://logo.synthfinance.com/mcdonalds.com", txn1.reload.merchant.logo_url - assert_equal "https://logo.synthfinance.com/chipotle.com", txn2.reload.merchant.logo_url + assert_nil txn1.reload.merchant.logo_url + assert_nil txn2.reload.merchant.logo_url assert_nil txn3.reload.merchant # After auto-detection, all transactions are locked and no longer enrichable diff --git a/test/models/provider/registry_test.rb b/test/models/provider/registry_test.rb deleted file mode 100644 index 76c20cd70..000000000 --- a/test/models/provider/registry_test.rb +++ /dev/null @@ -1,27 +0,0 @@ -require "test_helper" - -class Provider::RegistryTest < ActiveSupport::TestCase - test "synth configured with ENV" do - Setting.stubs(:synth_api_key).returns(nil) - - with_env_overrides SYNTH_API_KEY: "123" do - assert_instance_of Provider::Synth, Provider::Registry.get_provider(:synth) - end - end - - test "synth configured with Setting" do - Setting.stubs(:synth_api_key).returns("123") - - with_env_overrides SYNTH_API_KEY: nil do - assert_instance_of Provider::Synth, Provider::Registry.get_provider(:synth) - end - end - - test "synth not configured" do - Setting.stubs(:synth_api_key).returns(nil) - - with_env_overrides SYNTH_API_KEY: nil do - assert_nil Provider::Registry.get_provider(:synth) - end - end -end diff --git a/test/models/provider/synth_test.rb b/test/models/provider/synth_test.rb deleted file mode 100644 index 5dfa3bed5..000000000 --- a/test/models/provider/synth_test.rb +++ /dev/null @@ -1,26 +0,0 @@ -require "test_helper" -require "ostruct" - -class Provider::SynthTest < ActiveSupport::TestCase - include ExchangeRateProviderInterfaceTest, SecurityProviderInterfaceTest - - setup do - @subject = @synth = Provider::Synth.new(ENV["SYNTH_API_KEY"]) - end - - test "health check" do - VCR.use_cassette("synth/health") do - assert @synth.healthy? - end - end - - test "usage info" do - VCR.use_cassette("synth/usage") do - usage = @synth.usage.data - assert usage.used.present? - assert usage.limit.present? - assert usage.utilization.present? - assert usage.plan.present? - end - end -end diff --git a/test/system/settings_test.rb b/test/system/settings_test.rb index 028aad18d..7da571784 100644 --- a/test/system/settings_test.rb +++ b/test/system/settings_test.rb @@ -33,7 +33,6 @@ class SettingsTest < ApplicationSystemTestCase test "can update self hosting settings" do Rails.application.config.app_mode.stubs(:self_hosted?).returns(true) - Provider::Registry.stubs(:get_provider).with(:synth).returns(nil) Provider::Registry.stubs(:get_provider).with(:twelve_data).returns(nil) open_settings_from_sidebar assert_selector "li", text: "Self hosting" diff --git a/test/test_helper.rb b/test/test_helper.rb index 077eae5bc..a5edb0cde 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -28,7 +28,6 @@ VCR.configure do |config| config.hook_into :webmock config.ignore_localhost = true config.default_cassette_options = { erb: true } - config.filter_sensitive_data("") { ENV["SYNTH_API_KEY"] } config.filter_sensitive_data("") { ENV["OPENAI_ACCESS_TOKEN"] } config.filter_sensitive_data("") { ENV["OPENAI_ORGANIZATION_ID"] } config.filter_sensitive_data("") { ENV["STRIPE_SECRET_KEY"] } diff --git a/test/vcr_cassettes/synth/exchange_rate.yml b/test/vcr_cassettes/synth/exchange_rate.yml deleted file mode 100644 index adc22263d..000000000 --- a/test/vcr_cassettes/synth/exchange_rate.yml +++ /dev/null @@ -1,81 +0,0 @@ ---- -http_interactions: -- request: - method: get - uri: https://api.synthfinance.com/rates/historical?date=2024-01-01&from=USD&to=GBP - body: - encoding: US-ASCII - string: '' - headers: - Authorization: - - Bearer - X-Source: - - maybe_app - X-Source-Type: - - managed - User-Agent: - - Faraday v2.13.1 - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - response: - status: - code: 200 - message: OK - headers: - Date: - - Fri, 16 May 2025 13:01:38 GMT - Content-Type: - - application/json; charset=utf-8 - Transfer-Encoding: - - chunked - Connection: - - keep-alive - Cache-Control: - - max-age=0, private, must-revalidate - Etag: - - W/"0c93a67d0c68e6f206e2954a41aa2933" - Referrer-Policy: - - strict-origin-when-cross-origin - Rndr-Id: - - 146e30b2-e03b-47e3 - Strict-Transport-Security: - - max-age=63072000; includeSubDomains - Vary: - - Accept-Encoding - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - SAMEORIGIN - X-Permitted-Cross-Domain-Policies: - - none - X-Render-Origin-Server: - - Render - X-Request-Id: - - 3cf7ade1-8066-422a-97c7-5f8b99e24296 - X-Runtime: - - '0.024284' - X-Xss-Protection: - - '0' - Cf-Cache-Status: - - DYNAMIC - Report-To: - - '{"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v4?s=ih8sEFqAOWyINqAEtKGKPKO2lr1qAYSVeipyB5F8g2umPODXvCD4hN3G6wTTs2Q7H8CDWsqiOlYkmVvmr%2BWvl2ojOtBwO25Ahk9TbhlcgRO9nT6mEIXOSdVXJpzpRn5Ov%2FMGigpQ"}],"group":"cf-nel","max_age":604800}' - Nel: - - '{"success_fraction":0,"report_to":"cf-nel","max_age":604800}' - Speculation-Rules: - - '"/cdn-cgi/speculation"' - Server: - - cloudflare - Cf-Ray: - - 940b109b5df1a3d7-ORD - Alt-Svc: - - h3=":443"; ma=86400 - Server-Timing: - - cfL4;desc="?proto=TCP&rtt=25865&min_rtt=25683&rtt_var=9996&sent=4&recv=6&lost=0&retrans=0&sent_bytes=2827&recv_bytes=922&delivery_rate=106690&cwnd=219&unsent_bytes=0&cid=e48ae188d1f86721&ts=190&x=0" - body: - encoding: ASCII-8BIT - string: '{"data":{"date":"2024-01-01","source":"USD","rates":{"GBP":0.785476}},"meta":{"total_records":1,"credits_used":1,"credits_remaining":249734,"date":"2024-01-01"}}' - recorded_at: Fri, 16 May 2025 13:01:38 GMT -recorded_with: VCR 6.3.1 diff --git a/test/vcr_cassettes/synth/exchange_rates.yml b/test/vcr_cassettes/synth/exchange_rates.yml deleted file mode 100644 index 87071b8ff..000000000 --- a/test/vcr_cassettes/synth/exchange_rates.yml +++ /dev/null @@ -1,81 +0,0 @@ ---- -http_interactions: -- request: - method: get - uri: https://api.synthfinance.com/rates/historical-range?date_end=2024-07-31&date_start=2024-01-01&from=USD&page=1&to=GBP - body: - encoding: US-ASCII - string: '' - headers: - Authorization: - - Bearer - X-Source: - - maybe_app - X-Source-Type: - - managed - User-Agent: - - Faraday v2.13.1 - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - response: - status: - code: 200 - message: OK - headers: - Date: - - Fri, 16 May 2025 13:01:35 GMT - Content-Type: - - application/json; charset=utf-8 - Transfer-Encoding: - - chunked - Connection: - - keep-alive - Cache-Control: - - max-age=0, private, must-revalidate - Etag: - - W/"ad21b1fba71fe0b149fe37b483a60438" - Referrer-Policy: - - strict-origin-when-cross-origin - Rndr-Id: - - 28bc6622-47b8-4aeb - Strict-Transport-Security: - - max-age=63072000; includeSubDomains - Vary: - - Accept-Encoding - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - SAMEORIGIN - X-Permitted-Cross-Domain-Policies: - - none - X-Render-Origin-Server: - - Render - X-Request-Id: - - fcf251a3-f850-4464-9592-ced9de5e0c86 - X-Runtime: - - '0.080857' - X-Xss-Protection: - - '0' - Cf-Cache-Status: - - DYNAMIC - Report-To: - - '{"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v4?s=622lysAXubNaj3TsuhR9RYZRXPc%2BgnyMWj52fxy%2BptvXoPr%2FxVJgJZ0g02mOUjCywdAymkMpawfWCaZVQOIaPVpocco3g4Y%2B0FB667ilf3UtCyiHwqCosUq0T99JabIsgFFJ%2FhP4"}],"group":"cf-nel","max_age":604800}' - Nel: - - '{"success_fraction":0,"report_to":"cf-nel","max_age":604800}' - Speculation-Rules: - - '"/cdn-cgi/speculation"' - Server: - - cloudflare - Cf-Ray: - - 940b108a2921607d-ORD - Alt-Svc: - - h3=":443"; ma=86400 - Server-Timing: - - cfL4;desc="?proto=TCP&rtt=25729&min_rtt=25575&rtt_var=9899&sent=4&recv=6&lost=0&retrans=0&sent_bytes=2825&recv_bytes=961&delivery_rate=108019&cwnd=251&unsent_bytes=0&cid=ca574e4a637aba29&ts=241&x=0" - body: - encoding: ASCII-8BIT - string: '{"data":[{"date":"2024-01-01","source":"USD","rates":{"GBP":0.785476}},{"date":"2024-01-02","source":"USD","rates":{"GBP":0.785644}},{"date":"2024-01-03","source":"USD","rates":{"GBP":0.792232}},{"date":"2024-01-04","source":"USD","rates":{"GBP":0.789053}},{"date":"2024-01-05","source":"USD","rates":{"GBP":0.788487}},{"date":"2024-01-06","source":"USD","rates":{"GBP":0.785787}},{"date":"2024-01-07","source":"USD","rates":{"GBP":0.785994}},{"date":"2024-01-08","source":"USD","rates":{"GBP":0.786378}},{"date":"2024-01-09","source":"USD","rates":{"GBP":0.784775}},{"date":"2024-01-10","source":"USD","rates":{"GBP":0.786769}},{"date":"2024-01-11","source":"USD","rates":{"GBP":0.784633}},{"date":"2024-01-12","source":"USD","rates":{"GBP":0.782576}},{"date":"2024-01-13","source":"USD","rates":{"GBP":0.78447}},{"date":"2024-01-14","source":"USD","rates":{"GBP":0.784423}},{"date":"2024-01-15","source":"USD","rates":{"GBP":0.785204}},{"date":"2024-01-16","source":"USD","rates":{"GBP":0.786438}},{"date":"2024-01-17","source":"USD","rates":{"GBP":0.791264}},{"date":"2024-01-18","source":"USD","rates":{"GBP":0.788852}},{"date":"2024-01-19","source":"USD","rates":{"GBP":0.786744}},{"date":"2024-01-20","source":"USD","rates":{"GBP":0.787186}},{"date":"2024-01-21","source":"USD","rates":{"GBP":0.787166}},{"date":"2024-01-22","source":"USD","rates":{"GBP":0.787487}},{"date":"2024-01-23","source":"USD","rates":{"GBP":0.786985}},{"date":"2024-01-24","source":"USD","rates":{"GBP":0.787961}},{"date":"2024-01-25","source":"USD","rates":{"GBP":0.786236}},{"date":"2024-01-26","source":"USD","rates":{"GBP":0.786961}},{"date":"2024-01-27","source":"USD","rates":{"GBP":0.786935}},{"date":"2024-01-28","source":"USD","rates":{"GBP":0.787014}},{"date":"2024-01-29","source":"USD","rates":{"GBP":0.78761}},{"date":"2024-01-30","source":"USD","rates":{"GBP":0.786652}},{"date":"2024-01-31","source":"USD","rates":{"GBP":0.787736}},{"date":"2024-02-01","source":"USD","rates":{"GBP":0.788759}},{"date":"2024-02-02","source":"USD","rates":{"GBP":0.784546}},{"date":"2024-02-03","source":"USD","rates":{"GBP":0.791634}},{"date":"2024-02-04","source":"USD","rates":{"GBP":0.791637}},{"date":"2024-02-05","source":"USD","rates":{"GBP":0.792205}},{"date":"2024-02-06","source":"USD","rates":{"GBP":0.797836}},{"date":"2024-02-07","source":"USD","rates":{"GBP":0.79341}},{"date":"2024-02-08","source":"USD","rates":{"GBP":0.791971}},{"date":"2024-02-09","source":"USD","rates":{"GBP":0.792371}},{"date":"2024-02-10","source":"USD","rates":{"GBP":0.791997}},{"date":"2024-02-11","source":"USD","rates":{"GBP":0.792019}},{"date":"2024-02-12","source":"USD","rates":{"GBP":0.791339}},{"date":"2024-02-13","source":"USD","rates":{"GBP":0.791977}},{"date":"2024-02-14","source":"USD","rates":{"GBP":0.794262}},{"date":"2024-02-15","source":"USD","rates":{"GBP":0.795709}},{"date":"2024-02-16","source":"USD","rates":{"GBP":0.793714}},{"date":"2024-02-17","source":"USD","rates":{"GBP":0.793499}},{"date":"2024-02-18","source":"USD","rates":{"GBP":0.79367}},{"date":"2024-02-19","source":"USD","rates":{"GBP":0.792968}},{"date":"2024-02-20","source":"USD","rates":{"GBP":0.794437}},{"date":"2024-02-21","source":"USD","rates":{"GBP":0.791988}},{"date":"2024-02-22","source":"USD","rates":{"GBP":0.791262}},{"date":"2024-02-23","source":"USD","rates":{"GBP":0.789749}},{"date":"2024-02-24","source":"USD","rates":{"GBP":0.78886}},{"date":"2024-02-25","source":"USD","rates":{"GBP":0.789107}},{"date":"2024-02-26","source":"USD","rates":{"GBP":0.78917}},{"date":"2024-02-27","source":"USD","rates":{"GBP":0.788381}},{"date":"2024-02-28","source":"USD","rates":{"GBP":0.78861}},{"date":"2024-02-29","source":"USD","rates":{"GBP":0.789837}},{"date":"2024-03-01","source":"USD","rates":{"GBP":0.792028}},{"date":"2024-03-02","source":"USD","rates":{"GBP":0.790312}},{"date":"2024-03-03","source":"USD","rates":{"GBP":0.790258}},{"date":"2024-03-04","source":"USD","rates":{"GBP":0.789891}},{"date":"2024-03-05","source":"USD","rates":{"GBP":0.788025}},{"date":"2024-03-06","source":"USD","rates":{"GBP":0.787136}},{"date":"2024-03-07","source":"USD","rates":{"GBP":0.785219}},{"date":"2024-03-08","source":"USD","rates":{"GBP":0.780438}},{"date":"2024-03-09","source":"USD","rates":{"GBP":0.777772}},{"date":"2024-03-10","source":"USD","rates":{"GBP":0.777884}},{"date":"2024-03-11","source":"USD","rates":{"GBP":0.77786}},{"date":"2024-03-12","source":"USD","rates":{"GBP":0.780067}},{"date":"2024-03-13","source":"USD","rates":{"GBP":0.781535}},{"date":"2024-03-14","source":"USD","rates":{"GBP":0.781184}},{"date":"2024-03-15","source":"USD","rates":{"GBP":0.784604}},{"date":"2024-03-16","source":"USD","rates":{"GBP":0.785537}},{"date":"2024-03-17","source":"USD","rates":{"GBP":0.785147}},{"date":"2024-03-18","source":"USD","rates":{"GBP":0.785457}},{"date":"2024-03-19","source":"USD","rates":{"GBP":0.785746}},{"date":"2024-03-20","source":"USD","rates":{"GBP":0.786238}},{"date":"2024-03-21","source":"USD","rates":{"GBP":0.781351}},{"date":"2024-03-22","source":"USD","rates":{"GBP":0.789841}},{"date":"2024-03-23","source":"USD","rates":{"GBP":0.793659}},{"date":"2024-03-24","source":"USD","rates":{"GBP":0.793385}},{"date":"2024-03-25","source":"USD","rates":{"GBP":0.793673}},{"date":"2024-03-26","source":"USD","rates":{"GBP":0.791344}},{"date":"2024-03-27","source":"USD","rates":{"GBP":0.791899}},{"date":"2024-03-28","source":"USD","rates":{"GBP":0.792585}},{"date":"2024-03-29","source":"USD","rates":{"GBP":0.792205}},{"date":"2024-03-30","source":"USD","rates":{"GBP":0.792228}},{"date":"2024-03-31","source":"USD","rates":{"GBP":0.792057}},{"date":"2024-04-01","source":"USD","rates":{"GBP":0.79134}},{"date":"2024-04-02","source":"USD","rates":{"GBP":0.797058}},{"date":"2024-04-03","source":"USD","rates":{"GBP":0.795147}},{"date":"2024-04-04","source":"USD","rates":{"GBP":0.790398}},{"date":"2024-04-05","source":"USD","rates":{"GBP":0.791151}},{"date":"2024-04-06","source":"USD","rates":{"GBP":0.791314}},{"date":"2024-04-07","source":"USD","rates":{"GBP":0.791273}},{"date":"2024-04-08","source":"USD","rates":{"GBP":0.792111}},{"date":"2024-04-09","source":"USD","rates":{"GBP":0.790047}},{"date":"2024-04-10","source":"USD","rates":{"GBP":0.788828}},{"date":"2024-04-11","source":"USD","rates":{"GBP":0.797646}},{"date":"2024-04-12","source":"USD","rates":{"GBP":0.796524}},{"date":"2024-04-13","source":"USD","rates":{"GBP":0.803024}},{"date":"2024-04-14","source":"USD","rates":{"GBP":0.802912}},{"date":"2024-04-15","source":"USD","rates":{"GBP":0.8025}},{"date":"2024-04-16","source":"USD","rates":{"GBP":0.80344}},{"date":"2024-04-17","source":"USD","rates":{"GBP":0.804505}},{"date":"2024-04-18","source":"USD","rates":{"GBP":0.80301}},{"date":"2024-04-19","source":"USD","rates":{"GBP":0.804145}},{"date":"2024-04-20","source":"USD","rates":{"GBP":0.80845}},{"date":"2024-04-21","source":"USD","rates":{"GBP":0.808199}},{"date":"2024-04-22","source":"USD","rates":{"GBP":0.808004}},{"date":"2024-04-23","source":"USD","rates":{"GBP":0.809734}},{"date":"2024-04-24","source":"USD","rates":{"GBP":0.802955}},{"date":"2024-04-25","source":"USD","rates":{"GBP":0.80264}},{"date":"2024-04-26","source":"USD","rates":{"GBP":0.799526}},{"date":"2024-04-27","source":"USD","rates":{"GBP":0.80053}},{"date":"2024-04-28","source":"USD","rates":{"GBP":0.800761}},{"date":"2024-04-29","source":"USD","rates":{"GBP":0.799397}},{"date":"2024-04-30","source":"USD","rates":{"GBP":0.796217}},{"date":"2024-05-01","source":"USD","rates":{"GBP":0.800703}},{"date":"2024-05-02","source":"USD","rates":{"GBP":0.797562}},{"date":"2024-05-03","source":"USD","rates":{"GBP":0.797457}},{"date":"2024-05-04","source":"USD","rates":{"GBP":0.797001}},{"date":"2024-05-05","source":"USD","rates":{"GBP":0.797107}},{"date":"2024-05-06","source":"USD","rates":{"GBP":0.797363}},{"date":"2024-05-07","source":"USD","rates":{"GBP":0.796218}},{"date":"2024-05-08","source":"USD","rates":{"GBP":0.799915}},{"date":"2024-05-09","source":"USD","rates":{"GBP":0.800422}},{"date":"2024-05-10","source":"USD","rates":{"GBP":0.798411}},{"date":"2024-05-11","source":"USD","rates":{"GBP":0.798489}},{"date":"2024-05-12","source":"USD","rates":{"GBP":0.798475}},{"date":"2024-05-13","source":"USD","rates":{"GBP":0.79853}},{"date":"2024-05-14","source":"USD","rates":{"GBP":0.796122}},{"date":"2024-05-15","source":"USD","rates":{"GBP":0.794614}},{"date":"2024-05-16","source":"USD","rates":{"GBP":0.78804}},{"date":"2024-05-17","source":"USD","rates":{"GBP":0.789188}},{"date":"2024-05-18","source":"USD","rates":{"GBP":0.787162}},{"date":"2024-05-19","source":"USD","rates":{"GBP":0.787194}},{"date":"2024-05-20","source":"USD","rates":{"GBP":0.787022}},{"date":"2024-05-21","source":"USD","rates":{"GBP":0.786793}},{"date":"2024-05-22","source":"USD","rates":{"GBP":0.786723}},{"date":"2024-05-23","source":"USD","rates":{"GBP":0.786132}},{"date":"2024-05-24","source":"USD","rates":{"GBP":0.78778}},{"date":"2024-05-25","source":"USD","rates":{"GBP":0.785013}},{"date":"2024-05-26","source":"USD","rates":{"GBP":0.785081}},{"date":"2024-05-27","source":"USD","rates":{"GBP":0.78526}},{"date":"2024-05-28","source":"USD","rates":{"GBP":0.78296}},{"date":"2024-05-29","source":"USD","rates":{"GBP":0.783808}},{"date":"2024-05-30","source":"USD","rates":{"GBP":0.787552}},{"date":"2024-05-31","source":"USD","rates":{"GBP":0.785599}},{"date":"2024-06-01","source":"USD","rates":{"GBP":0.785113}},{"date":"2024-06-02","source":"USD","rates":{"GBP":0.785019}},{"date":"2024-06-03","source":"USD","rates":{"GBP":0.784657}},{"date":"2024-06-04","source":"USD","rates":{"GBP":0.780649}},{"date":"2024-06-05","source":"USD","rates":{"GBP":0.782934}},{"date":"2024-06-06","source":"USD","rates":{"GBP":0.781631}},{"date":"2024-06-07","source":"USD","rates":{"GBP":0.781732}},{"date":"2024-06-08","source":"USD","rates":{"GBP":0.785947}},{"date":"2024-06-09","source":"USD","rates":{"GBP":0.785767}},{"date":"2024-06-10","source":"USD","rates":{"GBP":0.785588}},{"date":"2024-06-11","source":"USD","rates":{"GBP":0.785791}},{"date":"2024-06-12","source":"USD","rates":{"GBP":0.784932}},{"date":"2024-06-13","source":"USD","rates":{"GBP":0.781472}},{"date":"2024-06-14","source":"USD","rates":{"GBP":0.784041}},{"date":"2024-06-15","source":"USD","rates":{"GBP":0.789096}},{"date":"2024-06-16","source":"USD","rates":{"GBP":0.788449}},{"date":"2024-06-17","source":"USD","rates":{"GBP":0.788479}},{"date":"2024-06-18","source":"USD","rates":{"GBP":0.786542}},{"date":"2024-06-19","source":"USD","rates":{"GBP":0.786916}},{"date":"2024-06-20","source":"USD","rates":{"GBP":0.786107}},{"date":"2024-06-21","source":"USD","rates":{"GBP":0.789875}},{"date":"2024-06-22","source":"USD","rates":{"GBP":0.79058}},{"date":"2024-06-23","source":"USD","rates":{"GBP":0.790546}},{"date":"2024-06-24","source":"USD","rates":{"GBP":0.791248}},{"date":"2024-06-25","source":"USD","rates":{"GBP":0.788496}},{"date":"2024-06-26","source":"USD","rates":{"GBP":0.788395}},{"date":"2024-06-27","source":"USD","rates":{"GBP":0.792298}},{"date":"2024-06-28","source":"USD","rates":{"GBP":0.79087}},{"date":"2024-06-29","source":"USD","rates":{"GBP":0.790726}},{"date":"2024-06-30","source":"USD","rates":{"GBP":0.790719}},{"date":"2024-07-01","source":"USD","rates":{"GBP":0.790622}},{"date":"2024-07-02","source":"USD","rates":{"GBP":0.790812}},{"date":"2024-07-03","source":"USD","rates":{"GBP":0.78816}},{"date":"2024-07-04","source":"USD","rates":{"GBP":0.784451}},{"date":"2024-07-05","source":"USD","rates":{"GBP":0.783992}},{"date":"2024-07-06","source":"USD","rates":{"GBP":0.780243}},{"date":"2024-07-07","source":"USD","rates":{"GBP":0.780594}},{"date":"2024-07-08","source":"USD","rates":{"GBP":0.780827}},{"date":"2024-07-09","source":"USD","rates":{"GBP":0.780333}},{"date":"2024-07-10","source":"USD","rates":{"GBP":0.781936}},{"date":"2024-07-11","source":"USD","rates":{"GBP":0.777992}},{"date":"2024-07-12","source":"USD","rates":{"GBP":0.773816}},{"date":"2024-07-13","source":"USD","rates":{"GBP":0.770374}},{"date":"2024-07-14","source":"USD","rates":{"GBP":0.770294}},{"date":"2024-07-15","source":"USD","rates":{"GBP":0.771174}},{"date":"2024-07-16","source":"USD","rates":{"GBP":0.771041}},{"date":"2024-07-17","source":"USD","rates":{"GBP":0.770574}},{"date":"2024-07-18","source":"USD","rates":{"GBP":0.768775}},{"date":"2024-07-19","source":"USD","rates":{"GBP":0.772195}},{"date":"2024-07-20","source":"USD","rates":{"GBP":0.774311}},{"date":"2024-07-21","source":"USD","rates":{"GBP":0.774096}},{"date":"2024-07-22","source":"USD","rates":{"GBP":0.773251}},{"date":"2024-07-23","source":"USD","rates":{"GBP":0.773304}},{"date":"2024-07-24","source":"USD","rates":{"GBP":0.775165}},{"date":"2024-07-25","source":"USD","rates":{"GBP":0.775289}},{"date":"2024-07-26","source":"USD","rates":{"GBP":0.777882}},{"date":"2024-07-27","source":"USD","rates":{"GBP":0.777203}},{"date":"2024-07-28","source":"USD","rates":{"GBP":0.776969}},{"date":"2024-07-29","source":"USD","rates":{"GBP":0.777176}},{"date":"2024-07-30","source":"USD","rates":{"GBP":0.777613}},{"date":"2024-07-31","source":"USD","rates":{"GBP":0.778999}}],"paging":{"prev":"/rates/historical-range?date_end=2024-07-31\u0026date_start=2024-01-01\u0026from=USD\u0026page=\u0026to=GBP","next":"/rates/historical-range?date_end=2024-07-31\u0026date_start=2024-01-01\u0026from=USD\u0026page=\u0026to=GBP","total_records":213,"current_page":1,"per_page":500,"total_pages":1},"meta":{"credits_used":1,"credits_remaining":249739,"date_start":"2024-01-01","date_end":"2024-07-31"}}' - recorded_at: Fri, 16 May 2025 13:01:35 GMT -recorded_with: VCR 6.3.1 diff --git a/test/vcr_cassettes/synth/health.yml b/test/vcr_cassettes/synth/health.yml deleted file mode 100644 index 24e3e67b7..000000000 --- a/test/vcr_cassettes/synth/health.yml +++ /dev/null @@ -1,82 +0,0 @@ ---- -http_interactions: -- request: - method: get - uri: https://api.synthfinance.com/user - body: - encoding: US-ASCII - string: '' - headers: - Authorization: - - Bearer - X-Source: - - maybe_app - X-Source-Type: - - managed - User-Agent: - - Faraday v2.13.1 - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - response: - status: - code: 200 - message: OK - headers: - Date: - - Fri, 16 May 2025 13:01:39 GMT - Content-Type: - - application/json; charset=utf-8 - Transfer-Encoding: - - chunked - Connection: - - keep-alive - Cache-Control: - - max-age=0, private, must-revalidate - Etag: - - W/"c5c1d51b68b499d00936c9eb1e8bfdbb" - Referrer-Policy: - - strict-origin-when-cross-origin - Rndr-Id: - - 3abc1256-5517-44a7 - Strict-Transport-Security: - - max-age=63072000; includeSubDomains - Vary: - - Accept-Encoding - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - SAMEORIGIN - X-Permitted-Cross-Domain-Policies: - - none - X-Render-Origin-Server: - - Render - X-Request-Id: - - aaf85301-dd16-4b9b-a3a4-c4fbcf1d3f55 - X-Runtime: - - '0.014386' - X-Xss-Protection: - - '0' - Cf-Cache-Status: - - DYNAMIC - Report-To: - - '{"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v4?s=OaVSdNPSl6CQ8gbhnDzkCisX2ILOEWAwweMW3rXXP5rBKuxZoDT024srQWmHKGLsCEhpt4G9mqCthDwlHu2%2BuZ3AyTJQcnBONtE%2FNQ7fKT9x8nLz4mnqL8iyynLuRWQSUJ8SWMj5"}],"group":"cf-nel","max_age":604800}' - Nel: - - '{"success_fraction":0,"report_to":"cf-nel","max_age":604800}' - Speculation-Rules: - - '"/cdn-cgi/speculation"' - Server: - - cloudflare - Cf-Ray: - - 940b109d086eb4b8-ORD - Alt-Svc: - - h3=":443"; ma=86400 - Server-Timing: - - cfL4;desc="?proto=TCP&rtt=32457&min_rtt=26792&rtt_var=14094&sent=5&recv=6&lost=0&retrans=0&sent_bytes=2826&recv_bytes=878&delivery_rate=108091&cwnd=229&unsent_bytes=0&cid=a6f330e4d5f16682&ts=309&x=0" - body: - encoding: ASCII-8BIT - string: '{"id":"user_3208c49393f54b3e974795e4bea5b864","email":"zach@maybe.co","name":"Zach - Gollwitzer","plan":"Business","api_calls_remaining":249733,"api_limit":250000,"credits_reset_at":"2025-06-01T00:00:00.000-04:00","current_period_start":"2025-05-01T00:00:00.000-04:00"}' - recorded_at: Fri, 16 May 2025 13:01:39 GMT -recorded_with: VCR 6.3.1 diff --git a/test/vcr_cassettes/synth/security_info.yml b/test/vcr_cassettes/synth/security_info.yml deleted file mode 100644 index 8dbb76d1c..000000000 --- a/test/vcr_cassettes/synth/security_info.yml +++ /dev/null @@ -1,105 +0,0 @@ ---- -http_interactions: -- request: - method: get - uri: https://api.synthfinance.com/tickers/AAPL?operating_mic=XNAS - body: - encoding: US-ASCII - string: '' - headers: - Authorization: - - Bearer - X-Source: - - maybe_app - X-Source-Type: - - managed - User-Agent: - - Faraday v2.13.1 - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - response: - status: - code: 200 - message: OK - headers: - Date: - - Fri, 16 May 2025 13:01:37 GMT - Content-Type: - - application/json; charset=utf-8 - Transfer-Encoding: - - chunked - Connection: - - keep-alive - Cache-Control: - - max-age=0, private, must-revalidate - Etag: - - W/"75f336ad88e262c72044e8b865265298" - Referrer-Policy: - - strict-origin-when-cross-origin - Rndr-Id: - - ba973abf-7d96-4a9a - Strict-Transport-Security: - - max-age=63072000; includeSubDomains - Vary: - - Accept-Encoding - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - SAMEORIGIN - X-Permitted-Cross-Domain-Policies: - - none - X-Render-Origin-Server: - - Render - X-Request-Id: - - 76cb13a6-0d7e-4c36-8df9-bb63110d9e2a - X-Runtime: - - '0.099716' - X-Xss-Protection: - - '0' - Cf-Cache-Status: - - DYNAMIC - Report-To: - - '{"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v4?s=aDn7ApAO9Ma86gZ%2BJKCUCFjH2Re%2BtXdB5gcqYj2KTGXJKNpgf5TNgzbrp5%2Bw%2FGL5nTvtp%2B7cxT8MMcLWjAV6Ne1r6z5YBFq1K4W7Zw5m1lhMiqYLnTnEs2Oq85TjzOvpsE%2BmC33d"}],"group":"cf-nel","max_age":604800}' - Nel: - - '{"success_fraction":0,"report_to":"cf-nel","max_age":604800}' - Speculation-Rules: - - '"/cdn-cgi/speculation"' - Server: - - cloudflare - Cf-Ray: - - 940b10910abdd2ec-ORD - Alt-Svc: - - h3=":443"; ma=86400 - Server-Timing: - - cfL4;desc="?proto=TCP&rtt=28163&min_rtt=27237&rtt_var=12066&sent=5&recv=6&lost=0&retrans=0&sent_bytes=2827&recv_bytes=905&delivery_rate=83590&cwnd=239&unsent_bytes=0&cid=7ef62bd693b52ccd&ts=240&x=0" - body: - encoding: ASCII-8BIT - string: '{"data":{"ticker":"AAPL","name":"Apple Inc.","links":{"homepage_url":"https://www.apple.com"},"logo_url":"https://logo.synthfinance.com/ticker/AAPL","description":"Apple - Inc. designs, manufactures, and markets smartphones, personal computers, tablets, - wearables, and accessories worldwide. The company offers iPhone, a line of - smartphones; Mac, a line of personal computers; iPad, a line of multi-purpose - tablets; and wearables, home, and accessories comprising AirPods, Apple TV, - Apple Watch, Beats products, and HomePod. It also provides AppleCare support - and cloud services; and operates various platforms, including the App Store - that allow customers to discover and download applications and digital content, - such as books, music, video, games, and podcasts. In addition, the company - offers various services, such as Apple Arcade, a game subscription service; - Apple Fitness+, a personalized fitness service; Apple Music, which offers - users a curated listening experience with on-demand radio stations; Apple - News+, a subscription news and magazine service; Apple TV+, which offers exclusive - original content; Apple Card, a co-branded credit card; and Apple Pay, a cashless - payment service, as well as licenses its intellectual property. The company - serves consumers, and small and mid-sized businesses; and the education, enterprise, - and government markets. It distributes third-party applications for its products - through the App Store. The company also sells its products through its retail - and online stores, and direct sales force; and third-party cellular network - carriers, wholesalers, retailers, and resellers. Apple Inc. was founded in - 1976 and is headquartered in Cupertino, California.","kind":"common stock","cik":"0000320193","currency":"USD","address":{"country":"USA","address_line1":"One - Apple Park Way","city":"Cupertino","state":"CA","postal_code":"95014"},"exchange":{"name":"Nasdaq/Ngs - (Global Select Market)","mic_code":"XNGS","operating_mic_code":"XNAS","acronym":"NGS","country":"United - States","country_code":"US","timezone":"America/New_York"},"ceo":"Mr. Timothy - D. Cook","founding_year":1976,"industry":"Consumer Electronics","sector":"Technology","phone":"408-996-1010","total_employees":161000,"composite_figi":"BBG000B9Y5X2","market_data":{"high_today":212.96,"low_today":209.54,"open_today":210.95,"close_today":211.45,"volume_today":44979900.0,"fifty_two_week_high":260.1,"fifty_two_week_low":169.21,"average_volume":61769396.875,"price_change":0.0,"percent_change":0.0}},"meta":{"credits_used":1,"credits_remaining":249737}}' - recorded_at: Fri, 16 May 2025 13:01:37 GMT -recorded_with: VCR 6.3.1 diff --git a/test/vcr_cassettes/synth/security_price.yml b/test/vcr_cassettes/synth/security_price.yml deleted file mode 100644 index 5cd435d42..000000000 --- a/test/vcr_cassettes/synth/security_price.yml +++ /dev/null @@ -1,83 +0,0 @@ ---- -http_interactions: -- request: - method: get - uri: https://api.synthfinance.com/tickers/AAPL/open-close?end_date=2024-08-01&operating_mic_code=XNAS&page=1&start_date=2024-08-01 - body: - encoding: US-ASCII - string: '' - headers: - Authorization: - - Bearer - X-Source: - - maybe_app - X-Source-Type: - - managed - User-Agent: - - Faraday v2.13.1 - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - response: - status: - code: 200 - message: OK - headers: - Date: - - Fri, 16 May 2025 13:01:36 GMT - Content-Type: - - application/json; charset=utf-8 - Transfer-Encoding: - - chunked - Connection: - - keep-alive - Cache-Control: - - max-age=0, private, must-revalidate - Etag: - - W/"72340d82266397447b865407dda15492" - Referrer-Policy: - - strict-origin-when-cross-origin - Rndr-Id: - - 4c3462aa-2471-40b4 - Strict-Transport-Security: - - max-age=63072000; includeSubDomains - Vary: - - Accept-Encoding - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - SAMEORIGIN - X-Permitted-Cross-Domain-Policies: - - none - X-Render-Origin-Server: - - Render - X-Request-Id: - - bdbc757d-2528-44c3-ae08-9788e8ee15f7 - X-Runtime: - - '0.034898' - X-Xss-Protection: - - '0' - Cf-Cache-Status: - - DYNAMIC - Report-To: - - '{"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v4?s=2Mu4PK4XTsAq%2Bn1%2F2yxy%2Blj7kz3ZCiQ9t8ikr2m19BrhQhrqfeUQfPwxbLc1WIgGMIxpPInKYtDVIX3En%2FGpTNQLAeu%2FpuLKv%2BRmCx%2B7u28od5L%2F9%2BLmEhFWqJjs8Y6C1O2a3SKv"}],"group":"cf-nel","max_age":604800}' - Nel: - - '{"success_fraction":0,"report_to":"cf-nel","max_age":604800}' - Speculation-Rules: - - '"/cdn-cgi/speculation"' - Server: - - cloudflare - Cf-Ray: - - 940b108f29129d03-ORD - Alt-Svc: - - h3=":443"; ma=86400 - Server-Timing: - - cfL4;desc="?proto=TCP&rtt=27793&min_rtt=26182&rtt_var=13041&sent=5&recv=6&lost=0&retrans=0&sent_bytes=2827&recv_bytes=970&delivery_rate=74111&cwnd=244&unsent_bytes=0&cid=9bcc030369a615fb&ts=210&x=0" - body: - encoding: ASCII-8BIT - string: '{"ticker":"AAPL","currency":"USD","exchange":{"name":"Nasdaq/Ngs (Global - Select Market)","mic_code":"XNGS","operating_mic_code":"XNAS","acronym":"NGS","country":"United - States","country_code":"US","timezone":"America/New_York"},"prices":[{"date":"2024-08-01","open":224.37,"close":218.36,"high":224.48,"low":217.02,"volume":62501000}],"paging":{"prev":"/tickers/AAPL/open-close?end_date=2024-08-01\u0026operating_mic_code=XNAS\u0026page=\u0026start_date=2024-08-01","next":"/tickers/AAPL/open-close?end_date=2024-08-01\u0026operating_mic_code=XNAS\u0026page=\u0026start_date=2024-08-01","total_records":1,"current_page":1,"per_page":100,"total_pages":1},"meta":{"total_records":1,"credits_used":1,"credits_remaining":249738}}' - recorded_at: Fri, 16 May 2025 13:01:36 GMT -recorded_with: VCR 6.3.1 diff --git a/test/vcr_cassettes/synth/security_prices.yml b/test/vcr_cassettes/synth/security_prices.yml deleted file mode 100644 index 8f41f56a1..000000000 --- a/test/vcr_cassettes/synth/security_prices.yml +++ /dev/null @@ -1,163 +0,0 @@ ---- -http_interactions: -- request: - method: get - uri: https://api.synthfinance.com/tickers/AAPL/open-close?end_date=2024-08-01&operating_mic_code=XNAS&page=1&start_date=2024-01-01 - body: - encoding: US-ASCII - string: '' - headers: - Authorization: - - Bearer - X-Source: - - maybe_app - X-Source-Type: - - managed - User-Agent: - - Faraday v2.13.1 - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - response: - status: - code: 200 - message: OK - headers: - Date: - - Fri, 16 May 2025 13:01:37 GMT - Content-Type: - - application/json; charset=utf-8 - Transfer-Encoding: - - chunked - Connection: - - keep-alive - Cache-Control: - - max-age=0, private, must-revalidate - Etag: - - W/"909e48e0b9ed1f892c1a1e1b4abd3082" - Referrer-Policy: - - strict-origin-when-cross-origin - Rndr-Id: - - 63af1418-59b9-4111 - Strict-Transport-Security: - - max-age=63072000; includeSubDomains - Vary: - - Accept-Encoding - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - SAMEORIGIN - X-Permitted-Cross-Domain-Policies: - - none - X-Render-Origin-Server: - - Render - X-Request-Id: - - 74da6a68-0bbd-48fb-b52a-0c5a750bd925 - X-Runtime: - - '0.044404' - X-Xss-Protection: - - '0' - Cf-Cache-Status: - - DYNAMIC - Report-To: - - '{"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v4?s=nwA0tsfR9it%2B9%2BtfHGjyzyfiSqPdNGxQqOLNF%2BIqlTeT1wJT6gLDCtbd1WFpOc1f8UXm2Zjn%2FJDOf7jOKWmGN6SKUBBjZvFLlBq%2FWyC7DN55NJwwyO77vD%2F5nf%2FaqduWCdPx7n7m"}],"group":"cf-nel","max_age":604800}' - Nel: - - '{"success_fraction":0,"report_to":"cf-nel","max_age":604800}' - Speculation-Rules: - - '"/cdn-cgi/speculation"' - Server: - - cloudflare - Cf-Ray: - - 940b10932ec92305-ORD - Alt-Svc: - - h3=":443"; ma=86400 - Server-Timing: - - cfL4;desc="?proto=TCP&rtt=27451&min_rtt=26715&rtt_var=11491&sent=5&recv=6&lost=0&retrans=0&sent_bytes=2825&recv_bytes=970&delivery_rate=88818&cwnd=249&unsent_bytes=0&cid=63105dfc059c15ef&ts=344&x=0" - body: - encoding: ASCII-8BIT - string: '{"ticker":"AAPL","currency":"USD","exchange":{"name":"Nasdaq/Ngs (Global - Select Market)","mic_code":"XNGS","operating_mic_code":"XNAS","acronym":"NGS","country":"United - States","country_code":"US","timezone":"America/New_York"},"prices":[{"date":"2024-01-02","open":187.15,"close":185.64,"high":188.44,"low":183.89,"volume":82488700},{"date":"2024-01-03","open":184.22,"close":184.25,"high":185.88,"low":183.43,"volume":58414500},{"date":"2024-01-04","open":182.15,"close":181.91,"high":183.09,"low":180.88,"volume":71983600},{"date":"2024-01-05","open":181.99,"close":181.18,"high":182.76,"low":180.17,"volume":62303300},{"date":"2024-01-08","open":182.09,"close":185.56,"high":185.6,"low":181.5,"volume":59144500},{"date":"2024-01-09","open":183.92,"close":185.14,"high":185.15,"low":182.73,"volume":42841800},{"date":"2024-01-10","open":184.35,"close":186.19,"high":186.4,"low":183.92,"volume":46792900},{"date":"2024-01-11","open":186.54,"close":185.59,"high":187.05,"low":183.62,"volume":49128400},{"date":"2024-01-12","open":186.06,"close":185.92,"high":186.74,"low":185.19,"volume":40444700},{"date":"2024-01-16","open":182.16,"close":183.63,"high":184.26,"low":180.93,"volume":65603000},{"date":"2024-01-17","open":181.27,"close":182.68,"high":182.93,"low":180.3,"volume":47317400},{"date":"2024-01-18","open":186.09,"close":188.63,"high":189.14,"low":185.83,"volume":78005800},{"date":"2024-01-19","open":189.33,"close":191.56,"high":191.95,"low":188.82,"volume":68741000},{"date":"2024-01-22","open":192.3,"close":193.89,"high":195.33,"low":192.26,"volume":60133900},{"date":"2024-01-23","open":195.02,"close":195.18,"high":195.75,"low":193.83,"volume":42355600},{"date":"2024-01-24","open":195.42,"close":194.5,"high":196.38,"low":194.34,"volume":53631300},{"date":"2024-01-25","open":195.22,"close":194.17,"high":196.27,"low":193.11,"volume":54822100},{"date":"2024-01-26","open":194.27,"close":192.42,"high":194.76,"low":191.94,"volume":44594000},{"date":"2024-01-29","open":192.01,"close":191.73,"high":192.2,"low":189.58,"volume":47145600},{"date":"2024-01-30","open":190.94,"close":188.04,"high":191.8,"low":187.47,"volume":55859400},{"date":"2024-01-31","open":187.04,"close":184.4,"high":187.1,"low":184.35,"volume":55467800},{"date":"2024-02-01","open":183.99,"close":186.86,"high":186.95,"low":183.82,"volume":64885400},{"date":"2024-02-02","open":179.86,"close":185.85,"high":187.33,"low":179.25,"volume":102518000},{"date":"2024-02-05","open":188.15,"close":187.68,"high":189.25,"low":185.84,"volume":69668800},{"date":"2024-02-06","open":186.86,"close":189.3,"high":189.31,"low":186.77,"volume":43490800},{"date":"2024-02-07","open":190.64,"close":189.41,"high":191.05,"low":188.61,"volume":53439000},{"date":"2024-02-08","open":189.39,"close":188.32,"high":189.54,"low":187.35,"volume":40962000},{"date":"2024-02-09","open":188.65,"close":188.85,"high":189.99,"low":188.0,"volume":45155200},{"date":"2024-02-12","open":188.42,"close":187.15,"high":188.67,"low":186.79,"volume":41781900},{"date":"2024-02-13","open":185.77,"close":185.04,"high":186.21,"low":183.51,"volume":56529500},{"date":"2024-02-14","open":185.32,"close":184.15,"high":185.53,"low":182.44,"volume":54630500},{"date":"2024-02-15","open":183.55,"close":183.86,"high":184.49,"low":181.35,"volume":65434500},{"date":"2024-02-16","open":183.42,"close":182.31,"high":184.85,"low":181.67,"volume":49701400},{"date":"2024-02-20","open":181.79,"close":181.56,"high":182.43,"low":180.0,"volume":53665600},{"date":"2024-02-21","open":181.94,"close":182.32,"high":182.89,"low":180.66,"volume":41529700},{"date":"2024-02-22","open":183.48,"close":184.37,"high":184.96,"low":182.46,"volume":52292200},{"date":"2024-02-23","open":185.01,"close":182.52,"high":185.04,"low":182.23,"volume":45119700},{"date":"2024-02-26","open":182.24,"close":181.16,"high":182.76,"low":180.65,"volume":40867400},{"date":"2024-02-27","open":181.1,"close":182.63,"high":183.92,"low":179.56,"volume":54318900},{"date":"2024-02-28","open":182.51,"close":181.42,"high":183.12,"low":180.13,"volume":48953900},{"date":"2024-02-29","open":181.27,"close":180.75,"high":182.57,"low":179.53,"volume":136682600},{"date":"2024-03-01","open":179.55,"close":179.66,"high":180.53,"low":177.38,"volume":73488000},{"date":"2024-03-04","open":176.15,"close":175.1,"high":176.9,"low":173.79,"volume":81510100},{"date":"2024-03-05","open":170.76,"close":170.12,"high":172.04,"low":169.62,"volume":95132400},{"date":"2024-03-06","open":171.06,"close":169.12,"high":171.24,"low":168.68,"volume":68587700},{"date":"2024-03-07","open":169.15,"close":169.0,"high":170.73,"low":168.49,"volume":71765100},{"date":"2024-03-08","open":169.0,"close":170.73,"high":173.7,"low":168.94,"volume":76114600},{"date":"2024-03-11","open":172.94,"close":172.75,"high":174.38,"low":172.05,"volume":60139500},{"date":"2024-03-12","open":173.15,"close":173.23,"high":174.03,"low":171.01,"volume":59825400},{"date":"2024-03-13","open":172.77,"close":171.13,"high":173.19,"low":170.76,"volume":52488700},{"date":"2024-03-14","open":172.91,"close":173.0,"high":174.31,"low":172.05,"volume":72913500},{"date":"2024-03-15","open":171.17,"close":172.62,"high":172.62,"low":170.29,"volume":121664700},{"date":"2024-03-18","open":175.57,"close":173.72,"high":177.71,"low":173.52,"volume":75604200},{"date":"2024-03-19","open":174.34,"close":176.08,"high":176.61,"low":173.03,"volume":55215200},{"date":"2024-03-20","open":175.72,"close":178.67,"high":178.67,"low":175.09,"volume":53423100},{"date":"2024-03-21","open":177.05,"close":171.37,"high":177.49,"low":170.84,"volume":106181300},{"date":"2024-03-22","open":171.76,"close":172.28,"high":173.05,"low":170.06,"volume":71106600},{"date":"2024-03-25","open":170.57,"close":170.85,"high":171.94,"low":169.45,"volume":54288300},{"date":"2024-03-26","open":170.0,"close":169.71,"high":171.42,"low":169.58,"volume":57388400},{"date":"2024-03-27","open":170.41,"close":173.31,"high":173.6,"low":170.11,"volume":60273300},{"date":"2024-03-28","open":171.75,"close":171.48,"high":172.23,"low":170.51,"volume":65672700},{"date":"2024-04-01","open":171.19,"close":170.03,"high":171.25,"low":169.48,"volume":46240500},{"date":"2024-04-02","open":169.08,"close":168.84,"high":169.34,"low":168.23,"volume":49329500},{"date":"2024-04-03","open":168.79,"close":169.65,"high":170.68,"low":168.58,"volume":47691700},{"date":"2024-04-04","open":170.29,"close":168.82,"high":171.92,"low":168.82,"volume":53704400},{"date":"2024-04-05","open":169.59,"close":169.58,"high":170.39,"low":168.95,"volume":42055200},{"date":"2024-04-08","open":169.03,"close":168.45,"high":169.2,"low":168.24,"volume":37425500},{"date":"2024-04-09","open":168.7,"close":169.67,"high":170.08,"low":168.35,"volume":42451200},{"date":"2024-04-10","open":168.8,"close":167.78,"high":169.09,"low":167.11,"volume":49709300},{"date":"2024-04-11","open":168.34,"close":175.04,"high":175.46,"low":168.16,"volume":91070300},{"date":"2024-04-12","open":174.26,"close":176.55,"high":178.36,"low":174.21,"volume":101593300},{"date":"2024-04-15","open":175.36,"close":172.69,"high":176.63,"low":172.5,"volume":73531800},{"date":"2024-04-16","open":171.75,"close":169.38,"high":173.76,"low":168.27,"volume":73711200},{"date":"2024-04-17","open":169.61,"close":168.0,"high":170.65,"low":168.0,"volume":50901200},{"date":"2024-04-18","open":168.03,"close":167.04,"high":168.64,"low":166.55,"volume":43122900},{"date":"2024-04-19","open":166.21,"close":165.0,"high":166.4,"low":164.08,"volume":67772100},{"date":"2024-04-22","open":165.52,"close":165.84,"high":167.26,"low":164.77,"volume":48116400},{"date":"2024-04-23","open":165.35,"close":166.9,"high":167.05,"low":164.92,"volume":49537800},{"date":"2024-04-24","open":166.54,"close":169.02,"high":169.3,"low":166.21,"volume":48251800},{"date":"2024-04-25","open":169.53,"close":169.89,"high":170.61,"low":168.15,"volume":50558300},{"date":"2024-04-26","open":169.88,"close":169.3,"high":171.34,"low":169.18,"volume":44838400},{"date":"2024-04-29","open":173.37,"close":173.5,"high":176.03,"low":173.1,"volume":68169400},{"date":"2024-04-30","open":173.33,"close":170.33,"high":174.99,"low":170.0,"volume":65934800},{"date":"2024-05-01","open":169.58,"close":169.3,"high":172.71,"low":169.11,"volume":50383100},{"date":"2024-05-02","open":172.51,"close":173.03,"high":173.42,"low":170.89,"volume":94214900},{"date":"2024-05-03","open":186.65,"close":183.38,"high":187.0,"low":182.66,"volume":163224100},{"date":"2024-05-06","open":182.35,"close":181.71,"high":184.2,"low":180.42,"volume":78569700},{"date":"2024-05-07","open":183.45,"close":182.4,"high":184.9,"low":181.32,"volume":77305800},{"date":"2024-05-08","open":182.85,"close":182.74,"high":183.07,"low":181.45,"volume":45057100},{"date":"2024-05-09","open":182.56,"close":184.57,"high":184.66,"low":182.11,"volume":48983000},{"date":"2024-05-10","open":184.9,"close":183.05,"high":185.09,"low":182.13,"volume":50759500},{"date":"2024-05-13","open":185.44,"close":186.28,"high":187.1,"low":184.62,"volume":72044800},{"date":"2024-05-14","open":187.51,"close":187.43,"high":188.3,"low":186.29,"volume":52393600},{"date":"2024-05-15","open":187.91,"close":189.72,"high":190.65,"low":187.37,"volume":70400000},{"date":"2024-05-16","open":190.47,"close":189.84,"high":191.1,"low":189.66,"volume":52845200},{"date":"2024-05-17","open":189.51,"close":189.87,"high":190.81,"low":189.18,"volume":41282900},{"date":"2024-05-20","open":189.33,"close":191.04,"high":191.92,"low":189.01,"volume":44361300},{"date":"2024-05-21","open":191.09,"close":192.35,"high":192.73,"low":190.92,"volume":42309400},{"date":"2024-05-22","open":192.27,"close":190.9,"high":192.82,"low":190.27,"volume":34648500},{"date":"2024-05-23","open":190.98,"close":186.88,"high":191.0,"low":186.63,"volume":51005900}],"paging":{"prev":"/tickers/AAPL/open-close?end_date=2024-08-01\u0026operating_mic_code=XNAS\u0026page=\u0026start_date=2024-01-01","next":"/tickers/AAPL/open-close?end_date=2024-08-01\u0026operating_mic_code=XNAS\u0026page=2\u0026start_date=2024-01-01","total_records":147,"current_page":1,"per_page":100,"total_pages":2},"meta":{"total_records":147,"credits_used":1,"credits_remaining":249736}}' - recorded_at: Fri, 16 May 2025 13:01:37 GMT -- request: - method: get - uri: https://api.synthfinance.com/tickers/AAPL/open-close?end_date=2024-08-01&operating_mic_code=XNAS&page=2&start_date=2024-01-01 - body: - encoding: US-ASCII - string: '' - headers: - Authorization: - - Bearer - X-Source: - - maybe_app - X-Source-Type: - - managed - User-Agent: - - Faraday v2.13.1 - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - response: - status: - code: 200 - message: OK - headers: - Date: - - Fri, 16 May 2025 13:01:37 GMT - Content-Type: - - application/json; charset=utf-8 - Transfer-Encoding: - - chunked - Connection: - - keep-alive - Cache-Control: - - max-age=0, private, must-revalidate - Etag: - - W/"bbc82ef9591694561dd9992a9c06d491" - Referrer-Policy: - - strict-origin-when-cross-origin - Rndr-Id: - - 63ebee52-f1b2-4e81 - Strict-Transport-Security: - - max-age=63072000; includeSubDomains - Vary: - - Accept-Encoding - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - SAMEORIGIN - X-Permitted-Cross-Domain-Policies: - - none - X-Render-Origin-Server: - - Render - X-Request-Id: - - dd95cb59-aead-4d1e-b1a2-881696e742fb - X-Runtime: - - '0.031482' - X-Xss-Protection: - - '0' - Cf-Cache-Status: - - DYNAMIC - Report-To: - - '{"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v4?s=ebrOdAId1yoCYepT0CPKImNIA%2BOe8V3W3BHYheEOkVQFLsffFpfl%2B%2BYXfEHL21wczvW5dkZSd3OrF%2FklB%2FwGGDahXpveXzf497azY1Ho4YJrtDJeghxyZV6J%2BALPYwwpGrfUpv%2F1"}],"group":"cf-nel","max_age":604800}' - Nel: - - '{"success_fraction":0,"report_to":"cf-nel","max_age":604800}' - Speculation-Rules: - - '"/cdn-cgi/speculation"' - Server: - - cloudflare - Cf-Ray: - - 940b1095ccd41156-ORD - Alt-Svc: - - h3=":443"; ma=86400 - Server-Timing: - - cfL4;desc="?proto=TCP&rtt=26344&min_rtt=26162&rtt_var=10175&sent=4&recv=6&lost=0&retrans=0&sent_bytes=2825&recv_bytes=970&delivery_rate=104847&cwnd=237&unsent_bytes=0&cid=9603fe0eb1df39aa&ts=212&x=0" - body: - encoding: ASCII-8BIT - string: '{"ticker":"AAPL","currency":"USD","exchange":{"name":"Nasdaq/Ngs (Global - Select Market)","mic_code":"XNGS","operating_mic_code":"XNAS","acronym":"NGS","country":"United - States","country_code":"US","timezone":"America/New_York"},"prices":[{"date":"2024-05-24","open":188.82,"close":189.98,"high":190.58,"low":188.04,"volume":36294600},{"date":"2024-05-28","open":191.51,"close":189.99,"high":193.0,"low":189.1,"volume":52280100},{"date":"2024-05-29","open":189.61,"close":190.29,"high":192.25,"low":189.51,"volume":53068000},{"date":"2024-05-30","open":190.76,"close":191.29,"high":192.18,"low":190.63,"volume":49947900},{"date":"2024-05-31","open":191.44,"close":192.25,"high":192.57,"low":189.91,"volume":75158300},{"date":"2024-06-03","open":192.9,"close":194.03,"high":194.99,"low":192.52,"volume":50080500},{"date":"2024-06-04","open":194.64,"close":194.35,"high":195.32,"low":193.03,"volume":47471400},{"date":"2024-06-05","open":195.4,"close":195.87,"high":196.9,"low":194.87,"volume":54156800},{"date":"2024-06-06","open":195.69,"close":194.48,"high":196.5,"low":194.17,"volume":41181800},{"date":"2024-06-07","open":194.65,"close":196.89,"high":196.94,"low":194.14,"volume":53103900},{"date":"2024-06-10","open":196.9,"close":193.12,"high":197.3,"low":192.15,"volume":97262100},{"date":"2024-06-11","open":193.65,"close":207.15,"high":207.16,"low":193.63,"volume":172373300},{"date":"2024-06-12","open":207.37,"close":213.07,"high":220.2,"low":206.9,"volume":198134300},{"date":"2024-06-13","open":214.74,"close":214.24,"high":216.75,"low":211.6,"volume":97862700},{"date":"2024-06-14","open":213.85,"close":212.49,"high":215.17,"low":211.3,"volume":70122700},{"date":"2024-06-17","open":213.37,"close":216.67,"high":218.95,"low":212.72,"volume":93728300},{"date":"2024-06-18","open":217.59,"close":214.29,"high":218.63,"low":213.0,"volume":79943300},{"date":"2024-06-20","open":213.93,"close":209.68,"high":214.24,"low":208.85,"volume":86172500},{"date":"2024-06-21","open":210.39,"close":207.49,"high":211.89,"low":207.11,"volume":246421400},{"date":"2024-06-24","open":207.72,"close":208.14,"high":212.7,"low":206.59,"volume":80727000},{"date":"2024-06-25","open":209.15,"close":209.07,"high":211.38,"low":208.61,"volume":56713900},{"date":"2024-06-26","open":211.5,"close":213.25,"high":214.86,"low":210.64,"volume":66213200},{"date":"2024-06-27","open":214.69,"close":214.1,"high":215.74,"low":212.35,"volume":49772700},{"date":"2024-06-28","open":215.77,"close":210.62,"high":216.07,"low":210.3,"volume":82542700},{"date":"2024-07-01","open":212.09,"close":216.75,"high":217.51,"low":211.92,"volume":60402900},{"date":"2024-07-02","open":216.15,"close":220.27,"high":220.38,"low":215.1,"volume":58046200},{"date":"2024-07-03","open":220.0,"close":221.55,"high":221.55,"low":219.03,"volume":37369800},{"date":"2024-07-05","open":221.65,"close":226.34,"high":226.45,"low":221.65,"volume":60412400},{"date":"2024-07-08","open":227.09,"close":227.82,"high":227.85,"low":223.25,"volume":59085900},{"date":"2024-07-09","open":227.93,"close":228.68,"high":229.4,"low":226.37,"volume":48076100},{"date":"2024-07-10","open":229.3,"close":232.98,"high":233.08,"low":229.25,"volume":62627700},{"date":"2024-07-11","open":231.39,"close":227.57,"high":232.39,"low":225.77,"volume":64710600},{"date":"2024-07-12","open":228.92,"close":230.54,"high":232.64,"low":228.68,"volume":53046500},{"date":"2024-07-15","open":236.48,"close":234.4,"high":237.23,"low":233.09,"volume":62631300},{"date":"2024-07-16","open":235.0,"close":234.82,"high":236.27,"low":232.33,"volume":43234300},{"date":"2024-07-17","open":229.45,"close":228.88,"high":231.46,"low":226.64,"volume":57345900},{"date":"2024-07-18","open":230.28,"close":224.18,"high":230.44,"low":222.27,"volume":66034600},{"date":"2024-07-19","open":224.82,"close":224.31,"high":226.8,"low":223.28,"volume":49151500},{"date":"2024-07-22","open":227.01,"close":223.96,"high":227.78,"low":223.09,"volume":48201800},{"date":"2024-07-23","open":224.37,"close":225.01,"high":226.94,"low":222.68,"volume":39960300},{"date":"2024-07-24","open":224.0,"close":218.54,"high":224.8,"low":217.13,"volume":61777600},{"date":"2024-07-25","open":218.93,"close":217.49,"high":220.85,"low":214.62,"volume":51391200},{"date":"2024-07-26","open":218.7,"close":217.96,"high":219.49,"low":216.01,"volume":41601300},{"date":"2024-07-29","open":216.96,"close":218.24,"high":219.3,"low":215.75,"volume":36311800},{"date":"2024-07-30","open":219.19,"close":218.8,"high":220.33,"low":216.12,"volume":41643800},{"date":"2024-07-31","open":221.44,"close":222.08,"high":223.82,"low":220.63,"volume":50036300},{"date":"2024-08-01","open":224.37,"close":218.36,"high":224.48,"low":217.02,"volume":62501000}],"paging":{"prev":"/tickers/AAPL/open-close?end_date=2024-08-01\u0026operating_mic_code=XNAS\u0026page=1\u0026start_date=2024-01-01","next":"/tickers/AAPL/open-close?end_date=2024-08-01\u0026operating_mic_code=XNAS\u0026page=\u0026start_date=2024-01-01","total_records":147,"current_page":2,"per_page":100,"total_pages":2},"meta":{"total_records":147,"credits_used":1,"credits_remaining":249735}}' - recorded_at: Fri, 16 May 2025 13:01:37 GMT -recorded_with: VCR 6.3.1 diff --git a/test/vcr_cassettes/synth/security_search.yml b/test/vcr_cassettes/synth/security_search.yml deleted file mode 100644 index c06c0f420..000000000 --- a/test/vcr_cassettes/synth/security_search.yml +++ /dev/null @@ -1,104 +0,0 @@ ---- -http_interactions: -- request: - method: get - uri: https://api.synthfinance.com/tickers/search?country_code=US&dataset=limited&limit=25&name=AAPL - body: - encoding: US-ASCII - string: '' - headers: - Authorization: - - Bearer - X-Source: - - maybe_app - X-Source-Type: - - managed - User-Agent: - - Faraday v2.13.1 - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - response: - status: - code: 200 - message: OK - headers: - Date: - - Fri, 16 May 2025 13:01:38 GMT - Content-Type: - - application/json; charset=utf-8 - Transfer-Encoding: - - chunked - Connection: - - keep-alive - Cache-Control: - - max-age=0, private, must-revalidate - Etag: - - W/"3e444869eacbaf17006766a691cc8fdc" - Referrer-Policy: - - strict-origin-when-cross-origin - Rndr-Id: - - 701ae22a-18c8-4e62 - Strict-Transport-Security: - - max-age=63072000; includeSubDomains - Vary: - - Accept-Encoding - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - SAMEORIGIN - X-Permitted-Cross-Domain-Policies: - - none - X-Render-Origin-Server: - - Render - X-Request-Id: - - edb55bc6-e3ea-470b-b7af-9b4d9883420b - X-Runtime: - - '0.355152' - X-Xss-Protection: - - '0' - Cf-Cache-Status: - - DYNAMIC - Report-To: - - '{"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v4?s=QGeBWdYED%2F%2FgT9BzborFAnM%2FG6UiNmI0ej212XGHWdFwYXUvTJ2GyqA9hMJrpYIvgbHdQ9Ed0MsQUv3KFb57VXQq0T6UXTNPa%2BFRPepK0hsXeGDLxch04v6KnkTATqcw2M8HuYHS"}],"group":"cf-nel","max_age":604800}' - Nel: - - '{"success_fraction":0,"report_to":"cf-nel","max_age":604800}' - Speculation-Rules: - - '"/cdn-cgi/speculation"' - Server: - - cloudflare - Cf-Ray: - - 940b1097a830f856-ORD - Alt-Svc: - - h3=":443"; ma=86400 - Server-Timing: - - cfL4;desc="?proto=TCP&rtt=26401&min_rtt=25556&rtt_var=11273&sent=5&recv=6&lost=0&retrans=0&sent_bytes=2825&recv_bytes=939&delivery_rate=89615&cwnd=244&unsent_bytes=0&cid=cf6d0758d165295d&ts=500&x=0" - body: - encoding: ASCII-8BIT - string: '{"data":[{"symbol":"AAPL","name":"Apple Inc.","logo_url":"https://logo.synthfinance.com/ticker/AAPL","currency":"USD","exchange":{"name":"Nasdaq/Ngs - (Global Select Market)","mic_code":"XNGS","operating_mic_code":"XNAS","acronym":"NGS","country":"United - States","country_code":"US","timezone":"America/New_York"}},{"symbol":"APLY","isin":"US88634T8577","name":"YieldMax - AAPL Option Income ETF","logo_url":"https://logo.synthfinance.com/ticker/APLY","currency":"USD","exchange":{"name":"Nyse - Arca","mic_code":"ARCX","operating_mic_code":"XNYS","acronym":"NYSE","country":"United - States","country_code":"US","timezone":"America/New_York"}},{"symbol":"AAPD","name":"Direxion - Daily AAPL Bear 1X ETF","logo_url":"https://logo.synthfinance.com/ticker/AAPD","currency":"USD","exchange":{"name":"Nasdaq/Nms - (Global Market)","mic_code":"XNMS","operating_mic_code":"XNAS","acronym":"","country":"United - States","country_code":"US","timezone":"America/New_York"}},{"symbol":"AAPU","isin":"US25461A8743","name":"Direxion - Daily AAPL Bull 2X Shares","logo_url":"https://logo.synthfinance.com/ticker/AAPU","currency":"USD","exchange":{"name":"Nasdaq/Nms - (Global Market)","mic_code":"XNMS","operating_mic_code":"XNAS","acronym":"","country":"United - States","country_code":"US","timezone":"America/New_York"}},{"symbol":"AAPB","isin":"XXXXXXXR8842","name":"GraniteShares - 2x Long AAPL Daily ETF","logo_url":"https://logo.synthfinance.com/ticker/AAPB","currency":"USD","exchange":{"name":"Nasdaq/Ngs - (Global Select Market)","mic_code":"XNGS","operating_mic_code":"XNAS","acronym":"NGS","country":"United - States","country_code":"US","timezone":"America/New_York"}},{"symbol":"AAPD","isin":"US25461A3041","name":"Direxion - Daily AAPL Bear 1X Shares","logo_url":"https://logo.synthfinance.com/ticker/AAPD","currency":"USD","exchange":{"name":"Nasdaq/Ngs - (Global Select Market)","mic_code":"XNGS","operating_mic_code":"XNAS","acronym":"NGS","country":"United - States","country_code":"US","timezone":"America/New_York"}},{"symbol":"AAPU","isin":"US25461A8743","name":"Direxion - Daily AAPL Bull 1.5X Shares","logo_url":"https://logo.synthfinance.com/ticker/AAPU","currency":"USD","exchange":{"name":"Nasdaq/Ngs - (Global Select Market)","mic_code":"XNGS","operating_mic_code":"XNAS","acronym":"NGS","country":"United - States","country_code":"US","timezone":"America/New_York"}},{"symbol":"AAPJ","isin":"US00037T1034","name":"AAP, - Inc.","logo_url":"https://logo.synthfinance.com/ticker/AAPJ","currency":"USD","exchange":{"name":"Otc - Pink Marketplace","mic_code":"PINX","operating_mic_code":"OTCM","acronym":"","country":"United - States","country_code":"US","timezone":"America/New_York"}}]}' - recorded_at: Fri, 16 May 2025 13:01:38 GMT -recorded_with: VCR 6.3.1 diff --git a/test/vcr_cassettes/synth/usage.yml b/test/vcr_cassettes/synth/usage.yml deleted file mode 100644 index d60922db7..000000000 --- a/test/vcr_cassettes/synth/usage.yml +++ /dev/null @@ -1,82 +0,0 @@ ---- -http_interactions: -- request: - method: get - uri: https://api.synthfinance.com/user - body: - encoding: US-ASCII - string: '' - headers: - Authorization: - - Bearer - X-Source: - - maybe_app - X-Source-Type: - - managed - User-Agent: - - Faraday v2.13.1 - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - response: - status: - code: 200 - message: OK - headers: - Date: - - Fri, 16 May 2025 13:01:36 GMT - Content-Type: - - application/json; charset=utf-8 - Transfer-Encoding: - - chunked - Connection: - - keep-alive - Cache-Control: - - max-age=0, private, must-revalidate - Etag: - - W/"7b8c2bf0cba54bc26b78bdc6e611dcbd" - Referrer-Policy: - - strict-origin-when-cross-origin - Rndr-Id: - - 1b53adf6-b391-45b2 - Strict-Transport-Security: - - max-age=63072000; includeSubDomains - Vary: - - Accept-Encoding - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - SAMEORIGIN - X-Permitted-Cross-Domain-Policies: - - none - X-Render-Origin-Server: - - Render - X-Request-Id: - - f88670a2-81d2-48b6-8d73-a911c846e330 - X-Runtime: - - '0.018749' - X-Xss-Protection: - - '0' - Cf-Cache-Status: - - DYNAMIC - Report-To: - - '{"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v4?s=oH4OsWB6itK0jpi%2FPs%2BswVyCZIbkJGPfyJaoR4TKFtTAfmnqa8Lp6aZhv22WKzotXJuAKbh99VdYdZIOkeIPWbYTc6j4rGw%2BkQB3Hw%2Fc44QxDBJFdIo6wJNe8TGiPAZ%2BvgoBVHWn"}],"group":"cf-nel","max_age":604800}' - Nel: - - '{"success_fraction":0,"report_to":"cf-nel","max_age":604800}' - Speculation-Rules: - - '"/cdn-cgi/speculation"' - Server: - - cloudflare - Cf-Ray: - - 940b108c38f66392-ORD - Alt-Svc: - - h3=":443"; ma=86400 - Server-Timing: - - cfL4;desc="?proto=TCP&rtt=33369&min_rtt=25798&rtt_var=15082&sent=5&recv=6&lost=0&retrans=0&sent_bytes=2826&recv_bytes=878&delivery_rate=112256&cwnd=205&unsent_bytes=0&cid=1b13324eb0768fd3&ts=285&x=0" - body: - encoding: ASCII-8BIT - string: '{"id":"user_3208c49393f54b3e974795e4bea5b864","email":"zach@maybe.co","name":"Zach - Gollwitzer","plan":"Business","api_calls_remaining":249738,"api_limit":250000,"credits_reset_at":"2025-06-01T00:00:00.000-04:00","current_period_start":"2025-05-01T00:00:00.000-04:00"}' - recorded_at: Fri, 16 May 2025 13:01:36 GMT -recorded_with: VCR 6.3.1