# 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 Requests` gracefully by skipping affected accounts. ## Setup & Configuration 1. **Prerequisites**: - Rust (latest stable) - An account with GoCardless Bank Account Data (get your `secret_id` and `secret_key`). - A running Firefly III instance (get your Personal Access Token). 2. **Environment Variables**: Copy `env.example` to `.env` and fill in your details: ```bash cp env.example .env ``` Required 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 to `https://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: ```bash cargo test --workspace ``` ## Usage To run the synchronization: ```bash # 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 1. **Fetch**: Retrieves active accounts from GoCardless (filtered by those present in Firefly III to save requests). 2. **Match**: Resolves the destination account in Firefly III by matching the IBAN. 3. **Sync Window**: Determines the start date automatically by finding the latest transaction in Firefly for that account. 4. **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.