fd6c76f7ed42c08c810f1f49e6d8f06fab43e47c
Banks2FF
A robust command-line tool to synchronize bank transactions from GoCardless (formerly Nordigen) to Firefly III.
Architecture
This project is a Rust Workspace consisting of:
banks2ff: The main CLI application (Hexagonal Architecture).gocardless-client: A hand-crafted, strongly-typed library for the GoCardless Bank Account Data API.firefly-client: A hand-crafted, strongly-typed library for the Firefly III API.
Features
- Multi-Currency Support: Correctly handles foreign currency transactions by extracting exchange rate data.
- Idempotency (Healer Mode):
- Detects duplicates using a windowed search (Date +/- 3 days, exact Amount).
- "Heals" historical transactions by updating them with the correct
external_id. - Skips transactions that already have a matching
external_id.
- Clean Architecture: Decoupled core logic makes it reliable and testable.
- Observability: Structured logging via
tracing. - Dry Run: Preview changes without writing to Firefly III.
- Rate Limit Protection:
- Caches GoCardless account details to avoid unnecessary calls.
- Respects token expiry to minimize auth calls.
- Handles
429 Too Many Requestsgracefully by skipping affected accounts.
Setup & Configuration
-
Prerequisites:
- Rust (latest stable)
- An account with GoCardless Bank Account Data (get your
secret_idandsecret_key). - A running Firefly III instance (get your Personal Access Token).
-
Environment Variables: Copy
env.exampleto.envand fill in your details:cp env.example .envRequired variables:
GOCARDLESS_ID: Your GoCardless Secret ID.GOCARDLESS_KEY: Your GoCardless Secret Key.FIREFLY_III_URL: The base URL of your Firefly instance (e.g.,https://money.example.com).FIREFLY_III_API_KEY: Your Personal Access Token.
Optional:
GOCARDLESS_URL: Defaults tohttps://bankaccountdata.gocardless.com.RUST_LOG: Set log level (e.g.,info,debug,trace).
Testing
The project has a comprehensive test suite using wiremock for API clients and mockall for core logic.
To run all tests:
cargo test --workspace
Usage
To run the synchronization:
# Run via cargo (defaults: Start = Last Firefly Date + 1, End = Yesterday)
cargo run -p banks2ff
# Dry Run (Read-only)
cargo run -p banks2ff -- --dry-run
# Custom Date Range
cargo run -p banks2ff -- --start 2023-01-01 --end 2023-01-31
How it works
- Fetch: Retrieves active accounts from GoCardless (filtered by those present in Firefly III to save requests).
- Match: Resolves the destination account in Firefly III by matching the IBAN.
- Sync Window: Determines the start date automatically by finding the latest transaction in Firefly for that account.
- Process: For each transaction:
- Search: Checks Firefly for an existing transaction (matching Amount and Date +/- 3 days).
- Heal: If found but missing an
external_id, it updates the transaction. - Skip: If found and matches
external_id, it skips. - Create: If not found, it creates a new transaction.
Description
Languages
Rust
100%