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:
Padreug 2026-05-05 10:24:46 +02:00
commit c174cda48d
44 changed files with 953 additions and 953 deletions

View file

@ -3,7 +3,7 @@
{% block scripts %}
{{ window_vars(user) }}
<script src="{{ static_url_for('castle/static', path='js/index.js') }}"></script>
<script src="{{ static_url_for('libra/static', path='js/index.js') }}"></script>
{% endblock %}
{% block page %}
@ -13,7 +13,7 @@
<q-card-section>
<div class="row items-center no-wrap">
<div class="col">
<h5 class="q-my-none">🏰 Castle Accounting</h5>
<h5 class="q-my-none">Libra</h5>
<p class="q-mb-none">Track expenses, receivables, and balances for the collective</p>
</div>
<div class="col-auto q-gutter-xs">
@ -21,14 +21,14 @@
<q-btn v-if="settingsLoaded && !isSuperUser" flat round icon="account_balance_wallet" @click="showUserWalletDialog">
<q-tooltip>Configure Your Wallet</q-tooltip>
</q-btn>
<q-btn v-if="settingsLoaded && isSuperUser" flat round icon="admin_panel_settings" :href="'/castle/permissions'">
<q-btn v-if="settingsLoaded && isSuperUser" flat round icon="admin_panel_settings" :href="'/libra/permissions'">
<q-tooltip>Manage Permissions (Admin)</q-tooltip>
</q-btn>
<q-btn v-if="settingsLoaded && isSuperUser" flat round icon="sync" :loading="syncingAccounts" @click="syncAccounts">
<q-tooltip>Sync Accounts from Beancount</q-tooltip>
</q-btn>
<q-btn v-if="settingsLoaded && isSuperUser" flat round icon="settings" @click="showSettingsDialog">
<q-tooltip>Castle Settings (Super User Only)</q-tooltip>
<q-tooltip>Libra Settings (Super User Only)</q-tooltip>
</q-btn>
</div>
</div>
@ -36,19 +36,19 @@
</q-card>
<!-- Setup Warning -->
<q-banner v-if="settingsLoaded && !castleWalletConfigured && isSuperUser" class="bg-warning text-white" rounded>
<q-banner v-if="settingsLoaded && !libraWalletConfigured && isSuperUser" class="bg-warning text-white" rounded>
<template v-slot:avatar>
<q-icon name="warning" color="white"></q-icon>
</template>
<div>
<strong>Setup Required:</strong> Castle Wallet ID must be configured before the extension can function.
<strong>Setup Required:</strong> Libra Wallet ID must be configured before the extension can function.
</div>
<template v-slot:action>
<q-btn flat color="white" label="Configure Now" @click="showSettingsDialog"></q-btn>
</template>
</q-banner>
<q-banner v-if="settingsLoaded && !castleWalletConfigured && !isSuperUser" class="bg-info text-white" rounded>
<q-banner v-if="settingsLoaded && !libraWalletConfigured && !isSuperUser" class="bg-info text-white" rounded>
<template v-slot:avatar>
<q-icon name="info" color="white"></q-icon>
</template>
@ -57,7 +57,7 @@
</div>
</q-banner>
<q-banner v-if="settingsLoaded && castleWalletConfigured && !userWalletConfigured && !isSuperUser" class="bg-orange text-white" rounded>
<q-banner v-if="settingsLoaded && libraWalletConfigured && !userWalletConfigured && !isSuperUser" class="bg-orange text-white" rounded>
<template v-slot:avatar>
<q-icon name="account_balance_wallet" color="white"></q-icon>
</template>
@ -131,13 +131,13 @@
<q-btn
color="primary"
@click="expenseDialog.show = true"
:disable="!castleWalletConfigured || (!userWalletConfigured && !isSuperUser)"
:disable="!libraWalletConfigured || (!userWalletConfigured && !isSuperUser)"
>
Add Expense
<q-tooltip v-if="!castleWalletConfigured">
Castle wallet must be configured first
<q-tooltip v-if="!libraWalletConfigured">
Libra wallet must be configured first
</q-tooltip>
<q-tooltip v-if="castleWalletConfigured && !userWalletConfigured && !isSuperUser">
<q-tooltip v-if="libraWalletConfigured && !userWalletConfigured && !isSuperUser">
You must configure your wallet first
</q-tooltip>
</q-btn>
@ -145,14 +145,14 @@
v-if="isSuperUser"
color="orange"
@click="showReceivableDialog"
:disable="!castleWalletConfigured"
:disable="!libraWalletConfigured"
>
Add Receivable
<q-tooltip v-if="!castleWalletConfigured">
Castle wallet must be configured first
<q-tooltip v-if="!libraWalletConfigured">
Libra wallet must be configured first
</q-tooltip>
<q-tooltip v-else>
Record when a user owes the Castle
Record when a user owes the Libra
</q-tooltip>
</q-btn>
<q-btn color="secondary" @click="loadTransactions">
@ -201,7 +201,7 @@
</template>
<template v-slot:body-cell-actions="props">
<q-td :props="props">
<!-- User owes Castle (positive balance) - Castle receives payment -->
<!-- User owes Libra (positive balance) - Libra receives payment -->
<q-btn
v-if="props.row.balance > 0"
flat
@ -211,9 +211,9 @@
icon="payments"
@click="showSettleReceivableDialog(props.row)"
>
<q-tooltip>Settle receivable (user pays castle)</q-tooltip>
<q-tooltip>Settle receivable (user pays libra)</q-tooltip>
</q-btn>
<!-- Castle owes User (negative balance) - Castle pays user -->
<!-- Libra owes User (negative balance) - Libra pays user -->
<q-btn
v-if="props.row.balance < 0"
flat
@ -223,7 +223,7 @@
icon="send"
@click="showPayUserDialog(props.row)"
>
<q-tooltip>Pay user (castle pays user)</q-tooltip>
<q-tooltip>Pay user (libra pays user)</q-tooltip>
</q-btn>
</q-td>
</template>
@ -257,7 +257,7 @@
{% raw %}{{ balance.balance > 0 ? 'Total owed to you' : balance.balance < 0 ? 'Total you owe' : 'No outstanding balances' }}{% endraw %}
</div>
<div class="text-subtitle2" v-else>
{% raw %}{{ balance.balance >= 0 ? 'You owe Castle' : 'Castle owes you' }}{% endraw %}
{% raw %}{{ balance.balance >= 0 ? 'You owe Libra' : 'Libra owes you' }}{% endraw %}
</div>
<div class="q-mt-md q-gutter-sm">
<q-btn
@ -924,7 +924,7 @@
dense
v-model="expenseDialog.isEquity"
:options="[
{label: 'Liability (Castle owes me)', value: false},
{label: 'Liability (Libra owes me)', value: false},
{label: 'Equity (My contribution)', value: true}
]"
option-label="label"
@ -932,7 +932,7 @@
emit-value
map-options
label="Type *"
hint="Choose whether this is a liability (Castle owes you) or an equity contribution"
hint="Choose whether this is a liability (Libra owes you) or an equity contribution"
></q-select>
<!-- If user is not equity eligible, force liability -->
@ -941,9 +941,9 @@
filled
dense
readonly
:model-value="'Liability (Castle owes me)'"
:model-value="'Liability (Libra owes me)'"
label="Type"
hint="This expense will be recorded as a liability (Castle owes you)"
hint="This expense will be recorded as a liability (Libra owes you)"
>
<template v-slot:prepend>
<q-icon name="info" color="blue-grey-7"></q-icon>
@ -1056,7 +1056,7 @@
<div class="text-h6 q-mb-md">Request Manual Payment</div>
<div class="text-caption text-grey q-mb-md">
Request the Castle to pay you manually (cash, bank transfer, etc.) to settle your balance.
Request the Libra to pay you manually (cash, bank transfer, etc.) to settle your balance.
</div>
<div v-if="balance" class="q-mb-md">
@ -1104,7 +1104,7 @@
<q-dialog v-model="settingsDialog.show" position="top">
<q-card v-if="settingsDialog.show" class="q-pa-lg q-pt-xl lnbits__dialog-card">
<q-form @submit="submitSettings" class="q-gutter-md">
<div class="text-h6 q-mb-md">Castle Settings</div>
<div class="text-h6 q-mb-md">Libra Settings</div>
<q-banner v-if="!isSuperUser" class="bg-warning text-dark q-mb-md" dense rounded>
<template v-slot:avatar>
@ -1119,15 +1119,15 @@
filled
dense
emit-value
v-model="settingsDialog.castleWalletId"
v-model="settingsDialog.libraWalletId"
:options="g.user.walletOptions"
label="Castle Wallet *"
label="Libra Wallet *"
:readonly="!isSuperUser"
:disable="!isSuperUser"
></q-select>
<div class="text-caption text-grey q-mb-md">
Select the wallet that will be used for Castle operations and transactions.
Select the wallet that will be used for Libra operations and transactions.
</div>
<q-separator class="q-my-md"></q-separator>
@ -1149,7 +1149,7 @@
dense
v-model="settingsDialog.favaLedgerSlug"
label="Ledger Slug"
hint="Ledger identifier in Fava URL (e.g., castle-ledger)"
hint="Ledger identifier in Fava URL (e.g., libra-ledger)"
:readonly="!isSuperUser"
:disable="!isSuperUser"
></q-input>
@ -1173,7 +1173,7 @@
color="primary"
type="submit"
:loading="settingsDialog.loading"
:disable="!settingsDialog.castleWalletId"
:disable="!settingsDialog.libraWalletId"
>
Save Settings
</q-btn>
@ -1201,7 +1201,7 @@
></q-select>
<div class="text-caption text-grey">
Select the wallet you'll use for Castle transactions.
Select the wallet you'll use for Libra transactions.
</div>
<div class="row q-mt-lg">
@ -1307,7 +1307,7 @@
<div class="text-caption text-grey q-mb-md">
Balance assertions are written to your Beancount ledger and validated automatically by Beancount.
This verifies that an account's actual balance matches your expected balance at a specific date.
If the assertion fails, Beancount will alert you to investigate the discrepancy. Castle stores
If the assertion fails, Beancount will alert you to investigate the discrepancy. Libra stores
metadata (tolerance, notes) for your convenience.
</div>
@ -1531,7 +1531,7 @@
</q-card>
</q-dialog>
<!-- Pay User Dialog (Castle pays user - Super User Only) -->
<!-- Pay User Dialog (Libra pays user - Super User Only) -->
<q-dialog v-model="payUserDialog.show" position="top">
<q-card class="q-pa-md" style="min-width: 400px">
<q-form @submit="submitPayUser">
@ -1544,7 +1544,7 @@
</div>
<div class="q-mb-md">
<div class="text-subtitle2">Amount Castle Owes</div>
<div class="text-subtitle2">Amount Libra Owes</div>
<div class="text-positive text-h6">
{% raw %}{{ formatSats(payUserDialog.maxAmount) }}{% endraw %} sats
</div>
@ -1559,7 +1559,7 @@
v-model.number="payUserDialog.amount"
type="number"
:label="paymentAmountLabel"
hint="Amount castle is paying (max: owed amount)"
hint="Amount libra is paying (max: owed amount)"
:max="paymentMaxAmount"
:step="paymentAmountStep"
:rules="[

View file

@ -4,7 +4,7 @@
{% block scripts %}
{{ window_vars(user) }}
<script src="{{ static_url_for('castle/static', path='js/permissions.js') }}"></script>
<script src="{{ static_url_for('libra/static', path='js/permissions.js') }}"></script>
{% endblock %}
{% block page %}