86 lines
3.1 KiB
Markdown
86 lines
3.1 KiB
Markdown
# 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.
|