Skip to content

feat(bank-connectors): pluggable architecture for bank integrations#653

Open
sungdark wants to merge 2 commits intorohitdash08:mainfrom
sungdark:feature/pluggable-bank-connectors
Open

feat(bank-connectors): pluggable architecture for bank integrations#653
sungdark wants to merge 2 commits intorohitdash08:mainfrom
sungdark:feature/pluggable-bank-connectors

Conversation

@sungdark
Copy link

Summary

Implements a pluggable bank connector architecture for FinMind, fulfilling all acceptance criteria from Issue #75:

✅ Acceptance Criteria Met

  1. Connector interface — Abstract BankConnector base class (base.py) defining the full contract:

    • get_auth_status() — verify credentials
    • list_accounts() — enumerate linked accounts
    • get_transactions() — fetch transaction history
    • refresh() — incremental refresh (new transactions only)
    • normalize_transactions() — hook for connector-specific normalization
  2. Import & refresh support — Full implementation via BankConnectionService:

    • POST /bank-connections/connections/{id}/import — full import with dry_run, date range filtering, per-account or all accounts
    • POST /bank-connections/connections/{id}/refresh — incremental refresh returning only new transactions since last import
    • Deduplication against existing expenses
  3. Mock connector includedMockBankConnector (mock.py) for development/testing:

    • Deterministic transaction generation (configurable via seed)
    • default, empty, and error modes for testing all code paths
    • Realistic transaction data (merchants, amounts, types)

Architecture

packages/backend/app/services/bank_connectors/
├── __init__.py       # Public exports, auto-registers MockBankConnector
├── base.py           # BankConnector ABC, Transaction, Account, ConnectorError
├── registry.py       # ConnectorRegistry singleton (pluggable factory)
├── mock.py           # MockBankConnector implementation
└── service.py        # BankConnectionService (orchestration + DB persistence)

packages/backend/app/routes/bank_connections.py  # REST API endpoints
packages/backend/app/models.py                   # BankConnection, BankConnectionAccount, BankImportRun
packages/backend/app/db/schema.sql              # PostgreSQL schema for new tables

Key Design Decisions

  • Pluggable factory pattern via ConnectorRegistry — new connectors register with a name and factory function; no code changes needed to core files
  • Connector-agnostic normalizationnormalize_transactions() delegates to the existing expense_import pipeline so all connectors benefit from existing deduplication, date parsing, etc.
  • Encrypted config storage — Per-user connector credentials stored encrypted in config_encrypted TEXT (placeholder implementation; production should use KMS/Vault)
  • Import run trackingBankImportRun table records every import for audit/debugging

Payment

Bounty: $500 — Issue #75

Payment preference: PayPal (or GitHub Sponsors). Please share PayPal email or payment instructions.

bounty-scout and others added 2 commits March 26, 2026 14:44
Implements signed webhook delivery for key events with HMAC-SHA256
signatures, retry support, and comprehensive event documentation.

Features:
- Signed delivery using HMAC-SHA256 (X-Webhook-Signature header)
- Replay attack protection via timestamp validation (5min window)
- Automatic retry with exponential backoff (1min, 5min, 15min)
- Webhook subscription management API (CRUD)
- Event types documented in service docstring

Event types:
- expense.created
- expense.updated
- expense.deleted
- bill.due
- reminder.sent

Signed-off-by: Claude <noreply@anthropic.com>
Implements a pluggable bank connector architecture for FinMind with:

- BankConnector abstract interface defining the connector contract
  - get_auth_status, list_accounts, get_transactions, refresh methods
  - Transaction, Account, ConnectorAuthStatus data models
  - ConnectorError hierarchy (AuthenticationError, RateLimitError, etc.)

- ConnectorRegistry for managing pluggable connectors
  - Auto-registers built-in MockBankConnector
  - Thread-safe factory pattern for adding new connectors

- MockBankConnector for development and testing
  - Generates realistic deterministic transaction data
  - Supports default/empty/error modes
  - Implements full connector interface

- BankConnectionService for orchestrating connections
  - connect(), disconnect(), list_connections() lifecycle
  - import_transactions() and refresh_transactions() for syncing
  - Manages encrypted per-user connector configs
  - Integrates with existing expense_import normalization pipeline

- BankConnection, BankConnectionAccount, BankImportRun SQLAlchemy models
  - Persisted in PostgreSQL with proper FK relationships

- REST API endpoints under /bank-connections
  - GET /connectors - list available connectors
  - POST /connections - create connection
  - GET/DELETE /connections/{id}
  - POST /connections/{id}/import - full import with dry_run support
  - POST /connections/{id}/refresh - incremental refresh
  - GET /connections/{id}/accounts
  - GET /connections/{id}/import-runs

- 23 passing unit tests for connector interface and registry

Bounty: $500 - Issue rohitdash08#75
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant