Add migrations for HCB payment integration

- Add can_use_indicia boolean to users table
- Create hcb_oauth_connections table for storing OAuth tokens
- Create hcb_payment_accounts table for user/org pairs
This commit is contained in:
24c02 2025-12-18 14:40:06 -05:00
parent 7a8e91b692
commit 417c1f0e8f
9 changed files with 232 additions and 2 deletions

165
.idea/workspace.xml generated Normal file
View file

@ -0,0 +1,165 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="d1cc2402-3c65-4046-bb1c-ec3e5b4aef52" name="Changes" comment="" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="GitHubPullRequestSearchHistory">{
&quot;lastFilter&quot;: {
&quot;state&quot;: &quot;OPEN&quot;,
&quot;assignee&quot;: &quot;24c02&quot;
}
}</component>
<component name="GithubPullRequestsUISettings">{
&quot;selectedUrlAndAccountId&quot;: {
&quot;url&quot;: &quot;https://github.com/hackclub/theseus.git&quot;,
&quot;accountId&quot;: &quot;3eaf51f9-f8da-43ac-8e0c-ec58d166ad1e&quot;
}
}</component>
<component name="ProjectColorInfo">{
&quot;customColor&quot;: &quot;&quot;,
&quot;associatedIndex&quot;: 4
}</component>
<component name="ProjectId" id="36aRgK2JIPtQhsXSARIYxSAuuXK" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"ModuleVcsDetector.initialDetectionPerformed": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
"RunOnceActivity.git.unshallow": "true",
"com.intellij.lang.ruby.rbs.tools.collection.workspace.sync.RbsCollectionUpdateProjectActivity#LAST_UPDATE_TIMESTAMP": "1766085193730",
"git-widget-placeholder": "main",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "yarn",
"ruby.structure.view.model.defaults.configured": "true",
"settings.editor.selected.configurable": "preferences.lookFeel",
"vue.rearranger.settings.migration": "true"
}
}]]></component>
<component name="RubyModuleManagerSettings">
<option name="blackListedRootsPaths">
<list>
<option value="$PROJECT_DIR$" />
</list>
</option>
</component>
<component name="RunManager" selected="Rails.theseus">
<configuration name="theseus" type="RailsRunConfigurationType" factoryName="Rails">
<module name="theseus" />
<predefined_log_file enabled="true" id="RUBY_RAILS_SERVER" />
<RAILS_SERVER_CONFIG_SETTINGS_ID NAME="RUBY_ARGS" VALUE="" />
<RAILS_SERVER_CONFIG_SETTINGS_ID NAME="WORK DIR" VALUE="$MODULE_DIR$" />
<RAILS_SERVER_CONFIG_SETTINGS_ID NAME="SHOULD_USE_SDK" VALUE="false" />
<RAILS_SERVER_CONFIG_SETTINGS_ID NAME="ALTERN_SDK_NAME" VALUE="" />
<RAILS_SERVER_CONFIG_SETTINGS_ID NAME="myPassParentEnvs" VALUE="true" />
<EXTENSION ID="BundlerRunConfigurationExtension" BUNDLE_MODE="AUTO" bundleExecEnabled="true" />
<EXTENSION ID="RubyCoverageRunConfigurationExtension" track_test_folders="true" runner="rcov" ENABLE_BRANCH_COVERAGE="true" ENABLE_FORKED_COVERAGE="true">
<COVERAGE_PATTERN ENABLED="true">
<PATTERN REGEXPS="/.rvm/" INCLUDED="false" />
</COVERAGE_PATTERN>
</EXTENSION>
<EXTENSION ID="org.jetbrains.plugins.ruby.rails.run.RailsRunConfigurationExtension" SCRATCH_USE_RAILS_RUNNER="false" />
<RAILS_SERVER_CONFIG_SETTINGS_ID NAME="SCRIPT_ARGS" VALUE="" />
<RAILS_SERVER_CONFIG_SETTINGS_ID NAME="PORT" VALUE="3000" />
<RAILS_SERVER_CONFIG_SETTINGS_ID NAME="IP" VALUE="127.0.0.1" />
<RAILS_SERVER_CONFIG_SETTINGS_ID NAME="DUMMY_APP" VALUE="test/dummy" />
<RAILS_SERVER_CONFIG_SETTINGS_ID NAME="RAILS_SERVER_TYPE" VALUE="Default" />
<RAILS_SERVER_CONFIG_SETTINGS_ID NAME="ENVIRONMENT_TYPE" VALUE="development" />
<RAILS_SERVER_CONFIG_SETTINGS_ID NAME="LAUNCH_JS" VALUE="false" />
<method v="2" />
</configuration>
<configuration name="spec: theseus" type="RakeRunConfigurationType" factoryName="Rake">
<module name="theseus" />
<predefined_log_file enabled="true" id="RUBY_RAKE" />
<RAKE_RUN_CONFIG_SETTINGS_ID NAME="RUBY_ARGS" VALUE="" />
<RAKE_RUN_CONFIG_SETTINGS_ID NAME="WORK DIR" VALUE="$MODULE_DIR$" />
<RAKE_RUN_CONFIG_SETTINGS_ID NAME="SHOULD_USE_SDK" VALUE="false" />
<RAKE_RUN_CONFIG_SETTINGS_ID NAME="ALTERN_SDK_NAME" VALUE="" />
<RAKE_RUN_CONFIG_SETTINGS_ID NAME="myPassParentEnvs" VALUE="true" />
<EXTENSION ID="BundlerRunConfigurationExtension" BUNDLE_MODE="AUTO" bundleExecEnabled="true" />
<EXTENSION ID="RubyCoverageRunConfigurationExtension" track_test_folders="true" runner="rcov" ENABLE_BRANCH_COVERAGE="true" ENABLE_FORKED_COVERAGE="true">
<COVERAGE_PATTERN ENABLED="true">
<PATTERN REGEXPS="/.rvm/" INCLUDED="false" />
</COVERAGE_PATTERN>
</EXTENSION>
<EXTENSION ID="org.jetbrains.plugins.ruby.rails.run.RailsRunConfigurationExtension" SCRATCH_USE_RAILS_RUNNER="false" />
<RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_NAME" VALUE="spec" />
<RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_ARGS" VALUE="" />
<RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_ATTACHED_TEST_FRAMEWORKS" VALUE=":rspec " />
<RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_OPTION_TRACE" VALUE="false" />
<RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_OPTION_DRYRUN" VALUE="false" />
<RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_OPTION_PREREQS" VALUE="false" />
<RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_OPTION_TESTOPTS" VALUE="" />
<method v="2" />
</configuration>
<configuration name="test: theseus" type="RakeRunConfigurationType" factoryName="Rake">
<module name="theseus" />
<predefined_log_file enabled="true" id="RUBY_RAKE" />
<RAKE_RUN_CONFIG_SETTINGS_ID NAME="RUBY_ARGS" VALUE="" />
<RAKE_RUN_CONFIG_SETTINGS_ID NAME="WORK DIR" VALUE="$MODULE_DIR$" />
<RAKE_RUN_CONFIG_SETTINGS_ID NAME="SHOULD_USE_SDK" VALUE="false" />
<RAKE_RUN_CONFIG_SETTINGS_ID NAME="ALTERN_SDK_NAME" VALUE="" />
<RAKE_RUN_CONFIG_SETTINGS_ID NAME="myPassParentEnvs" VALUE="true" />
<envs>
<env name="RAILS_ENV" value="test" />
</envs>
<EXTENSION ID="BundlerRunConfigurationExtension" BUNDLE_MODE="AUTO" bundleExecEnabled="true" />
<EXTENSION ID="RubyCoverageRunConfigurationExtension" track_test_folders="true" runner="rcov" ENABLE_BRANCH_COVERAGE="true" ENABLE_FORKED_COVERAGE="true">
<COVERAGE_PATTERN ENABLED="true">
<PATTERN REGEXPS="/.rvm/" INCLUDED="false" />
</COVERAGE_PATTERN>
</EXTENSION>
<EXTENSION ID="org.jetbrains.plugins.ruby.rails.run.RailsRunConfigurationExtension" SCRATCH_USE_RAILS_RUNNER="false" />
<RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_NAME" VALUE="test" />
<RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_ARGS" VALUE="" />
<RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_ATTACHED_TEST_FRAMEWORKS" VALUE=":test_unit " />
<RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_OPTION_TRACE" VALUE="false" />
<RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_OPTION_DRYRUN" VALUE="false" />
<RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_OPTION_PREREQS" VALUE="false" />
<RAKE_RUN_CONFIG_SETTINGS_ID NAME="RAKE_TASK_OPTION_TESTOPTS" VALUE="" />
<method v="2" />
</configuration>
</component>
<component name="SharedIndexes">
<attachedChunks>
<set>
<option value="bundled-js-predefined-d6986cc7102b-9c94529fcfe0-JavaScript-RM-252.26199.157" />
</set>
</attachedChunks>
</component>
<component name="SpringUtil" SPRING_PRE_LOADER_OPTION="true" RAKE_SPRING_PRE_LOADER_OPTION="true" RAILS_SPRING_PRE_LOADER_OPTION="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="d1cc2402-3c65-4046-bb1c-ec3e5b4aef52" name="Changes" comment="" />
<created>1765242806022</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1765242806022</updated>
<workItem from="1765242807279" duration="1218000" />
<workItem from="1765302419304" duration="4201000" />
<workItem from="1765488873945" duration="19000" />
<workItem from="1765488900213" duration="5988000" />
<workItem from="1766085135057" duration="992000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
</project>

View file

@ -176,3 +176,5 @@ gem "xsv", "~> 1.3"
gem "phlex-pdf", "~> 0.1.2"
gem "ttfunk", github: "24c02/ttfunk"
gem "hcbv4", "~> 0.1"

View file

@ -238,6 +238,7 @@ GEM
hashids (~> 1.0)
hashids (1.0.6)
hashie (5.0.0)
hcbv4 (0.1.1)
honeybadger (5.28.0)
logger
ostruct
@ -719,6 +720,7 @@ DEPENDENCIES
foreman (~> 0.88.1)
good_job (~> 4.11)
hashid-rails (~> 1.4)
hcbv4 (~> 0.1)
honeybadger (~> 5.28)
http (~> 5.2)
ivymeter (~> 0.1.0)

View file

@ -7,6 +7,11 @@
# opted_out_of_map :boolean default(FALSE)
# created_at :datetime not null
# updated_at :datetime not null
# hca_id :string
#
# Indexes
#
# index_public_users_on_hca_id (hca_id) UNIQUE
#
class Public::User < ApplicationRecord
has_many :login_codes

View file

@ -5,6 +5,7 @@
# id :bigint not null, primary key
# back_office :boolean default(FALSE)
# can_impersonate_public :boolean
# can_use_indicia :boolean default(FALSE), not null
# can_warehouse :boolean
# email :string
# icon_url :string
@ -12,13 +13,14 @@
# username :string
# created_at :datetime not null
# updated_at :datetime not null
# hca_id :string
# home_mid_id :bigint default(1), not null
# home_return_address_id :bigint default(1), not null
# hca_id :string
# slack_id :string
#
# Indexes
#
# index_users_on_hca_id (hca_id) UNIQUE
# index_users_on_home_mid_id (home_mid_id)
# index_users_on_home_return_address_id (home_return_address_id)
#

