Rename Castle Accounting extension to Libra
Full identifier rename: module path lnbits.extensions.castle →
lnbits.extensions.libra, DB ext_castle → ext_libra, URL prefix
/castle/ → /libra/, manifest id castle → libra, fava ledger slug
default castle-ledger → libra-ledger, Beancount source metadata
castle-api → libra-api and link prefixes castle-{entry,tx}- →
libra-{entry,tx}-, column castle_wallet_id → libra_wallet_id, all
Python/JS/HTML identifiers (castle_ext, CastleSettings,
castle_reference, castleWalletConfigured, etc.).
Display name "Castle Accounting" → "Libra" (the scales/balance
metaphor — fits double-entry bookkeeping).
No backward compat: production hosts will be force-updated. Old
castle-prefixed Beancount metadata in existing Fava ledgers is
historical; new entries use libra-* prefixes going forward.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9c577c740c
commit
c174cda48d
44 changed files with 953 additions and 953 deletions
|
|
@ -21,13 +21,13 @@ Phase 3 of the Beancount-inspired refactor focused on **separating business logi
|
|||
- Easier to audit and verify
|
||||
- Clear architecture
|
||||
|
||||
### 2. CastleInventory for Position Tracking ✅
|
||||
### 2. LibraInventory for Position Tracking ✅
|
||||
|
||||
**Purpose**: Track balances across multiple currencies with cost basis information (following Beancount's Inventory pattern)
|
||||
|
||||
**Implementation** (`core/inventory.py`):
|
||||
|
||||
**CastlePosition** (Lines 11-84):
|
||||
**LibraPosition** (Lines 11-84):
|
||||
- Immutable dataclass representing a single position
|
||||
- Tracks currency, amount, cost basis, and metadata
|
||||
- Supports addition and negation operations
|
||||
|
|
@ -35,7 +35,7 @@ Phase 3 of the Beancount-inspired refactor focused on **separating business logi
|
|||
|
||||
```python
|
||||
@dataclass(frozen=True)
|
||||
class CastlePosition:
|
||||
class LibraPosition:
|
||||
currency: str # "SATS", "EUR", "USD"
|
||||
amount: Decimal
|
||||
cost_currency: Optional[str] = None
|
||||
|
|
@ -44,7 +44,7 @@ class CastlePosition:
|
|||
metadata: Dict[str, Any] = field(default_factory=dict)
|
||||
```
|
||||
|
||||
**CastleInventory** (Lines 87-201):
|
||||
**LibraInventory** (Lines 87-201):
|
||||
- Container for multiple positions
|
||||
- Positions keyed by `(currency, cost_currency)` tuple
|
||||
- Methods for querying balances:
|
||||
|
|
@ -83,7 +83,7 @@ class AccountType(str, Enum):
|
|||
- Liabilities/Equity/Revenue: Credit balance (credit - debit)
|
||||
|
||||
2. **`build_inventory_from_entry_lines()`** (Lines 56-117):
|
||||
- Build CastleInventory from journal entry lines
|
||||
- Build LibraInventory from journal entry lines
|
||||
- Handles both sats and fiat currency tracking
|
||||
- Accounts for account type when determining sign
|
||||
|
||||
|
|
@ -123,7 +123,7 @@ class AccountType(str, Enum):
|
|||
- Checks both sats and fiat within tolerance
|
||||
|
||||
3. **`validate_receivable_entry()`** (Lines 180-199):
|
||||
- Validates receivable (user owes castle) entries
|
||||
- Validates receivable (user owes libra) entries
|
||||
- Ensures positive amount
|
||||
- Ensures revenue account type
|
||||
|
||||
|
|
@ -216,10 +216,10 @@ views_api.py → crud.py → core/
|
|||
## File Structure
|
||||
|
||||
```
|
||||
lnbits/extensions/castle/
|
||||
lnbits/extensions/libra/
|
||||
├── core/
|
||||
│ ├── __init__.py # Module exports
|
||||
│ ├── inventory.py # CastleInventory, CastlePosition
|
||||
│ ├── inventory.py # LibraInventory, LibraPosition
|
||||
│ ├── balance.py # BalanceCalculator
|
||||
│ └── validation.py # Validation functions
|
||||
├── crud.py # DB operations (refactored to use core/)
|
||||
|
|
@ -230,22 +230,22 @@ lnbits/extensions/castle/
|
|||
|
||||
## Usage Examples
|
||||
|
||||
### Using CastleInventory
|
||||
### Using LibraInventory
|
||||
|
||||
```python
|
||||
from decimal import Decimal
|
||||
from castle.core.inventory import CastleInventory, CastlePosition
|
||||
from libra.core.inventory import LibraInventory, LibraPosition
|
||||
|
||||
# Create inventory
|
||||
inv = CastleInventory()
|
||||
inv = LibraInventory()
|
||||
|
||||
# Add positions
|
||||
inv.add_position(CastlePosition(
|
||||
inv.add_position(LibraPosition(
|
||||
currency="SATS",
|
||||
amount=Decimal("100000")
|
||||
))
|
||||
|
||||
inv.add_position(CastlePosition(
|
||||
inv.add_position(LibraPosition(
|
||||
currency="SATS",
|
||||
amount=Decimal("50000"),
|
||||
cost_currency="EUR",
|
||||
|
|
@ -264,7 +264,7 @@ data = inv.to_dict()
|
|||
### Using BalanceCalculator
|
||||
|
||||
```python
|
||||
from castle.core.balance import BalanceCalculator, AccountType
|
||||
from libra.core.balance import BalanceCalculator, AccountType
|
||||
|
||||
# Calculate account balance
|
||||
balance = BalanceCalculator.calculate_account_balance(
|
||||
|
|
@ -297,7 +297,7 @@ is_valid = BalanceCalculator.check_balance_matches(
|
|||
### Using Validation
|
||||
|
||||
```python
|
||||
from castle.core.validation import validate_journal_entry, ValidationError
|
||||
from libra.core.validation import validate_journal_entry, ValidationError
|
||||
|
||||
entry = {
|
||||
"id": "abc123",
|
||||
|
|
@ -320,8 +320,8 @@ except ValidationError as e:
|
|||
|
||||
## Testing Checklist
|
||||
|
||||
- [x] CastleInventory created and tested
|
||||
- [x] CastlePosition addition works
|
||||
- [x] LibraInventory created and tested
|
||||
- [x] LibraPosition addition works
|
||||
- [x] Inventory balance calculations work
|
||||
- [x] BalanceCalculator account balance calculation works
|
||||
- [x] BalanceCalculator inventory building works
|
||||
|
|
@ -348,10 +348,10 @@ except ValidationError as e:
|
|||
|
||||
## Conclusion
|
||||
|
||||
Phase 3 successfully refactors Castle's accounting logic into a clean, testable core module. By following Beancount's architecture patterns, we've created:
|
||||
Phase 3 successfully refactors Libra's accounting logic into a clean, testable core module. By following Beancount's architecture patterns, we've created:
|
||||
|
||||
- **Pure accounting logic** separated from database concerns
|
||||
- **CastleInventory** for position tracking across currencies
|
||||
- **LibraInventory** for position tracking across currencies
|
||||
- **BalanceCalculator** for consistent balance calculations
|
||||
- **Comprehensive validation** for data integrity
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue