Implements metadata-only accounts (e.g., "Expenses", "Assets") that exist
solely in Castle DB for hierarchical permission management. These accounts
don't exist in Beancount but cascade permissions to all child accounts.
Changes:
**Migration (m003)**:
- Add `is_virtual` BOOLEAN field to accounts table
- Create index idx_accounts_is_virtual
- Insert 5 default virtual parents: Assets, Liabilities, Equity, Income, Expenses
**Models**:
- Add `is_virtual: bool = False` to Account, CreateAccount, AccountWithPermissions
**CRUD**:
- Update create_account() to pass is_virtual to Account constructor
**Account Sync**:
- Skip deactivating virtual accounts (they're intentionally metadata-only)
- Virtual accounts never get marked as inactive by sync
**Use Case**:
Admin grants permission on virtual "Expenses" account → user automatically
gets access to ALL real expense accounts:
- Expenses:Groceries
- Expenses:Gas:Kitchen
- Expenses:Maintenance:Property
- (and all other Expenses:* children)
This solves the limitation where Beancount doesn't allow single-level accounts
(e.g., bare "Expenses" can't exist in ledger), but admins need a way to grant
broad access without manually selecting dozens of accounts.
Hierarchical permission inheritance already works via account_name.startswith()
check - virtual accounts simply provide the parent nodes to grant permissions on.
🤖 Generated with Claude Code (https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
New Features:
- BulkGrantPermission model: Grant same permission to multiple users
- BulkGrantResult model: Detailed success/failure results
- POST /api/v1/admin/permissions/bulk-grant endpoint
This simplifies the admin workflow for granting the same account
permission to multiple users at once (e.g., onboarding a team).
The endpoint validates the account exists and is active, then grants
the permission to each user, collecting successes and failures to
return a detailed result.
Related: UI-IMPROVEMENTS-PLAN.md Phase 1
- Migration m002: Add is_active column to castle_accounts table
- Updated Account and AccountWithPermissions models with is_active field
- Default value: TRUE (all existing accounts remain active)
- Index added for performance on is_active queries
Next steps (to be completed):
- Update account sync to mark orphaned accounts as inactive
- Filter inactive accounts in get_all_accounts queries
- Prevent permissions from being granted on inactive accounts
- Add API endpoint to list/reactivate orphaned accounts
This implements soft delete strategy where accounts removed from
Beancount are marked inactive rather than deleted, preserving
historical data and permissions while preventing new activity.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Updates journal entry flags to align with Beancount's limited flag support.
Beancount only uses cleared (*) and pending (!) flags.
Removes the VOID and FLAGGED flags and recommends using tags instead
(e.g., "! + #voided" for voided entries, "! + #review" for flagged entries).
Updates the API to reflect this change, removing the ability to directly
"reject" an expense entry via the void flag. Instead, instructs users to
add the #voided tag in Fava.
Updates reconciliation summary to count entries with voided/review tags
instead of voided/flagged flags.
Refactors account balance retrieval to fetch data from Fava/Beancount
for improved accounting accuracy.
Updates user balance retrieval to use Fava/Beancount data source.
Updates Castle settings ledger slug name.
Adds settings to the Castle extension for integration
with a Fava/Beancount accounting system. This enables
all accounting operations to be managed through Fava.
It includes settings for the Fava URL, ledger slug,
and request timeout.
Refactors the data model to use a single 'amount' field for journal entry lines, aligning with the Beancount approach.
This simplifies the model, enhances compatibility, and eliminates invalid states.
Includes a database migration to convert existing debit/credit columns to the new 'amount' field.
Updates balance calculation logic to utilize the new amount field for improved accuracy and efficiency.
Adds a comment to the `equity_account_name` field in the
`CreateUserEquityStatus` model, clarifying that it is
auto-generated if not provided.
This improves clarity for developers using the API.
Adds an account permissioning system to allow granular control over account access.
Introduces the ability to grant users specific permissions (read, submit_expense, manage) on individual accounts. This includes support for hierarchical permission inheritance, where permissions on parent accounts cascade to child accounts.
Adds new API endpoints for managing account permissions, including granting, listing, and revoking permissions.
Integrates permission checks into existing endpoints, such as creating expense entries, to ensure that users only have access to the accounts they are authorized to use.
Fixes#33 - Implements role based access control
Implements functionality to manage user equity eligibility, allowing admins to grant and revoke access.
Adds database migration, models, CRUD operations, and API endpoints for managing user equity status.
This feature enables finer-grained control over who can convert expenses to equity contributions.
Validates a user's eligibility before allowing them to submit expenses as equity.
Adds support for on-chain Bitcoin payments by:
- Introducing a new `Assets:Bitcoin:OnChain` account.
- Updating the `SettleReceivable` and `PayUser` models to include `txid` for storing transaction IDs.
- Modifying the API endpoints to handle `btc_onchain` as a valid payment method and associate it with the new account.
This allows tracking on-chain Bitcoin transactions separately from Lightning Network payments.
Adds a date field to expense entries for better tracking and reporting.
This allows users to specify the date of the expense transaction,
providing more accurate financial records.
Implements the ability for the super user (Castle) to pay other users for expenses or liabilities.
Introduces a new `PayUser` model to represent these payments, along with API endpoints to process and record them.
Integrates a "Pay User" button into the user list, allowing the super user to initiate payments through either lightning or manual methods (cash, bank transfer, check).
Adds UI elements and logic for handling both lightning payments (generating invoices and paying them) and manual payment recording.
This functionality allows Castle to manage and settle debts with its users directly through the application.
Adds support for settling receivables with fiat currencies
like EUR and USD, in addition to sats.
Updates the settlement dialog to handle fiat amounts and
exchange rates, defaulting to cash payment when a fiat balance
exists.
Modifies the API to accept currency and amount_sats parameters
and adjust the journal entry accordingly, converting the fiat amount
to minor units (e.g., cents) for accounting purposes.
Allows administrators to generate payment invoices on behalf of specific users.
This is useful for handling settlement invoices in certain scenarios.
The changes include:
- Adding a `user_id` field to the generate payment invoice request model
- Updating the API endpoint to accept the `user_id` parameter
- Implementing checks to ensure only superusers can generate invoices for other users
- Updating the memo and extra data to reflect the target user
Implements a "Settle Receivable" feature for super users to record manual payments from users who owe money.
Introduces a dialog for inputting payment details (amount, method, description, reference), triggers an API call to record the transaction, and updates user balances and transaction history.
This is for non-lightning payments like cash, bank transfers, or checks.
Adds balance assertion functionality to enable admins to verify accounting accuracy.
This includes:
- A new `balance_assertions` table in the database
- CRUD operations for balance assertions (create, get, list, check, delete)
- API endpoints for managing balance assertions (admin only)
- UI elements for creating, viewing, and re-checking assertions
Also, reorders the implementation roadmap in the documentation to reflect better the dependencies between phases.
Implements core improvements from Phase 1 of the Beancount patterns adoption:
- Uses Decimal for fiat amounts to prevent floating point errors
- Adds a meta field to journal entries for a full audit trail
- Adds a flag field to journal entries for transaction status
- Migrates existing account names to a hierarchical format
This commit introduces a database migration to add the `flag` and `meta` columns to the `journal_entries` table. It also includes updates to the models, CRUD operations, and API endpoints to handle the new fields.
Extends user balance information to include fiat currency balances,
calculated based on entry line metadata and account types.
This allows for a more comprehensive view of user balances,
including both satoshi and fiat currency holdings.
Updates the castle index template and API to display fiat balances.
Adds functionality for users to pay their Castle balance by generating and paying a Lightning invoice.
This includes:
- Adding API endpoints for invoice generation and payment recording.
- Updating the frontend to allow users to initiate the invoice payment process.
- Passing the wallet's `inkey` to the frontend for payment status checks.
Implements a feature that allows users to pay their outstanding balance via Lightning.
The changes include:
- Adds the UI elements for invoice generation and display, including QR code.
- Integrates backend endpoints to generate and record payments.
- Adds polling mechanism to track payments and update balance.
- Creates new database models to support manual payment requests.
Updates the receivable entry model and related API endpoints to use the user's ID instead of the user's wallet ID.
This change simplifies user identification and ensures consistency throughout the application.
Allows users to configure their own wallet ID, enabling
the system to track expenses and receivables on a per-user basis.
Introduces new database table, models, API endpoints, and UI elements
to manage user-specific wallet settings.
Adds functionality to configure the Castle extension, including a wallet ID.
This allows administrators to customize the extension's behavior by specifying a dedicated wallet for castle operations.
Extends expense entry functionality to support fiat currencies.
Users can now specify a currency (e.g., EUR, USD) when creating expense entries. The specified amount is converted to satoshis using exchange rates. The converted amount and currency information are stored in the journal entry metadata. Also adds an API endpoint to retrieve allowed currencies and updates the UI to allow currency selection when creating expense entries.