feat(v2)(ui): operator-side LP UI matches the new dca_lp authority split
Operator no longer chooses the LP's wallet / DCA mode / autoforward — those belong to the LP, written via satmachineclient. The Add LP / Edit LP dialogs reduce to (machine, user_id, optional username, status). The clients table loses the wallet / mode / autoforward columns and gains an "Onboarded" column showing whether the LP has a `dca_lp` row yet (server-side LEFT JOIN; `DcaClient.lp_onboarded`). Deposit creation gate (the structural enforcement of "must onboard first"): - Picker annotates each LP option with "— pending onboarding" and disables un-onboarded LP rows. - Selecting an un-onboarded LP shows an inline deep-orange banner explaining the LP needs to open satmachineclient once. - The Record button is `:disable`d in that state. The backend refuses with HTTP 422 anyway (see previous commit) — UI is just the first line of feedback. Backend wiring: - `DcaClient` model gains `lp_onboarded: bool = False`, populated at SELECT time via a shared `_CLIENT_SELECT` / `_CLIENT_FROM` fragment that LEFT JOINs `dca_lp` on `user_id`. All four list/ single-row read paths use it: by-id, by-(machine,user), by-machine, by-operator, by-user. No extra round-trip per row. - CSV export drops the removed columns; adds `lp_onboarded`. All 86 unit tests still pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
80b5a6d785
commit
cfad4e341c
4 changed files with 93 additions and 103 deletions
|
|
@ -222,13 +222,21 @@
|
|||
<q-td key="username">
|
||||
<span v-text="props.row.username || shortId(props.row.user_id)"></span>
|
||||
</q-td>
|
||||
<q-td key="wallet_id">
|
||||
<code :style="{fontSize: '0.8em'}"
|
||||
v-text="shortId(props.row.wallet_id)"></code>
|
||||
</q-td>
|
||||
<q-td key="dca_mode">
|
||||
<q-badge :color="props.row.dca_mode === 'flow' ? 'blue' : 'purple'"
|
||||
:label="props.row.dca_mode"></q-badge>
|
||||
<q-td key="onboarded">
|
||||
<q-icon v-if="props.row.lp_onboarded"
|
||||
name="check_circle" color="green" size="sm">
|
||||
<q-tooltip>
|
||||
LP has onboarded via satmachineclient.
|
||||
Deposits and DCA distributions can proceed.
|
||||
</q-tooltip>
|
||||
</q-icon>
|
||||
<q-icon v-else name="pending" color="deep-orange" size="sm">
|
||||
<q-tooltip>
|
||||
LP hasn't installed/opened satmachineclient yet.
|
||||
Deposits will be refused until they register and
|
||||
select a DCA wallet.
|
||||
</q-tooltip>
|
||||
</q-icon>
|
||||
</q-td>
|
||||
<q-td key="remaining_balance" class="text-right">
|
||||
<span v-if="clientBalances[props.row.id]"
|
||||
|
|
@ -236,18 +244,6 @@
|
|||
v-text="formatFiat(clientBalances[props.row.id].remaining_balance, clientBalances[props.row.id].currency)"></span>
|
||||
<span v-else :style="{opacity: 0.5}">…</span>
|
||||
</q-td>
|
||||
<q-td key="autoforward">
|
||||
<q-icon v-if="props.row.autoforward_enabled"
|
||||
name="forward_to_inbox" color="primary" size="sm">
|
||||
<q-tooltip>
|
||||
Auto-forward enabled →
|
||||
<span v-text="props.row.autoforward_ln_address || '(no address)'"></span>
|
||||
</q-tooltip>
|
||||
</q-icon>
|
||||
<q-icon v-else name="forward" color="grey-5" size="sm">
|
||||
<q-tooltip>Auto-forward disabled</q-tooltip>
|
||||
</q-icon>
|
||||
</q-td>
|
||||
<q-td key="status">
|
||||
<q-badge
|
||||
:color="props.row.status === 'active' ? 'green' : 'grey'"
|
||||
|
|
@ -1128,6 +1124,17 @@
|
|||
class="q-mb-md" dense outlined
|
||||
:rules="[v => !!v || 'Pick an LP']"></q-select>
|
||||
|
||||
<q-banner v-if="depositDialog.mode === 'add' && selectedDepositClient && !selectedDepositClient.lp_onboarded"
|
||||
class="bg-deep-orange-1 text-grey-9 q-mb-md">
|
||||
<template v-slot:avatar>
|
||||
<q-icon name="pending" color="deep-orange"></q-icon>
|
||||
</template>
|
||||
This LP hasn't onboarded via <b>satmachineclient</b> yet, so
|
||||
their DCA wallet isn't configured. Ask them to open the
|
||||
satmachineclient extension once and the deposit will be
|
||||
accepted next time.
|
||||
</q-banner>
|
||||
|
||||
<q-input v-model.number="depositDialog.data.amount"
|
||||
label="Amount (fiat)"
|
||||
type="number" step="0.01" min="0"
|
||||
|
|
@ -1148,6 +1155,7 @@
|
|||
<q-btn color="primary"
|
||||
:label="depositDialog.mode === 'add' ? 'Record' : 'Save'"
|
||||
:loading="depositDialog.saving"
|
||||
:disable="depositDialog.mode === 'add' && (!selectedDepositClient || !selectedDepositClient.lp_onboarded)"
|
||||
@click="submitDeposit"></q-btn>
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
|
|
@ -1195,9 +1203,10 @@
|
|||
<q-card-section>
|
||||
<p class="text-caption q-mb-md" :style="{opacity: 0.7}"
|
||||
v-if="clientDialog.mode === 'add'">
|
||||
LPs receive DCA distributions proportional to their remaining
|
||||
balance. Each LP is scoped to a single machine; the same LP user
|
||||
can register at multiple machines as separate rows.
|
||||
Enrol an LP at one of your machines. Wallet, DCA mode, and
|
||||
autoforward are configured by the LP themselves via the
|
||||
<b>satmachineclient</b> extension — you can't set them here.
|
||||
Deposits are refused until the LP has registered.
|
||||
</p>
|
||||
|
||||
<q-select
|
||||
|
|
@ -1217,38 +1226,9 @@
|
|||
class="q-mb-md" dense outlined
|
||||
:rules="[v => !!v || 'Required']"></q-input>
|
||||
|
||||
<q-input v-if="clientDialog.mode === 'add'"
|
||||
v-model="clientDialog.data.wallet_id"
|
||||
label="LP's wallet_id (receives DCA)"
|
||||
hint="The LP's wallet where their sats land"
|
||||
class="q-mb-md" dense outlined
|
||||
:rules="[v => !!v || 'Required']"></q-input>
|
||||
|
||||
<q-input v-model="clientDialog.data.username"
|
||||
label="Display name (optional)"
|
||||
class="q-mb-md" dense outlined></q-input>
|
||||
|
||||
<q-select v-model="clientDialog.data.dca_mode"
|
||||
:options="[{label: 'Flow (proportional)', value: 'flow'},
|
||||
{label: 'Fixed (daily limit)', value: 'fixed'}]"
|
||||
label="DCA mode"
|
||||
emit-value map-options
|
||||
class="q-mb-md" dense outlined></q-select>
|
||||
|
||||
<q-input v-if="clientDialog.data.dca_mode === 'fixed'"
|
||||
v-model.number="clientDialog.data.fixed_mode_daily_limit"
|
||||
label="Fixed mode daily limit (fiat)"
|
||||
type="number" step="0.01"
|
||||
class="q-mb-md" dense outlined></q-input>
|
||||
|
||||
<q-toggle v-model="clientDialog.data.autoforward_enabled"
|
||||
label="Auto-forward DCA to external LN address"
|
||||
class="q-mb-md"></q-toggle>
|
||||
|
||||
<q-input v-if="clientDialog.data.autoforward_enabled"
|
||||
v-model="clientDialog.data.autoforward_ln_address"
|
||||
label="LN address (e.g. user@walletofsatoshi.com)"
|
||||
hint="LP-controlled; failures leave sats safely in LP's LNbits wallet"
|
||||
hint="Operator-facing label only; doesn't affect distribution"
|
||||
class="q-mb-md" dense outlined></q-input>
|
||||
|
||||
<q-select v-if="clientDialog.mode === 'edit'"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue