- Python 75.3%
- HTML 13.7%
- JavaScript 11%
Auth + input-validation cluster (CODE-REVIEW-2026-06 #5, #6, #16, #17 + libra-#36, libra-#51, libra-#52): - can_access_user_data compares full user ids only. The 8-char prefix comparison was a 32-bit space: any prefix collision (or a crafted short target id) let one user read another's data. - can_access_account matches the User-{short} SEGMENT exactly; the substring test also matched accounts merely containing it (Expenses:Misc-User-deadbeef). - Manual-payment approve/reject are status-guarded (UPDATE ... WHERE status='pending' + rowcount): concurrent admins can't double-book. The approve endpoint claims the request BEFORE writing the ledger entry and reverts the claim if the write fails, so at most one journal entry can exist per request. - Account-name validation centralized into account_utils.validate_account_name (libra-#51) — called from crud.create_account (the choke point for every creation path, virtual parents allowed a bare root), the admin add-account endpoint, and fava_client.add_account at the writer boundary (libra-#52). - crud.create_account translates backend unique-violations into AccountExistsError instead of leaking sqlalchemy internals (libra-#36); POST /accounts returns 409 on duplicates and 400 on malformed names. get_or_create_user_account catches the domain error instead of string-matching the SQLite message (which never matched on Postgres). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|---|---|---|
| core | ||
| docs | ||
| helper | ||
| static | ||
| templates/libra | ||
| tests | ||
| .gitignore | ||
| __init__.py | ||
| account_sync.py | ||
| account_utils.py | ||
| auth.py | ||
| beancount_format.py | ||
| CLAUDE.md | ||
| config.json | ||
| crud.py | ||
| description.md | ||
| fava_client.py | ||
| manifest.json | ||
| MIGRATION_SQUASH_SUMMARY.md | ||
| migrations.py | ||
| migrations_old.py.bak | ||
| models.py | ||
| package.json | ||
| permission_management.py | ||
| README.md | ||
| services.py | ||
| tasks.py | ||
| views.py | ||
| views_api.py | ||
Libra Extension for LNbits
A full-featured double-entry accounting system for collective projects, integrated with LNbits Lightning payments.
Overview
Libra enables collectives like co-living spaces, makerspaces, and community projects to:
- Track expenses and revenue with proper accounting
- Manage individual member balances
- Record contributions as equity or reimbursable expenses
- Track accounts receivable (what members owe)
- Generate Lightning invoices for settlements
Installation
This extension is designed to be installed in the lnbits/extensions/ directory.
cd lnbits/extensions/
# Copy or clone the libra directory here
Enable the extension through the LNbits admin interface or by adding it to your configuration.
Usage
For Members
-
Add an Expense: Record money you spent on behalf of the collective
- Choose "Liability" if you want reimbursement
- Choose "Equity" if it's a contribution
-
View Your Balance: See if the collective owes you money or vice versa
-
Pay Outstanding Balance: Generate a Lightning invoice to settle what you owe
For Admins
-
Create Accounts Receivable: Record when someone owes the collective money
-
Record Revenue: Track income received by the collective
-
View All Transactions: See complete accounting history
-
Make Payments: Record payments to members
Architecture
Data Models
- Account: Individual accounts in the chart of accounts
- JournalEntry: Transaction header with description and date
- EntryLine: Individual debit/credit lines (always balanced)
Account Types
- Assets: Things the organization owns (Cash, Bank, Accounts Receivable)
- Liabilities: What the organization owes (Accounts Payable to members)
- Equity: Member contributions and retained earnings
- Revenue: Income streams
- Expenses: Operating costs
Database Schema
The extension creates three tables:
libra.accounts- Chart of accountslibra.journal_entries- Transaction headerslibra.entry_lines- Debit/credit lines
API Reference
See description.md for full API documentation.
Development
To modify this extension:
- Edit models in
models.py - Add database migrations in
migrations.py - Implement business logic in
crud.py - Create API endpoints in
views_api.py - Update UI in
templates/libra/index.html
Contributing
Contributions welcome! Please ensure:
- Journal entries always balance
- User permissions are properly checked
- Database transactions are atomic
License
MIT License - feel free to use and modify for your collective!