Initial enable banking implementation (#382)

* Initial enable banking implementation

* Handle multiple connections

* Amount fixes

* Account type mapping

* Add option to skip accounts

* Update schema.rb

* Transaction fixes

* Provider fixes

* FIX account identifier

* FIX support unlinking

* UI style fixes

* FIX safe redirect and brakeman issue

* FIX

- pagination max fix
- wrap crud in transaction logic

* FIX api uid access

- The Enable Banking API expects the UUID (uid from the API response) to fetch balances/transactions, not the identification_hash

* FIX add new connection

* FIX erb code

* Alert/notice box overflow protection

* Give alert/notification boxes room to grow (3 lines max)

* Add "Enable Banking (beta)" to `/settings/bank_sync`

* Make Enable Banking section collapsible like all others

* Add callback hint to error message

---------

Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
This commit is contained in:
soky srm
2025-11-29 13:31:08 +01:00
committed by GitHub
parent ba266986d4
commit 4a29d030af
36 changed files with 2642 additions and 15 deletions

View File

@@ -0,0 +1,73 @@
class CreateEnableBankingItemsAndAccounts < ActiveRecord::Migration[7.2]
def change
# Create provider items table (stores per-family connection credentials)
create_table :enable_banking_items, id: :uuid do |t|
t.references :family, null: false, foreign_key: true, type: :uuid
t.string :name
# Institution metadata
t.string :institution_id
t.string :institution_name
t.string :institution_domain
t.string :institution_url
t.string :institution_color
# Status and lifecycle
t.string :status, default: "good"
t.boolean :scheduled_for_deletion, default: false
t.boolean :pending_account_setup, default: false
# Sync settings
t.datetime :sync_start_date
# Raw data storage
t.jsonb :raw_payload
t.jsonb :raw_institution_payload
# Provider-specific credential fields
t.string :country_code
t.string :application_id
t.text :client_certificate
# OAuth session fields
t.string :session_id
t.datetime :session_expires_at
t.string :aspsp_name # Bank/ASPSP name
t.string :aspsp_id # Bank/ASPSP identifier
# Authorization flow fields (temporary, cleared after session created)
t.string :authorization_id
t.timestamps
end
add_index :enable_banking_items, :status
# Create provider accounts table (stores individual account data from provider)
create_table :enable_banking_accounts, id: :uuid do |t|
t.references :enable_banking_item, null: false, foreign_key: true, type: :uuid
# Account identification
t.string :name
t.string :account_id
# Account details
t.string :currency
t.decimal :current_balance, precision: 19, scale: 4
t.string :account_status
t.string :account_type
t.string :provider
t.string :iban
t.string :uid # Enable Banking unique identifier
# Metadata and raw data
t.jsonb :institution_metadata
t.jsonb :raw_payload
t.jsonb :raw_transactions_payload
t.timestamps
end
add_index :enable_banking_accounts, :account_id
end
end

52
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[7.2].define(version: 2025_11_21_140453) do
ActiveRecord::Schema[7.2].define(version: 2025_11_26_094446) do
# These are extensions that must be enabled in order to support this database
enable_extension "pgcrypto"
enable_extension "plpgsql"
@@ -233,6 +233,54 @@ ActiveRecord::Schema[7.2].define(version: 2025_11_21_140453) do
t.string "subtype"
end
create_table "enable_banking_accounts", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.uuid "enable_banking_item_id", null: false
t.string "name"
t.string "account_id"
t.string "currency"
t.decimal "current_balance", precision: 19, scale: 4
t.string "account_status"
t.string "account_type"
t.string "provider"
t.string "iban"
t.string "uid"
t.jsonb "institution_metadata"
t.jsonb "raw_payload"
t.jsonb "raw_transactions_payload"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["account_id"], name: "index_enable_banking_accounts_on_account_id"
t.index ["enable_banking_item_id"], name: "index_enable_banking_accounts_on_enable_banking_item_id"
end
create_table "enable_banking_items", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.uuid "family_id", null: false
t.string "name"
t.string "institution_id"
t.string "institution_name"
t.string "institution_domain"
t.string "institution_url"
t.string "institution_color"
t.string "status", default: "good"
t.boolean "scheduled_for_deletion", default: false
t.boolean "pending_account_setup", default: false
t.datetime "sync_start_date"
t.jsonb "raw_payload"
t.jsonb "raw_institution_payload"
t.string "country_code"
t.string "application_id"
t.text "client_certificate"
t.string "session_id"
t.datetime "session_expires_at"
t.string "aspsp_name"
t.string "aspsp_id"
t.string "authorization_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["family_id"], name: "index_enable_banking_items_on_family_id"
t.index ["status"], name: "index_enable_banking_items_on_status"
end
create_table "entries", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.uuid "account_id", null: false
t.string "entryable_type"
@@ -1020,6 +1068,8 @@ ActiveRecord::Schema[7.2].define(version: 2025_11_21_140453) do
add_foreign_key "budgets", "families"
add_foreign_key "categories", "families"
add_foreign_key "chats", "users"
add_foreign_key "enable_banking_accounts", "enable_banking_items"
add_foreign_key "enable_banking_items", "families"
add_foreign_key "entries", "accounts", on_delete: :cascade
add_foreign_key "entries", "imports"
add_foreign_key "family_exports", "families"