View file

@ -0,0 +1,5 @@
class AddCanUseIndiciaToUsers < ActiveRecord::Migration[8.0]
def change
add_column :users, :can_use_indicia, :boolean, default: false, null: false
end
end

View file

@ -0,0 +1,12 @@
class CreateHCBOauthConnections < ActiveRecord::Migration[8.0]
def change
create_table :hcb_oauth_connections do |t|
t.references :user, null: false, foreign_key: true
t.text :access_token_ciphertext
t.text :refresh_token_ciphertext
t.datetime :expires_at
t.timestamps
end
end
end

View file

@ -0,0 +1,12 @@
class CreateHCBPaymentAccounts < ActiveRecord::Migration[8.0]
def change
create_table :hcb_payment_accounts do |t|
t.references :user, null: false, foreign_key: true
t.references :hcb_oauth_connection, null: false, foreign_key: true
t.string :organization_id
t.string :organization_name
t.timestamps
end
end
end

27
db/schema.rb generated
View file

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[8.0].define(version: 2025_12_11_000001) do
ActiveRecord::Schema[8.0].define(version: 2025_12_18_193953) do
# These are extensions that must be enabled in order to support this database
enable_extension "citext"
enable_extension "pg_catalog.plpgsql"
@ -268,6 +268,27 @@ ActiveRecord::Schema[8.0].define(version: 2025_12_11_000001) do
t.index ["scheduled_at"], name: "index_good_jobs_on_scheduled_at", where: "(finished_at IS NULL)"
end
create_table "hcb_oauth_connections", force: :cascade do |t|
t.bigint "user_id", null: false
t.text "access_token_ciphertext"
t.text "refresh_token_ciphertext"
t.datetime "expires_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["user_id"], name: "index_hcb_oauth_connections_on_user_id"
end
create_table "hcb_payment_accounts", force: :cascade do |t|
t.bigint "user_id", null: false
t.bigint "hcb_oauth_connection_id", null: false
t.string "organization_id"
t.string "organization_name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["hcb_oauth_connection_id"], name: "index_hcb_payment_accounts_on_hcb_oauth_connection_id"
t.index ["user_id"], name: "index_hcb_payment_accounts_on_user_id"
end
create_table "letter_queues", force: :cascade do |t|
t.string "name"
t.string "slug"
@ -414,6 +435,7 @@ ActiveRecord::Schema[8.0].define(version: 2025_12_11_000001) do
t.bigint "home_mid_id", default: 1, null: false
t.bigint "home_return_address_id", default: 1, null: false
t.string "hca_id"
t.boolean "can_use_indicia", default: false, null: false
t.index ["hca_id"], name: "index_users_on_hca_id", unique: true
t.index ["home_mid_id"], name: "index_users_on_home_mid_id"
t.index ["home_return_address_id"], name: "index_users_on_home_return_address_id"
@ -577,6 +599,9 @@ ActiveRecord::Schema[8.0].define(version: 2025_12_11_000001) do
add_foreign_key "batches", "users"
add_foreign_key "batches", "usps_mailer_ids", column: "letter_mailer_id_id"
add_foreign_key "batches", "warehouse_templates"
add_foreign_key "hcb_oauth_connections", "users"
add_foreign_key "hcb_payment_accounts", "hcb_oauth_connections"
add_foreign_key "hcb_payment_accounts", "users"
add_foreign_key "letter_queues", "return_addresses", column: "letter_return_address_id"
add_foreign_key "letter_queues", "users"
add_foreign_key "letter_queues", "usps_mailer_ids", column: "letter_mailer_id_id"