PHASE 2: Fixes balance assertion creation and validation

Improves balance assertion creation by handling Decimal types correctly for database insertion.
It also fixes a validation issue in the UI where the expected balance was not correctly validated as a required field and initializes the value to 0.
This commit is contained in:
padreug 2025-10-23 01:55:20 +02:00
parent 0257b7807c
commit c0277dfc98
3 changed files with 36 additions and 42 deletions

26
crud.py
View file

@ -796,7 +796,31 @@ async def create_balance_assertion(
created_at=datetime.now(),
)
await db.insert("balance_assertions", assertion, convert_decimal=True)
# Manually insert with Decimal fields converted to strings
await db.execute(
"""
INSERT INTO balance_assertions (
id, date, account_id, expected_balance_sats, expected_balance_fiat,
fiat_currency, tolerance_sats, tolerance_fiat, status, created_by, created_at
) VALUES (
:id, :date, :account_id, :expected_balance_sats, :expected_balance_fiat,
:fiat_currency, :tolerance_sats, :tolerance_fiat, :status, :created_by, :created_at
)
""",
{
"id": assertion.id,
"date": assertion.date,
"account_id": assertion.account_id,
"expected_balance_sats": assertion.expected_balance_sats,
"expected_balance_fiat": str(assertion.expected_balance_fiat) if assertion.expected_balance_fiat else None,
"fiat_currency": assertion.fiat_currency,
"tolerance_sats": assertion.tolerance_sats,
"tolerance_fiat": str(assertion.tolerance_fiat),
"status": assertion.status.value,
"created_by": assertion.created_by,
"created_at": assertion.created_at,
},
)
return assertion

View file

@ -70,7 +70,7 @@ window.app = Vue.createApp({
assertionDialog: {
show: false,
account_id: '',
expected_balance_sats: null,
expected_balance_sats: 0,
expected_balance_fiat: null,
fiat_currency: null,
tolerance_sats: 0,
@ -646,7 +646,7 @@ window.app = Vue.createApp({
this.assertionDialog = {
show: false,
account_id: '',
expected_balance_sats: null,
expected_balance_sats: 0,
expected_balance_fiat: null,
fiat_currency: null,
tolerance_sats: 0,
@ -677,12 +677,6 @@ window.app = Vue.createApp({
}
},
async recheckAssertion(assertionId) {
// Set loading state
const assertion = this.balanceAssertions.find(a => a.id === assertionId)
if (assertion) {
this.$set(assertion, 'rechecking', true)
}
try {
await LNbits.api.request(
'POST',
@ -699,19 +693,9 @@ window.app = Vue.createApp({
await this.loadBalanceAssertions()
} catch (error) {
LNbits.utils.notifyApiError(error)
} finally {
if (assertion) {
this.$set(assertion, 'rechecking', false)
}
}
},
async deleteAssertion(assertionId) {
// Set loading state
const assertion = this.balanceAssertions.find(a => a.id === assertionId)
if (assertion) {
this.$set(assertion, 'deleting', true)
}
try {
await LNbits.api.request(
'DELETE',
@ -728,10 +712,6 @@ window.app = Vue.createApp({
await this.loadBalanceAssertions()
} catch (error) {
LNbits.utils.notifyApiError(error)
} finally {
if (assertion) {
this.$set(assertion, 'deleting', false)
}
}
},
getAccountName(accountId) {

View file

@ -302,7 +302,6 @@
round
icon="refresh"
@click="recheckAssertion(assertion.id)"
:loading="assertion.rechecking"
>
<q-tooltip>Re-check assertion</q-tooltip>
</q-btn>
@ -312,7 +311,6 @@
round
icon="delete"
@click="deleteAssertion(assertion.id)"
:loading="assertion.deleting"
>
<q-tooltip>Delete assertion</q-tooltip>
</q-btn>
@ -353,7 +351,6 @@
round
icon="refresh"
@click="recheckAssertion(assertion.id)"
:loading="assertion.rechecking"
>
<q-tooltip>Re-check assertion</q-tooltip>
</q-btn>
@ -363,7 +360,6 @@
round
icon="delete"
@click="deleteAssertion(assertion.id)"
:loading="assertion.deleting"
>
<q-tooltip>Delete assertion</q-tooltip>
</q-btn>
@ -929,12 +925,9 @@
v-model.number="assertionDialog.expected_balance_sats"
type="number"
label="Expected Balance (sats) *"
:rules="[val => val !== null && val !== undefined || 'Expected balance is required']"
>
<template v-slot:hint>
The balance you expect this account to have in satoshis
</template>
</q-input>
hint="The balance you expect this account to have in satoshis"
:rules="[val => val !== null && val !== undefined && val !== '' || 'Expected balance is required']"
></q-input>
<q-input
filled
@ -943,15 +936,12 @@
type="number"
label="Tolerance (sats)"
min="0"
>
<template v-slot:hint>
Allow the actual balance to differ by ± this amount (default: 0)
</template>
</q-input>
hint="Allow the actual balance to differ by ± this amount (default: 0)"
></q-input>
<q-separator />
<q-separator class="q-my-md"></q-separator>
<div class="text-subtitle2">Optional: Fiat Balance Check</div>
<div class="text-subtitle2 q-mb-sm">Optional: Fiat Balance Check</div>
<q-select
filled
@ -987,11 +977,11 @@
min="0"
></q-input>
<div class="row q-mt-lg">
<div class="row q-mt-md q-gutter-sm">
<q-btn unelevated color="primary" type="submit" :loading="assertionDialog.loading">
Create & Check
</q-btn>
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Cancel</q-btn>
<q-btn v-close-popup flat color="grey">Cancel</q-btn>
</div>
</q-form>
</q-card>