# frozen_string_literal: true # == Schema Information # # Table name: accounts # # id :bigint not null, primary key # archived_at :datetime # locale :string not null # name :string not null # timezone :string not null # uuid :string not null # created_at :datetime not null # updated_at :datetime not null # # Indexes # # index_accounts_on_uuid (uuid) UNIQUE # class Account < ApplicationRecord attribute :uuid, :string, default: -> { SecureRandom.uuid } has_many :users, dependent: :destroy has_many :encrypted_configs, dependent: :destroy has_many :account_configs, dependent: :destroy has_many :email_messages, dependent: :destroy has_many :templates, dependent: :destroy has_many :template_folders, dependent: :destroy has_one :default_template_folder, -> { where(name: TemplateFolder::DEFAULT_NAME) }, class_name: 'TemplateFolder', dependent: :destroy, inverse_of: :account has_many :submissions, dependent: :destroy has_many :submitters, dependent: :destroy has_many :account_linked_accounts, dependent: :destroy has_many :email_events, dependent: :destroy has_many :webhook_urls, dependent: :destroy has_many :webhook_events, dependent: nil has_many :account_accesses, dependent: :destroy has_many :account_testing_accounts, -> { testing }, dependent: :destroy, class_name: 'AccountLinkedAccount', inverse_of: :account has_one :linked_account_account, dependent: :destroy, foreign_key: :linked_account_id, class_name: 'AccountLinkedAccount', inverse_of: :linked_account has_many :linked_account_accounts, dependent: :destroy, foreign_key: :linked_account_id, class_name: 'AccountLinkedAccount', inverse_of: :linked_account has_many :linked_accounts, through: :account_linked_accounts has_many :testing_accounts, through: :account_testing_accounts, source: :linked_account has_many :active_users, -> { active }, dependent: :destroy, inverse_of: :account, class_name: 'User' attribute :timezone, :string, default: 'UTC' attribute :locale, :string, default: 'en-US' scope :active, -> { where(archived_at: nil) } after_create_commit :apply_env_config_overrides # Collect all DOCUSEAL_CONFIG_* env vars as a { key => casted_value } hash. def self.env_config_overrides prefix = AccountConfig::ENV_PREFIX ENV.each_with_object({}) do |(var, _), acc| next unless var.start_with?(prefix) key = var.sub(prefix, '').downcase acc[key] = AccountConfig.env_override_cast(key) end end # Upsert env overrides into this account's account_configs rows. def apply_env_config_overrides self.class.env_config_overrides.each do |key, value| cfg = account_configs.find_or_initialize_by(key: key) cfg.value = value cfg.save! end end # Returns [value, locked_by_env?] for a config key. Env value takes precedence. def config_value(key, default: nil) if AccountConfig.locked_by_env?(key) [AccountConfig.env_override_cast(key), true] else row = account_configs.find_by(key: key) [row ? row.value : default, false] end end # Convenience: treats the config value as a boolean visibility flag. def ui_visible?(key, default: true) value, _locked = config_value(key, default: default) return default if value.nil? ActiveModel::Type::Boolean.new.cast(value) end def testing? linked_account_account&.testing? end def tz_info @tz_info ||= TZInfo::Timezone.get(ActiveSupport::TimeZone::MAPPING[timezone] || timezone) end def default_template_folder super || build_default_template_folder(name: TemplateFolder::DEFAULT_NAME, author_id: users.minimum(:id)).tap(&:save!) end end