Stop calling submissions trades in dashboard
All checks were successful
deploy / deploy (push) Successful in 32s

Proof: Dashboard copy now describes durable submitted quote responses as submissions rather than successful trades or asset deltas, and regression coverage locks the new wording in place.

Assumptions: The current durable  execution result still means quote-response submission, not settled execution or realized inventory change.

Still fake: The backend still stores and aggregates these rows under trade-oriented names, and the full quote lifecycle model is still the active follow-up turn.
This commit is contained in:
philipp 2026-04-09 01:13:14 +02:00
parent 7ea1576ba7
commit 7ddefb500e
4 changed files with 56 additions and 15 deletions

View file

@ -1,4 +1,5 @@
import { formatAge, formatBoolean, formatEur, formatTimestamp, signedClass, truncateMiddle } from '../lib/format.js'; import { formatAge, formatBoolean, formatEur, formatTimestamp, signedClass, truncateMiddle } from '../lib/format.js';
import { SUBMISSION_COPY } from '../lib/submissionCopy.js';
function statusSubtitle(label, status, websocketState) { function statusSubtitle(label, status, websocketState) {
switch (label) { switch (label) {
@ -8,8 +9,8 @@ function statusSubtitle(label, status, websocketState) {
return formatTimestamp(status.market_observed_at); return formatTimestamp(status.market_observed_at);
case 'Inventory Freshness': case 'Inventory Freshness':
return formatTimestamp(status.inventory_observed_at); return formatTimestamp(status.inventory_observed_at);
case 'Trading': case SUBMISSION_COPY.statusTileLabel:
return 'Successful submissions from durable history'; return SUBMISSION_COPY.statusTileSubtitle;
default: default:
return ''; return '';
} }
@ -25,8 +26,8 @@ export default function StatusBar({ status, websocketState }) {
['Alerts', `${status.active_alert_count || 0} ${status.highest_alert_severity ? `(${status.highest_alert_severity})` : ''}`.trim()], ['Alerts', `${status.active_alert_count || 0} ${status.highest_alert_severity ? `(${status.highest_alert_severity})` : ''}`.trim()],
['Strategy Armed', formatBoolean(status.strategy_armed)], ['Strategy Armed', formatBoolean(status.strategy_armed)],
['Executor Armed', formatBoolean(status.executor_armed)], ['Executor Armed', formatBoolean(status.executor_armed)],
['Trading', `${status.recent_trade_count || 0} trades`], [SUBMISSION_COPY.statusTileLabel, `${status.recent_trade_count || 0} ${SUBMISSION_COPY.statusTileValueSuffix}`],
['Last Trade', formatTimestamp(status.last_successful_trade_at)], [SUBMISSION_COPY.lastStatusTileLabel, formatTimestamp(status.last_successful_trade_at)],
]; ];
return ( return (

View file

@ -0,0 +1,15 @@
export const SUBMISSION_COPY = {
statusTileLabel: 'Submissions',
statusTileSubtitle: 'Successful quote-response submissions from durable history',
statusTileValueSuffix: 'submissions',
lastStatusTileLabel: 'Last Submission',
recentMetricLabel: 'Recent submissions',
recentMetricValueSuffix: 'submissions',
termsEyebrow: 'Submission activity',
termsTitle: 'Recent submitted quote terms',
termsEmpty: 'No submitted quote responses are available yet.',
ledgerTitle: 'Submitted quote responses',
ledgerSubtitle: 'PostgreSQL-backed pagination of executor submissions',
ledgerEmpty: 'No submitted quote responses are stored yet.',
ledgerCountLabel: (page, totalPages, total) => `Page ${page} of ${totalPages} - ${total} submitted quote responses`,
};

View file

@ -5,6 +5,7 @@ import MetricCard from '../components/MetricCard.jsx';
import Pill from '../components/Pill.jsx'; import Pill from '../components/Pill.jsx';
import TableFrame from '../components/TableFrame.jsx'; import TableFrame from '../components/TableFrame.jsx';
import { formatEur, formatTimestamp, stringifyJson, truncateMiddle } from '../lib/format.js'; import { formatEur, formatTimestamp, stringifyJson, truncateMiddle } from '../lib/format.js';
import { SUBMISSION_COPY } from '../lib/submissionCopy.js';
function buildInitialEstimateForm(balances, withdrawalDefaults) { function buildInitialEstimateForm(balances, withdrawalDefaults) {
const firstAssetId = balances?.[0]?.asset_id || ''; const firstAssetId = balances?.[0]?.asset_id || '';
@ -204,7 +205,7 @@ function QuotesTable({ items }) {
} }
function AssetChangeTable({ items }) { function AssetChangeTable({ items }) {
if (!items?.length) return <EmptyState>No successful trades are available yet.</EmptyState>; if (!items?.length) return <EmptyState>{SUBMISSION_COPY.termsEmpty}</EmptyState>;
return ( return (
<TableFrame> <TableFrame>
@ -213,8 +214,8 @@ function AssetChangeTable({ items }) {
<tr> <tr>
<th>Observed</th> <th>Observed</th>
<th>Quote</th> <th>Quote</th>
<th>Spend</th> <th>Input</th>
<th>Receive</th> <th>Output</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -233,7 +234,7 @@ function AssetChangeTable({ items }) {
} }
function TradesTable({ items }) { function TradesTable({ items }) {
if (!items?.length) return <EmptyState>No successful trades are stored yet.</EmptyState>; if (!items?.length) return <EmptyState>{SUBMISSION_COPY.ledgerEmpty}</EmptyState>;
return ( return (
<TableFrame> <TableFrame>
@ -446,9 +447,9 @@ export default function FundsPage({
value={formatEur(profitability.trading_contribution_eure)} value={formatEur(profitability.trading_contribution_eure)}
/> />
<MetricCard <MetricCard
label="Recent trading" label={SUBMISSION_COPY.recentMetricLabel}
meta={formatTimestamp(profitability.last_successful_trade_at)} meta={formatTimestamp(profitability.last_successful_trade_at)}
value={`${profitability.recent_trade_count || 0} trades`} value={`${profitability.recent_trade_count || 0} ${SUBMISSION_COPY.recentMetricValueSuffix}`}
/> />
</div> </div>
<div className="panel-subtitle"> <div className="panel-subtitle">
@ -568,8 +569,8 @@ export default function FundsPage({
<div className="panel"> <div className="panel">
<div className="panel-head"> <div className="panel-head">
<div> <div>
<div className="eyebrow">Trade-driven changes</div> <div className="eyebrow">{SUBMISSION_COPY.termsEyebrow}</div>
<h3>Recent asset deltas</h3> <h3>{SUBMISSION_COPY.termsTitle}</h3>
</div> </div>
</div> </div>
<AssetChangeTable items={funds.trade_asset_changes} /> <AssetChangeTable items={funds.trade_asset_changes} />
@ -580,13 +581,13 @@ export default function FundsPage({
<div className="panel-head"> <div className="panel-head">
<div> <div>
<div className="eyebrow">Durable ledger</div> <div className="eyebrow">Durable ledger</div>
<h3>Successful trades</h3> <h3>{SUBMISSION_COPY.ledgerTitle}</h3>
</div> </div>
<div className="status-subtle">PostgreSQL-backed pagination</div> <div className="status-subtle">{SUBMISSION_COPY.ledgerSubtitle}</div>
</div> </div>
<TradesTable items={trades.items} /> <TradesTable items={trades.items} />
<div className="pagination"> <div className="pagination">
<div className="status-subtle">{`Page ${trades.page} of ${trades.total_pages} - ${trades.total} successful trades`}</div> <div className="status-subtle">{SUBMISSION_COPY.ledgerCountLabel(trades.page, trades.total_pages, trades.total)}</div>
<div className="button-row"> <div className="button-row">
<button <button
className="button secondary" className="button secondary"

View file

@ -0,0 +1,24 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import { SUBMISSION_COPY } from '../src/operator-dashboard/static/lib/submissionCopy.js';
test('submission copy does not present submissions as trades', () => {
const text = [
SUBMISSION_COPY.statusTileLabel,
SUBMISSION_COPY.statusTileSubtitle,
SUBMISSION_COPY.recentMetricLabel,
SUBMISSION_COPY.termsEyebrow,
SUBMISSION_COPY.termsTitle,
SUBMISSION_COPY.termsEmpty,
SUBMISSION_COPY.ledgerTitle,
SUBMISSION_COPY.ledgerSubtitle,
SUBMISSION_COPY.ledgerEmpty,
SUBMISSION_COPY.ledgerCountLabel(1, 2, 3),
].join(' ').toLowerCase();
assert.ok(text.includes('submission'));
assert.ok(!text.includes('successful trades'));
assert.ok(!text.includes('asset deltas'));
assert.ok(!text.includes('trade-driven'));
});