Handle expired agreements and rewrite README

- Implement robust End User Agreement expiry detection and handling
- Add graceful error recovery for failed accounts
- Rewrite README.md to focus on user benefits
- Add documentation guidelines to AGENTS.md
This commit is contained in:
2025-11-21 17:04:31 +01:00
parent a4fcea1afe
commit 74d362b412
13 changed files with 362 additions and 183 deletions

View File

@@ -58,16 +58,19 @@ Both clients are hand-crafted using `reqwest`:
## Synchronization Process
The "Healer" strategy ensures idempotency:
The "Healer" strategy ensures idempotency with robust error handling:
1. **Account Discovery**: Fetch active accounts from GoCardless
2. **Account Matching**: Match GoCardless accounts to Firefly asset accounts by IBAN
3. **Date Window**: Calculate sync range (Last Firefly transaction + 1 to Yesterday)
4. **Transaction Processing**:
1. **Account Discovery**: Fetch active accounts from GoCardless (filtered by End User Agreement (EUA) validity)
2. **Agreement Validation**: Check EUA expiry status for each account's requisition
3. **Account Matching**: Match GoCardless accounts to Firefly asset accounts by IBAN
4. **Error-Aware Processing**: Continue with valid accounts when some have expired agreements
5. **Date Window**: Calculate sync range (Last Firefly transaction + 1 to Yesterday)
6. **Transaction Processing** (with error recovery):
- **Search**: Look for existing transaction using windowed heuristic (date ± 3 days, exact amount)
- **Heal**: If found without `external_id`, update with GoCardless transaction ID
- **Skip**: If found with matching `external_id`, ignore
- **Create**: If not found, create new transaction in Firefly
- **Error Handling**: Log issues but continue with other transactions/accounts
## Key Features
@@ -81,6 +84,13 @@ The "Healer" strategy ensures idempotency:
- **Token Reuse**: Maintains tokens until expiry to minimize auth requests
- **Graceful Handling**: Continues sync for other accounts when encountering 429 errors
### Agreement Expiry Handling
- **Proactive Validation**: Checks End User Agreement (EUA) expiry before making API calls to avoid unnecessary requests
- **Reactive Recovery**: Detects expired agreements from API 401 errors and skips affected accounts
- **Continued Operation**: Maintains partial sync success even when some accounts are inaccessible
- **User Feedback**: Provides detailed reporting on account status and re-authorization needs
- **Multiple Requisitions**: Supports accounts linked to multiple requisitions, using the most recent valid one
### Idempotency
- GoCardless `transactionId` → Firefly `external_id` mapping
- Windowed duplicate detection prevents double-creation
@@ -101,10 +111,11 @@ GoCardless API → GoCardlessAdapter → TransactionSource → SyncEngine → Tr
## Error Handling
- **Custom Errors**: `thiserror` for domain-specific error types
- **Custom Errors**: `thiserror` for domain-specific error types including End User Agreement (EUA) expiry (`SyncError::AgreementExpired`)
- **Propagation**: `anyhow` for error context across async boundaries
- **Graceful Degradation**: Rate limits and network issues don't crash entire sync
- **Structured Logging**: `tracing` for observability and debugging
- **Graceful Degradation**: Rate limits, network issues, and expired agreements don't crash entire sync
- **Partial Success**: Continues processing available accounts when some fail
- **Structured Logging**: `tracing` for observability and debugging with account-level context
## Configuration Management