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:
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user