Add HCB models and user associations

- HCB::OauthConnection for storing encrypted OAuth tokens
- HCB::PaymentAccount for user/org payment pairs
- User#can_use_indicia? and #hcb_connected? helpers
This commit is contained in:
24c02 2025-12-18 14:41:15 -05:00
parent 417c1f0e8f
commit c0071a7593
5 changed files with 71 additions and 2 deletions

10
.idea/workspace.xml generated
View file

@ -4,7 +4,13 @@
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="d1cc2402-3c65-4046-bb1c-ec3e5b4aef52" name="Changes" comment="" />
<list default="true" id="d1cc2402-3c65-4046-bb1c-ec3e5b4aef52" name="Changes" comment="">
<change beforePath="$PROJECT_DIR$/Gemfile" beforeDir="false" afterPath="$PROJECT_DIR$/Gemfile" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Gemfile.lock" beforeDir="false" afterPath="$PROJECT_DIR$/Gemfile.lock" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/models/public/user.rb" beforeDir="false" afterPath="$PROJECT_DIR$/app/models/public/user.rb" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/models/user.rb" beforeDir="false" afterPath="$PROJECT_DIR$/app/models/user.rb" afterDir="false" />
<change beforePath="$PROJECT_DIR$/db/schema.rb" beforeDir="false" afterPath="$PROJECT_DIR$/db/schema.rb" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
@ -155,7 +161,7 @@
<workItem from="1765302419304" duration="4201000" />
<workItem from="1765488873945" duration="19000" />
<workItem from="1765488900213" duration="5988000" />
<workItem from="1766085135057" duration="992000" />
<workItem from="1766085135057" duration="1297000" />
</task>
<servers />
</component>

5
app/models/hcb.rb Normal file
View file

@ -0,0 +1,5 @@
module HCB
def self.table_name_prefix
"hcb_"
end
end

View file

@ -0,0 +1,29 @@
class HCB::OauthConnection < ApplicationRecord
belongs_to :user
has_many :payment_accounts, dependent: :destroy
has_encrypted :access_token, :refresh_token
validates :user_id, uniqueness: true
def client
@client ||= HCBV4::Client.new(
client_id: Rails.application.credentials.dig(:hcb, :client_id),
client_secret: Rails.application.credentials.dig(:hcb, :client_secret),
access_token: access_token,
refresh_token: refresh_token,
expires_at: expires_at&.to_i,
on_token_refresh: ->(new_access, new_refresh, new_expires) {
update!(
access_token: new_access,
refresh_token: new_refresh,
expires_at: Time.at(new_expires),
)
},
)
end
def organizations
client.user.organizations
end
end

View file

@ -0,0 +1,23 @@
class HCB::PaymentAccount < ApplicationRecord
belongs_to :user
belongs_to :oauth_connection, class_name: "HCB::OauthConnection", foreign_key: :hcb_oauth_connection_id
validates :organization_id, presence: true, uniqueness: { scope: :user_id }
validates :organization_name, presence: true
def client
oauth_connection.client
end
def organization
client.organization!(organization_id)
end
def create_disbursement!(amount_cents:, memo:)
organization.create_transfer(
amount_cents: amount_cents,
recipient_organization_id: Rails.application.credentials.dig(:hcb, :recipient_org_id),
memo: memo,
)
end
end

View file

@ -35,6 +35,8 @@ class User < ApplicationRecord
has_many :letters
has_many :batches
has_many :letter_queues, dependent: :destroy, class_name: "Letter::Queue"
has_one :hcb_oauth_connection, class_name: "HCB::OauthConnection", dependent: :destroy
has_many :hcb_payment_accounts, class_name: "HCB::PaymentAccount", dependent: :destroy
belongs_to :home_mid, class_name: "USPS::MailerId", optional: true
belongs_to :home_return_address, class_name: "ReturnAddress", optional: true
@ -44,6 +46,10 @@ class User < ApplicationRecord
def admin? = is_admin
def can_use_indicia? = can_use_indicia
def hcb_connected? = hcb_oauth_connection.present?
def make_admin! = update!(is_admin: true)
def remove_admin! = update!(is_admin: false)