From c0071a759377fee84b74280bbbe7fc800d675b77 Mon Sep 17 00:00:00 2001
From: 24c02 <163450896+24c02@users.noreply.github.com>
Date: Thu, 18 Dec 2025 14:41:15 -0500
Subject: [PATCH] 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
---
.idea/workspace.xml | 10 ++++++++--
app/models/hcb.rb | 5 +++++
app/models/hcb/oauth_connection.rb | 29 +++++++++++++++++++++++++++++
app/models/hcb/payment_account.rb | 23 +++++++++++++++++++++++
app/models/user.rb | 6 ++++++
5 files changed, 71 insertions(+), 2 deletions(-)
create mode 100644 app/models/hcb.rb
create mode 100644 app/models/hcb/oauth_connection.rb
create mode 100644 app/models/hcb/payment_account.rb
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index a307bd3..ac7d38d 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,7 +4,13 @@
-
+
+
+
+
+
+
+
@@ -155,7 +161,7 @@
-
+
diff --git a/app/models/hcb.rb b/app/models/hcb.rb
new file mode 100644
index 0000000..ab05c02
--- /dev/null
+++ b/app/models/hcb.rb
@@ -0,0 +1,5 @@
+module HCB
+ def self.table_name_prefix
+ "hcb_"
+ end
+end
diff --git a/app/models/hcb/oauth_connection.rb b/app/models/hcb/oauth_connection.rb
new file mode 100644
index 0000000..0425a11
--- /dev/null
+++ b/app/models/hcb/oauth_connection.rb
@@ -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
diff --git a/app/models/hcb/payment_account.rb b/app/models/hcb/payment_account.rb
new file mode 100644
index 0000000..1678488
--- /dev/null
+++ b/app/models/hcb/payment_account.rb
@@ -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
diff --git a/app/models/user.rb b/app/models/user.rb
index 008600a..935fa52 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -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)