feat(v2)(ui): per-direction fee inputs in super-config + machine modals (#38 5/5)
Surfaces the new directional fee fields in the admin dashboard so
operators + the LNbits super can configure cash-in and cash-out fees
independently:
Templates (`templates/satmachineadmin/index.html`):
- Platform fee banner now shows both directional super fractions
side-by-side ("cash-in X% · cash-out Y% of each transaction's
principal"). Wording updated to "principal" not "commission" since
the math is now principal-based.
- Super-fee edit dialog: replaces the single q-input with two
(super_cash_in_fee_fraction + super_cash_out_fee_fraction); each
capped at 0.15 via max attr (visual hint; server enforces).
- Add-machine + edit-machine dialogs both gain operator_cash_in_fee_
fraction + operator_cash_out_fee_fraction inputs with the same 0.15
cap hint. Hint text mentions the "sits on top of platform fee, total
capped at 15% per direction" semantics so operators understand the
layering.
JS (`static/js/index.js`):
- superFeeDialog.data shape switches to the new directional fields.
- openSuperFeeDialog / submitSuperFee load + POST the new shape.
- _emptyMachineForm / _cleanMachineForm pass through operator
directional fields (Number-coerced, default 0).
- openEditMachineDialog / submitEditMachine include the operator fee
fields in the form data + PUT body.
- New computed `superAnyFee` drives the banner styling (sum of both
directional fractions — non-zero → blue active banner; zero → muted
grey "free instance" banner).
All Quasar UMD components use explicit close tags per the UMD-mode
parsing rule.
Migration carry-over verified in dev container: pre-m009
super_fee_fraction=0.33 backfilled to super_cash_in=0.33 +
super_cash_out=0.33 on migrate-up. Note this puts existing dev
instances above the new 15% cap; operators will see the cap
validation error on their next super-config save and must adjust to
≤0.15 per direction. Production aiolabs/server-deploy will land at
0.03 on both directions (well under cap).
164/164 tests green. Layer 1 (#38) complete; Layer 2 (#39) wire-
format publisher is the next milestone.
Refs: aiolabs/satmachineadmin#37 (parent), #38 (closes Layer 1).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
d9e8a04b8b
commit
10f4b50ca5
2 changed files with 81 additions and 19 deletions
|
|
@ -100,7 +100,11 @@ window.app = Vue.createApp({
|
|||
superFeeDialog: {
|
||||
show: false,
|
||||
saving: false,
|
||||
data: {super_fee_fraction: 0, super_fee_wallet_id: ''}
|
||||
data: {
|
||||
super_cash_in_fee_fraction: 0,
|
||||
super_cash_out_fee_fraction: 0,
|
||||
super_fee_wallet_id: ''
|
||||
}
|
||||
},
|
||||
|
||||
// UI configuration -----------------------------------------------
|
||||
|
|
@ -266,6 +270,17 @@ window.app = Vue.createApp({
|
|||
},
|
||||
|
||||
computed: {
|
||||
superAnyFee() {
|
||||
// Banner styling key — true when either directional super fee is
|
||||
// non-zero, so the banner reads as "active platform fee" instead
|
||||
// of the muted grey "free instance" state.
|
||||
const c = this.superConfig
|
||||
if (!c) return 0
|
||||
return (
|
||||
Number(c.super_cash_in_fee_fraction || 0) +
|
||||
Number(c.super_cash_out_fee_fraction || 0)
|
||||
)
|
||||
},
|
||||
walletOptions() {
|
||||
// g.user is sometimes null on initial mount in LNbits 1.4 — guard it.
|
||||
const wallets = this.g?.user?.wallets || []
|
||||
|
|
@ -549,7 +564,10 @@ window.app = Vue.createApp({
|
|||
// -----------------------------------------------------------------
|
||||
openSuperFeeDialog() {
|
||||
this.superFeeDialog.data = {
|
||||
super_fee_fraction: this.superConfig?.super_fee_fraction ?? 0,
|
||||
super_cash_in_fee_fraction:
|
||||
this.superConfig?.super_cash_in_fee_fraction ?? 0,
|
||||
super_cash_out_fee_fraction:
|
||||
this.superConfig?.super_cash_out_fee_fraction ?? 0,
|
||||
super_fee_wallet_id: this.superConfig?.super_fee_wallet_id || ''
|
||||
}
|
||||
this.superFeeDialog.show = true
|
||||
|
|
@ -562,7 +580,8 @@ window.app = Vue.createApp({
|
|||
const {data} = await LNbits.api.request(
|
||||
'PUT', SUPER_FEE_PATH, null,
|
||||
{
|
||||
super_fee_fraction: Number(d.super_fee_fraction),
|
||||
super_cash_in_fee_fraction: Number(d.super_cash_in_fee_fraction),
|
||||
super_cash_out_fee_fraction: Number(d.super_cash_out_fee_fraction),
|
||||
super_fee_wallet_id: (d.super_fee_wallet_id || '').trim() || null
|
||||
}
|
||||
)
|
||||
|
|
@ -705,7 +724,9 @@ window.app = Vue.createApp({
|
|||
location: machine.location || '',
|
||||
wallet_id: machine.wallet_id,
|
||||
fiat_code: machine.fiat_code,
|
||||
is_active: machine.is_active
|
||||
is_active: machine.is_active,
|
||||
operator_cash_in_fee_fraction: machine.operator_cash_in_fee_fraction ?? 0,
|
||||
operator_cash_out_fee_fraction: machine.operator_cash_out_fee_fraction ?? 0
|
||||
}
|
||||
this.editMachineDialog.show = true
|
||||
},
|
||||
|
|
@ -723,7 +744,9 @@ window.app = Vue.createApp({
|
|||
location: d.location,
|
||||
wallet_id: d.wallet_id,
|
||||
fiat_code: d.fiat_code,
|
||||
is_active: d.is_active
|
||||
is_active: d.is_active,
|
||||
operator_cash_in_fee_fraction: Number(d.operator_cash_in_fee_fraction) || 0,
|
||||
operator_cash_out_fee_fraction: Number(d.operator_cash_out_fee_fraction) || 0
|
||||
}
|
||||
)
|
||||
const idx = this.machines.findIndex(m => m.id === data.id)
|
||||
|
|
@ -1475,7 +1498,9 @@ window.app = Vue.createApp({
|
|||
wallet_id: null,
|
||||
name: '',
|
||||
location: '',
|
||||
fiat_code: 'GTQ'
|
||||
fiat_code: 'GTQ',
|
||||
operator_cash_in_fee_fraction: 0,
|
||||
operator_cash_out_fee_fraction: 0
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -1485,7 +1510,9 @@ window.app = Vue.createApp({
|
|||
wallet_id: d.wallet_id,
|
||||
name: (d.name || '').trim() || null,
|
||||
location: (d.location || '').trim() || null,
|
||||
fiat_code: (d.fiat_code || 'GTQ').trim()
|
||||
fiat_code: (d.fiat_code || 'GTQ').trim(),
|
||||
operator_cash_in_fee_fraction: Number(d.operator_cash_in_fee_fraction) || 0,
|
||||
operator_cash_out_fee_fraction: Number(d.operator_cash_out_fee_fraction) || 0
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue