From cdb1fe71ccebdc36aeb9b01752179be866520b16 Mon Sep 17 00:00:00 2001 From: Padreug Date: Sat, 10 Oct 2026 22:26:45 +0200 Subject: [PATCH] feat(ui): settle off-machine, glossary links, alerts pubkey Settle action on the cash_owed/partial_pending worklist buckets and the settlements table; the worklist's error cell links the raw code to the glossary entry; the platform settings dialog gains the alerts pubkey. --- static/js/index.js | 52 +++++++++++++++++++++++++- templates/spirekeeper/index.html | 64 ++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+), 2 deletions(-) diff --git a/static/js/index.js b/static/js/index.js index 54b6014..a52aa55 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -108,7 +108,8 @@ window.app = Vue.createApp({ super_cash_in_fee_fraction: 0, super_cash_out_fee_fraction: 0, super_fee_wallet_id: '', - max_cash_in_sats: null + max_cash_in_sats: null, + alerts_pubkey: '' } }, @@ -261,6 +262,13 @@ window.app = Vue.createApp({ dispensed_sats: null, notes: '' }, + // ADR-005 §6 — settle an owed-cash settlement off-machine + settleDialog: { + show: false, + settlement: null, + note: '', + saving: false + }, noteDialog: { show: false, saving: false, @@ -659,7 +667,8 @@ window.app = Vue.createApp({ super_cash_out_fee_fraction: this.superConfig?.super_cash_out_fee_fraction ?? 0, super_fee_wallet_id: this.superConfig?.super_fee_wallet_id || '', - max_cash_in_sats: this.superConfig?.max_cash_in_sats ?? null + max_cash_in_sats: this.superConfig?.max_cash_in_sats ?? null, + alerts_pubkey: this.superConfig?.alerts_pubkey || '' } this.superFeeDialog.show = true }, @@ -1263,6 +1272,45 @@ window.app = Vue.createApp({ this.partialDispenseDialog.show = true }, + // ADR-005 §6 — the operator paid the customer by hand; close both ledgers. + openSettleCashOwed(settlement) { + this.settleDialog.settlement = settlement + this.settleDialog.note = '' + this.settleDialog.show = true + }, + + async submitSettleCashOwed() { + const d = this.settleDialog + d.saving = true + try { + const {data} = await LNbits.api.request( + 'POST', + `${SETTLEMENTS_PATH}/${d.settlement.id}/settle-cash-owed`, + null, + {note: d.note} + ) + this._replaceSettlement(data) + d.show = false + Quasar.Notify.create({ + type: 'positive', + message: + 'Settled — distributing the full amount; the machine will mark its row remediated' + }) + if (this.worklist.totalCount) await this.loadWorklist() + } catch (e) { + this._notifyError(e, 'Settle failed') + } finally { + d.saving = false + } + }, + + // Deep link into the error glossary for a settlement's dispenser error. + errorGlossaryHref(settlement) { + const code = settlement.dispense_raw_code || settlement.dispense_error_code || '' + const anchor = code.toLowerCase().replace(/[^a-z0-9]+/g, '-') + return `/spirekeeper/static/docs/errors.html${anchor ? '#' + anchor : ''}` + }, + // ADR-005 §5 — release a machine's cash-out hold after a terminal // dispenser fault, when the jam was cleared without a recount. confirmResumeCashOut(machine) { diff --git a/templates/spirekeeper/index.html b/templates/spirekeeper/index.html index 77d9612..eb84664 100644 --- a/templates/spirekeeper/index.html +++ b/templates/spirekeeper/index.html @@ -16,6 +16,9 @@

Satoshi Machine — Operator

Manage your bitSpire fleet, liquidity providers, and commission distribution. + Operator guide · + Error glossary

@@ -654,6 +657,13 @@ + + + + What this code means and what to do + Open machine detail + + Settle off-machine — you paid the customer by hand + Retry distribution + + + + + Settle off-machine… + + + + + +
Settle off-machine
+ + +
+ +

+ The customer paid + + and the machine reports + . +

+

+ Use this when you have made the customer whole outside the machine. + The settlement distributes at the full amount and the machine marks its own + record remediated. Nothing is dispensed. If you dispensed the shortfall at the + machine instead, do nothing — it reports that itself. +

+ +
+ + + + +
+
+ @@ -1518,6 +1578,10 @@ hint="Server-side ceiling on a single cash-in's principal. The ATM attests the amount; this bounds a compromised/buggy machine to one capped tx." type="number" step="1" min="0" class="q-mb-md" dense outlined> +