No description
  • Python 75.3%
  • HTML 13.7%
  • JavaScript 11%
Find a file
Padreug ec6cac51f0 chore: hygiene sweep — dead code, role race, user lookup, stale files
One pass over the LOW-tier review items plus two folded issues:

- Delete validate_journal_entry (dead since the Fava migration; it
  validated the pre-string-amount model) with its exports, unused
  crud imports, and tests. Beancount validates entries now.
- Migration m006: UNIQUE index on user_roles(user_id, role_id) after
  deduping; assign_user_role inserts with ON CONFLICT DO NOTHING and
  returns the existing assignment — closes the auto-assign
  check-then-act race on concurrent logins.
- Extract _get_username_from_user_id (110 lines in views_api, fresh
  LNbits Database per call inside per-row hot paths) into
  user_lookup.py with one shared core-DB handle, a 60s TTL cache and
  a batch get_usernames API (review #18).
- Receivable-entry responses report CLEARED, matching the flag the
  formatter actually writes; PENDING misled the UI (libra-#35).
- Replace the remaining print() calls in tasks.py with logger.
- get_all_accounts derives valid roots from
  account_utils.ACCOUNT_TYPE_ROOTS instead of a hardcoded tuple, and
  the no-op per-test rate-limit reset is gone (libra-#54).
- Delete migrations_old.py.bak, MIGRATION_SQUASH_SUMMARY.md,
  docs/PHASE*_COMPLETE.md and the rendered .html; .gitignore data/
  (it holds the runtime .lnbits_auth_key secret).
- Track docs/CODE-REVIEW-2026-06.md with finding statuses updated for
  the PR #55-#59 + chore/hygiene series.
- CLAUDE.md notes LNbits pins Pydantic v1: keep .dict(), don't
  "modernize" to .model_dump().

Note: format_payment_entry's is_payable docstring (flagged in review
follow-up) turned out to be consistent with the body — no change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 16:01:34 +02:00
core chore: hygiene sweep — dead code, role race, user lookup, stale files 2026-07-12 16:01:34 +02:00
docs chore: hygiene sweep — dead code, role race, user lookup, stale files 2026-07-12 16:01:34 +02:00
helper Clean up awkward "the Libra" phrasing left over from rename 2026-05-07 08:37:30 +02:00
static feat(accounts): validate account-name characters server-side 2026-06-16 22:55:45 +02:00
templates/libra feat(ui): constrain add-account to a root-type dropdown + sub-path 2026-06-16 01:15:06 +02:00
tests chore: hygiene sweep — dead code, role race, user lookup, stale files 2026-07-12 16:01:34 +02:00
.gitignore chore: hygiene sweep — dead code, role race, user lookup, stale files 2026-07-12 16:01:34 +02:00
__init__.py fix(fava): serialize source mutations, share HTTP client, validate BQL input 2026-07-12 15:42:44 +02:00
account_sync.py fix(fava): serialize source mutations, share HTTP client, validate BQL input 2026-07-12 15:42:44 +02:00
account_utils.py fix(auth): exact-match authorization; guard reviews; centralize name validation 2026-07-12 15:52:29 +02:00
auth.py fix(auth): exact-match authorization; guard reviews; centralize name validation 2026-07-12 15:52:29 +02:00
beancount_format.py fix(assertions): send Balance directives in Fava's JSON shape (libra-#39) 2026-07-12 15:42:44 +02:00
CLAUDE.md chore: hygiene sweep — dead code, role race, user lookup, stale files 2026-07-12 16:01:34 +02:00
config.json Rename Castle Accounting extension to Libra 2026-05-05 10:24:46 +02:00
crud.py chore: hygiene sweep — dead code, role race, user lookup, stale files 2026-07-12 16:01:34 +02:00
description.md Clean up awkward "the Libra" phrasing left over from rename 2026-05-07 08:37:30 +02:00
fava_client.py chore: hygiene sweep — dead code, role race, user lookup, stale files 2026-07-12 16:01:34 +02:00
manifest.json Rename Castle Accounting extension to Libra 2026-05-05 10:24:46 +02:00
migrations.py chore: hygiene sweep — dead code, role race, user lookup, stale files 2026-07-12 16:01:34 +02:00
models.py fix(accounts): default CreateChartAccount.currencies to None 2026-06-15 23:53:04 +02:00
package.json Rename Castle Accounting extension to Libra 2026-05-05 10:24:46 +02:00
permission_management.py Rename Castle Accounting extension to Libra 2026-05-05 10:24:46 +02:00
README.md Clean up awkward "the Libra" phrasing left over from rename 2026-05-07 08:37:30 +02:00
services.py Rename Castle Accounting extension to Libra 2026-05-05 10:24:46 +02:00
tasks.py chore: hygiene sweep — dead code, role race, user lookup, stale files 2026-07-12 16:01:34 +02:00
user_lookup.py chore: hygiene sweep — dead code, role race, user lookup, stale files 2026-07-12 16:01:34 +02:00
views.py Rename Castle Accounting extension to Libra 2026-05-05 10:24:46 +02:00
views_api.py chore: hygiene sweep — dead code, role race, user lookup, stale files 2026-07-12 16:01:34 +02:00

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

  1. 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
  2. View Your Balance: See if the collective owes you money or vice versa

  3. Pay Outstanding Balance: Generate a Lightning invoice to settle what you owe

For Admins

  1. Create Accounts Receivable: Record when someone owes the collective money

  2. Record Revenue: Track income received by the collective

  3. View All Transactions: See complete accounting history

  4. 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 accounts
  • libra.journal_entries - Transaction headers
  • libra.entry_lines - Debit/credit lines

API Reference

See description.md for full API documentation.

Development

To modify this extension:

  1. Edit models in models.py
  2. Add database migrations in migrations.py
  3. Implement business logic in crud.py
  4. Create API endpoints in views_api.py
  5. 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!