IMPROVEMENT use BQL to calculate balance #2
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
BQL Balance Queries Implementation
Date: November 10, 2025
Status: In Progress
Context: Replace manual aggregation with Beancount Query Language (BQL)
Problem
Current
get_user_balance()implementation:Performance Impact:
Solution: Use Beancount Query Language (BQL)
Beancount has a built-in query language that can efficiently:
BQL Query Design
Query 1: Get User Balance (SATS + Fiat)
What this does:
account ~ ':User-abc12345'- Match user's accounts (regex)account ~ 'Payable' OR account ~ 'Receivable'- Only payable/receivable accountsflag != '!'- Exclude pending transactionssum(position)- Aggregate balancesGROUP BY account- Separate totals per accountResult Format (from Fava API):
Query 2: Get All User Balances (Admin View)
What this does:
Implementation Plan
Step 1: Add General BQL Query Method
Add to
fava_client.py:Step 2: Implement BQL-Based Balance Query
Add to
fava_client.py:Step 3: Implement BQL-Based All Users Balance
Testing Strategy
Unit Tests
Integration Tests
Migration Strategy
Phase 1: Add BQL Methods (Non-Breaking)
query_bql()methodget_user_balance_bql()methodget_all_user_balances_bql()methodBenefit: Can test BQL in parallel without breaking existing code.
Phase 2: Switch to BQL (Breaking Change)
Rename old methods:
get_user_balance()→get_user_balance_manual()(deprecated)get_all_user_balances()→get_all_user_balances_manual()(deprecated)Rename new methods:
get_user_balance_bql()→get_user_balance()get_all_user_balances_bql()→get_all_user_balances()Update all call sites
Test thoroughly
Remove deprecated manual methods after 1-2 sprints
Expected Performance Improvements
Before (Manual Aggregation)
After (BQL)
Scalability
Manual approach:
BQL approach:
Code Reduction
Before:
get_user_balance()= 115 linesAfter:
get_user_balance_bql()= ~60 lines (with comments and error handling)Net reduction: 55 lines (~48%)
Before:
get_all_user_balances()= ~100 linesAfter:
get_all_user_balances_bql()= ~70 linesNet reduction: 30 lines (~30%)
Total code reduction: ~85 lines across balance query methods
Risks and Mitigation
Risk 1: BQL Query Syntax Errors
Mitigation:
Risk 2: Position Format Variations
Mitigation:
Risk 3: Regression in Balance Calculations
Mitigation:
Test Results and Findings
Date: November 10, 2025
Status: ⚠️ NOT FEASIBLE for Castle's Current Data Structure
Implementation Completed
query_bql()method (fava_client.py:494-547)get_user_balance_bql()method (fava_client.py:549-644)get_all_user_balances_bql()method (fava_client.py:646-747)Test Results
✅ BQL query execution works perfectly:
/queryendpointsum(position)❌ Cannot access SATS balances:
posting.meta["sats-equivalent"]Root Cause: Architecture Limitation
Current Castle Ledger Structure:
Test Data:
sats-equivalentmetadataBQL Limitation:
Why Manual Aggregation is Necessary
meta["sats-equivalent"]Performance: Cache Optimization is the Solution
Phase 1 Caching (Already Implemented) provides the performance boost:
BQL would not improve performance because:
Conclusion
Status: ⚠️ BQL Implementation Not Feasible
Recommendation: Keep manual aggregation method with Phase 1 caching
Rationale:
BQL Methods Status:
Future Consideration: Ledger Format Change
If Castle's ledger format changes to use SATS as position amounts:
Then BQL would become feasible:
Trade-offs of format change:
Recommendation: Consider during major version upgrade or architectural redesign.
Next Steps
query_bql()methodget_user_balance_bql()methodget_all_user_balances_bql()methodImplementation By: Claude Code
Date: November 10, 2025
Status: ✅ Tested and Documented | ⚠️ Not Feasible for Production Use