All checks were successful
deploy / deploy (push) Successful in 33s
Proof: Live dashboard preflight waited through the generic 3s proxy timeout while trade-executor later recorded solver_quote_unanswered after the 10s relay quote wait. Request controls now use action-aware timeouts and unanswered requests render with plain reason text. Assumptions: Own-request preflight needs at least quote_timeout plus small overhead; submit needs publish plus relay-status wait. Generic service refresh controls should keep the shorter dashboard upstream timeout. Still fake: This does not create external solver liquidity; it only lets the dashboard observe whether the request was answered, submitted, or blocked without timing out first.
1324 lines
42 KiB
JavaScript
1324 lines
42 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
|
|
import {
|
|
applyDashboardLiveEvent,
|
|
buildDashboardBootstrap,
|
|
buildDashboardControlErrorResponse,
|
|
buildLiveStatusBar,
|
|
buildProfitabilitySummary,
|
|
createDashboardLiveState,
|
|
deriveQuoteLifecycleRows,
|
|
resolveDashboardControl,
|
|
resolveDashboardControlTimeoutMs,
|
|
} from '../src/core/operator-dashboard.mjs';
|
|
import {
|
|
buildDashboardSessionToken,
|
|
parseBasicAuthorizationHeader,
|
|
resolveDashboardRequestAuth,
|
|
} from '../src/core/operator-dashboard-auth.mjs';
|
|
|
|
function buildConfig() {
|
|
const tradingBtc = {
|
|
assetId: 'nep141:btc.omft.near',
|
|
symbol: 'BTC',
|
|
decimals: 8,
|
|
chain: 'btc:mainnet',
|
|
};
|
|
const tradingEure = {
|
|
assetId: 'nep141:eure.omft.near',
|
|
symbol: 'EURe',
|
|
decimals: 18,
|
|
chain: 'eth:100',
|
|
};
|
|
|
|
return {
|
|
activePair: `${tradingBtc.assetId}->${tradingEure.assetId}`,
|
|
operatorDashboardQuoteLimit: 10,
|
|
tradingBtc,
|
|
tradingEure,
|
|
assetRegistry: new Map([
|
|
[tradingBtc.assetId, tradingBtc],
|
|
[tradingEure.assetId, tradingEure],
|
|
]),
|
|
};
|
|
}
|
|
|
|
test('profitability summary separates baseline, hold, market move, and portfolio comparison', () => {
|
|
const summary = buildProfitabilitySummary({
|
|
metric: {
|
|
computed_at: '2026-04-04T09:05:00.000Z',
|
|
baseline_anchor_at: '2026-04-04T08:00:00.000Z',
|
|
baseline_status: 'active',
|
|
payload: {
|
|
current_portfolio_value_eure: '110',
|
|
baseline_portfolio_value_eure_at_baseline_price: '100',
|
|
baseline_portfolio_value_eure_at_current_price: '105',
|
|
},
|
|
},
|
|
submissionSummary: {
|
|
total: 4,
|
|
last_submission_at: '2026-04-04T09:00:00.000Z',
|
|
},
|
|
});
|
|
|
|
assert.equal(summary.pnl_vs_deposit_baseline_eure, '10');
|
|
assert.equal(summary.pnl_vs_simple_hold_eure, '5');
|
|
assert.equal(summary.market_move_contribution_eure, '5');
|
|
assert.equal(summary.portfolio_vs_simple_hold_eure, '5');
|
|
assert.equal(summary.trading_contribution_eure, null);
|
|
assert.match(summary.caveats.join(' '), /not realized per-trade PnL/i);
|
|
assert.equal(summary.computed_at, '2026-04-04T09:05:00.000Z');
|
|
assert.equal(summary.recent_submission_count, 4);
|
|
assert.equal(summary.last_submission_at, '2026-04-04T09:00:00.000Z');
|
|
});
|
|
|
|
test('profitability summary flags cash-flow-adjusted benchmarks after later funding changes', () => {
|
|
const summary = buildProfitabilitySummary({
|
|
metric: {
|
|
computed_at: '2026-04-07T15:43:30.463Z',
|
|
baseline_anchor_at: '2026-04-02T18:10:43.569Z',
|
|
baseline_status: 'active',
|
|
payload: {
|
|
current_portfolio_value_eure: '144.627100025978799978',
|
|
baseline_portfolio_value_eure_at_baseline_price: '141.7921998',
|
|
baseline_portfolio_value_eure_at_current_price: '142.8458998',
|
|
external_cash_flows: {
|
|
flow_count: 2,
|
|
deposit_count: 1,
|
|
withdrawal_count: 1,
|
|
latest_effective_at: '2026-04-07T15:20:54.757Z',
|
|
net_value_eure_at_flow_time: '23.9999998',
|
|
},
|
|
},
|
|
},
|
|
submissionSummary: {
|
|
total: 7,
|
|
last_submission_at: '2026-04-02T20:17:44.768Z',
|
|
},
|
|
});
|
|
|
|
assert.equal(summary.external_flow_adjusted, true);
|
|
assert.equal(summary.external_flow_count, 2);
|
|
assert.equal(summary.pnl_vs_deposit_baseline_eure, '2.834900225978799978');
|
|
assert.equal(summary.pnl_vs_simple_hold_eure, '1.781200225978799978');
|
|
assert.equal(summary.market_move_contribution_eure, '1.0537');
|
|
assert.match(summary.caveats[0], /external cash flows/);
|
|
});
|
|
|
|
test('request creation controls get enough upstream time for relay quote and status waits', () => {
|
|
const preflight = resolveDashboardControl({
|
|
service: 'trade-executor',
|
|
action: 'intent-request-preflight',
|
|
});
|
|
const submit = resolveDashboardControl({
|
|
service: 'trade-executor',
|
|
action: 'intent-request-submit',
|
|
});
|
|
const refresh = resolveDashboardControl({
|
|
service: 'inventory-sync',
|
|
action: 'refresh',
|
|
});
|
|
const config = {
|
|
operatorDashboardUpstreamTimeoutMs: 3000,
|
|
intentRequestQuoteTimeoutMs: 10000,
|
|
intentRequestPublishTimeoutMs: 10000,
|
|
intentRequestStatusTimeoutMs: 10000,
|
|
};
|
|
|
|
assert.equal(resolveDashboardControlTimeoutMs({ control: preflight, config }), 12000);
|
|
assert.equal(resolveDashboardControlTimeoutMs({ control: submit, config }), 25000);
|
|
assert.equal(resolveDashboardControlTimeoutMs({ control: refresh, config }), 3000);
|
|
});
|
|
|
|
test('dashboard control errors become structured responses instead of uncaught failures', () => {
|
|
const control = resolveDashboardControl({
|
|
service: 'trade-executor',
|
|
action: 'intent-request-preflight',
|
|
});
|
|
const timeout = new DOMException('The operation was aborted due to timeout', 'TimeoutError');
|
|
const response = buildDashboardControlErrorResponse(timeout, { control });
|
|
|
|
assert.equal(response.statusCode, 504);
|
|
assert.equal(response.payload.ok, false);
|
|
assert.equal(response.payload.error, 'control_timeout');
|
|
assert.equal(response.payload.control.action, 'intent-request-preflight');
|
|
assert.match(response.payload.reason, /timeout/i);
|
|
});
|
|
|
|
test('control routing only resolves the allowlisted safe dashboard actions', () => {
|
|
const refresh = resolveDashboardControl({
|
|
service: 'liquidity-manager',
|
|
action: 'refresh',
|
|
});
|
|
const armExecutor = resolveDashboardControl({
|
|
service: 'trade-executor',
|
|
action: 'arm',
|
|
});
|
|
const resumeExecutor = resolveDashboardControl({
|
|
service: 'trade-executor',
|
|
action: 'resume',
|
|
});
|
|
const requestPreflight = resolveDashboardControl({
|
|
service: 'trade-executor',
|
|
action: 'intent-request-preflight',
|
|
});
|
|
const requestSubmit = resolveDashboardControl({
|
|
service: 'trade-executor',
|
|
action: 'intent-request-submit',
|
|
});
|
|
const risky = resolveDashboardControl({
|
|
service: 'strategy-engine',
|
|
action: 'arm',
|
|
});
|
|
|
|
assert.equal(refresh?.path, '/refresh');
|
|
assert.equal(refresh?.risk_class, 'safe');
|
|
assert.equal(armExecutor?.path, '/arm');
|
|
assert.equal(armExecutor?.label, 'Arm Executor');
|
|
assert.equal(resumeExecutor?.path, '/resume');
|
|
assert.equal(resumeExecutor?.label, 'Resume Executor Intake');
|
|
assert.equal(requestPreflight?.path, '/intent-request/preflight');
|
|
assert.equal(requestPreflight?.risk_class, 'safe');
|
|
assert.equal(requestSubmit?.path, '/intent-request/submit');
|
|
assert.equal(requestSubmit?.risk_class, 'live_funds');
|
|
assert.equal(risky, null);
|
|
});
|
|
|
|
test('basic auth resolves operator identity and reuses a session cookie', () => {
|
|
const authorizationHeader = `Basic ${Buffer.from('admin:secret-password').toString('base64')}`;
|
|
const first = resolveDashboardRequestAuth({
|
|
mode: 'basic',
|
|
authorizationHeader,
|
|
username: 'admin',
|
|
password: 'secret-password',
|
|
});
|
|
|
|
const token = buildDashboardSessionToken({
|
|
username: 'admin',
|
|
password: 'secret-password',
|
|
});
|
|
const second = resolveDashboardRequestAuth({
|
|
mode: 'basic',
|
|
cookieHeader: `operator_dashboard_session=${token}`,
|
|
username: 'admin',
|
|
password: 'secret-password',
|
|
});
|
|
|
|
assert.equal(parseBasicAuthorizationHeader(authorizationHeader).username, 'admin');
|
|
assert.equal(first.authenticated, true);
|
|
assert.equal(first.setSessionCookie, true);
|
|
assert.equal(second.authenticated, true);
|
|
assert.equal(second.via, 'session_cookie');
|
|
});
|
|
|
|
test('live quote updates stay capped at ten items and submitted results update live counters', () => {
|
|
const config = buildConfig();
|
|
const state = createDashboardLiveState({
|
|
config,
|
|
recentSubmissionCount: 2,
|
|
lastSubmissionAt: '2026-04-04T08:00:00.000Z',
|
|
});
|
|
|
|
for (let index = 0; index < 11; index += 1) {
|
|
applyDashboardLiveEvent(state, {
|
|
topic: 'norm.swap_demand',
|
|
event: {
|
|
observed_at: `2026-04-04T08:00:${String(index).padStart(2, '0')}.000Z`,
|
|
ingested_at: `2026-04-04T08:00:${String(index).padStart(2, '0')}.000Z`,
|
|
payload: {
|
|
quote_id: `quote-${index}`,
|
|
asset_in: config.tradingBtc.assetId,
|
|
asset_out: config.tradingEure.assetId,
|
|
pair: config.activePair,
|
|
request_kind: 'exact_in',
|
|
amount_in: '100',
|
|
amount_out: '200',
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|
|
const updates = applyDashboardLiveEvent(state, {
|
|
topic: 'exec.trade_result',
|
|
event: {
|
|
observed_at: '2026-04-04T08:30:00.000Z',
|
|
ingested_at: '2026-04-04T08:30:00.000Z',
|
|
payload: {
|
|
status: 'submitted',
|
|
},
|
|
},
|
|
});
|
|
|
|
assert.equal(state.recent_quotes.length, 10);
|
|
assert.equal(state.recent_quotes[0].quote_id, 'quote-10');
|
|
assert.equal(state.recent_quotes.at(-1).quote_id, 'quote-1');
|
|
assert.equal(state.recent_submission_count, 3);
|
|
assert.equal(state.last_submission_at, '2026-04-04T08:30:00.000Z');
|
|
assert.equal(updates[0].type, 'status_bar.updated');
|
|
});
|
|
|
|
test('live dashboard ignores ops alert events so alert severity cannot re-enter operator state', () => {
|
|
const config = buildConfig();
|
|
const state = createDashboardLiveState({ config });
|
|
|
|
const updates = applyDashboardLiveEvent(state, {
|
|
topic: 'ops.alert',
|
|
event: {
|
|
observed_at: '2026-04-04T08:30:00.000Z',
|
|
ingested_at: '2026-04-04T08:30:00.000Z',
|
|
payload: {
|
|
alert_code: 'near_intents_publish_stale',
|
|
status: 'raised',
|
|
severity: 'critical',
|
|
service_scope: 'near-intents-ingest',
|
|
},
|
|
},
|
|
});
|
|
|
|
assert.deepEqual(updates, []);
|
|
assert.equal(state.active_alerts.size, 0);
|
|
assert.equal(buildLiveStatusBar(state).active_alert_count, 0);
|
|
assert.equal(buildLiveStatusBar(state).highest_alert_severity, null);
|
|
});
|
|
|
|
test('lifecycle derivation keeps executor blocking distinct from strategy rejection', () => {
|
|
const rows = deriveQuoteLifecycleRows({
|
|
recentQuotes: [{
|
|
quote_id: 'quote-1',
|
|
pair: 'btc->eure',
|
|
request_kind: 'exact_in',
|
|
observed_at: '2026-04-09T09:00:00.000Z',
|
|
}],
|
|
recentTradeDecisions: [{
|
|
observed_at: '2026-04-09T09:00:01.000Z',
|
|
payload: {
|
|
decision_id: 'decision-1',
|
|
quote_id: 'quote-1',
|
|
pair: 'btc->eure',
|
|
decision: 'actionable',
|
|
decision_reason: 'actionable',
|
|
gross_edge_pct: '1.2',
|
|
},
|
|
}],
|
|
recentExecuteTradeCommands: [{
|
|
observed_at: '2026-04-09T09:00:02.000Z',
|
|
command_id: 'command-1',
|
|
decision_id: 'decision-1',
|
|
quote_id: 'quote-1',
|
|
pair: 'btc->eure',
|
|
}],
|
|
recentExecutionResults: [{
|
|
command_id: 'command-1',
|
|
decision_id: 'decision-1',
|
|
quote_id: 'quote-1',
|
|
pair: 'btc->eure',
|
|
result_at: '2026-04-09T09:00:03.000Z',
|
|
status: 'rejected',
|
|
result_code: 'executor_disarmed',
|
|
note: 'executor is disarmed',
|
|
}],
|
|
});
|
|
|
|
assert.equal(rows[0].lifecycle_state, 'blocked');
|
|
assert.equal(rows[0].lifecycle_label, 'Blocked before submit');
|
|
assert.equal(rows[0].reason_code, 'executor_disarmed');
|
|
assert.notEqual(rows[0].lifecycle_state, 'rejected');
|
|
});
|
|
|
|
test('lifecycle derivation never upgrades submitted evidence into completion or asset movement', () => {
|
|
const rows = deriveQuoteLifecycleRows({
|
|
recentTradeDecisions: [{
|
|
observed_at: '2026-04-09T09:10:01.000Z',
|
|
payload: {
|
|
decision_id: 'decision-2',
|
|
quote_id: 'quote-2',
|
|
pair: 'btc->eure',
|
|
decision: 'actionable',
|
|
decision_reason: 'actionable',
|
|
},
|
|
}],
|
|
recentExecuteTradeCommands: [{
|
|
observed_at: '2026-04-09T09:10:02.000Z',
|
|
command_id: 'command-2',
|
|
decision_id: 'decision-2',
|
|
quote_id: 'quote-2',
|
|
pair: 'btc->eure',
|
|
}],
|
|
recentExecutionResults: [{
|
|
command_id: 'command-2',
|
|
decision_id: 'decision-2',
|
|
quote_id: 'quote-2',
|
|
pair: 'btc->eure',
|
|
result_at: '2026-04-09T09:10:03.000Z',
|
|
status: 'submitted',
|
|
result_code: 'quote_response_ok',
|
|
}],
|
|
});
|
|
|
|
assert.equal(rows[0].lifecycle_state, 'submitted');
|
|
assert.equal(rows[0].lifecycle_label, 'Submitted');
|
|
assert.match(rows[0].reason_text, /no durable venue outcome/i);
|
|
assert.notEqual(rows[0].lifecycle_state, 'completed');
|
|
assert.doesNotMatch(`${rows[0].lifecycle_label} ${rows[0].reason_text}`.toLowerCase(), /asset delta|realized/);
|
|
});
|
|
|
|
test('strategy approval no longer renders the forbidden actionable label', () => {
|
|
const rows = deriveQuoteLifecycleRows({
|
|
recentTradeDecisions: [{
|
|
observed_at: '2026-04-09T09:20:01.000Z',
|
|
payload: {
|
|
decision_id: 'decision-3',
|
|
quote_id: 'quote-3',
|
|
pair: 'btc->eure',
|
|
decision: 'actionable',
|
|
decision_reason: 'actionable',
|
|
},
|
|
}],
|
|
});
|
|
|
|
assert.equal(rows[0].lifecycle_state, 'evaluated');
|
|
assert.equal(rows[0].lifecycle_label, 'Approved by strategy');
|
|
assert.notEqual(rows[0].lifecycle_label, 'Actionable');
|
|
assert.equal(rows[0].reason_code, 'strategy_approved');
|
|
});
|
|
|
|
test('bootstrap aggregation keeps Funds as default and carries live control state', () => {
|
|
const config = buildConfig();
|
|
const bootstrap = buildDashboardBootstrap({
|
|
config,
|
|
auth: {
|
|
authenticated: true,
|
|
subject: 'local-operator',
|
|
mode: 'stub',
|
|
roles: ['operator'],
|
|
},
|
|
portfolioMetric: {
|
|
computed_at: '2026-04-04T09:05:00.000Z',
|
|
baseline_anchor_at: '2026-04-04T08:00:00.000Z',
|
|
baseline_status: 'active',
|
|
payload: {
|
|
current_portfolio_value_eure: '110',
|
|
baseline_portfolio_value_eure_at_baseline_price: '100',
|
|
baseline_portfolio_value_eure_at_current_price: '105',
|
|
},
|
|
},
|
|
inventorySnapshot: {
|
|
ingested_at: '2026-04-04T09:00:00.000Z',
|
|
payload: {
|
|
synced_at: '2026-04-04T09:00:00.000Z',
|
|
reconciliation_status: 'ok',
|
|
spendable: {
|
|
[config.tradingBtc.assetId]: '100000000',
|
|
[config.tradingEure.assetId]: '1000000000000000000',
|
|
},
|
|
pending_inbound: {
|
|
[config.tradingBtc.assetId]: '0',
|
|
[config.tradingEure.assetId]: '0',
|
|
},
|
|
pending_outbound: {
|
|
[config.tradingBtc.assetId]: '0',
|
|
[config.tradingEure.assetId]: '0',
|
|
},
|
|
},
|
|
},
|
|
marketPrice: {
|
|
ingested_at: '2026-04-04T09:00:00.000Z',
|
|
payload: {
|
|
observed_at: '2026-04-04T09:00:00.000Z',
|
|
eure_per_btc: '100',
|
|
},
|
|
},
|
|
recentQuotes: [],
|
|
submissionPage: {
|
|
page: 1,
|
|
page_size: 20,
|
|
total: 0,
|
|
total_pages: 1,
|
|
items: [],
|
|
},
|
|
submissionSummary: {
|
|
total: 1,
|
|
last_submission_at: '2026-04-04T09:30:00.000Z',
|
|
},
|
|
fundingObservations: [
|
|
{
|
|
payload: {
|
|
funding_observation_id: 'fund-1',
|
|
asset_id: config.tradingBtc.assetId,
|
|
chain: config.tradingBtc.chain,
|
|
funding_handle: 'btc-address',
|
|
tx_hash: 'tx-1',
|
|
status: 'CREDITED',
|
|
amount: '100000000',
|
|
confirmations: 3,
|
|
first_seen_at: '2026-04-04T07:30:00.000Z',
|
|
last_seen_at: '2026-04-04T07:40:00.000Z',
|
|
credited_at: '2026-04-04T07:45:00.000Z',
|
|
},
|
|
},
|
|
],
|
|
recentTradeDecisions: [
|
|
{
|
|
observed_at: '2026-04-04T09:10:00.000Z',
|
|
ingested_at: '2026-04-04T09:10:01.000Z',
|
|
payload: {
|
|
decision_id: 'decision-1',
|
|
quote_id: 'quote-1',
|
|
pair: config.activePair,
|
|
decision: 'rejected',
|
|
decision_reason: 'strategy_disarmed',
|
|
},
|
|
},
|
|
],
|
|
recentAlertTransitions: [],
|
|
serviceSnapshots: [
|
|
{
|
|
service: 'liquidity-manager',
|
|
label: 'Liquidity Manager',
|
|
base_url: 'http://liquidity-manager',
|
|
reachable: true,
|
|
health: { ok: true },
|
|
state: {
|
|
paused: false,
|
|
funding_observer_paused: false,
|
|
withdrawals_frozen: true,
|
|
withdrawal_defaults: {
|
|
[config.tradingBtc.assetId]: 'btc-destination',
|
|
},
|
|
deposit_addresses: {
|
|
[config.tradingBtc.chain]: {
|
|
address: 'btc-address',
|
|
refreshed_at: '2026-04-04T09:00:00.000Z',
|
|
},
|
|
},
|
|
tracked_withdrawals: {},
|
|
},
|
|
},
|
|
{
|
|
service: 'ops-sentinel',
|
|
label: 'Ops Sentinel',
|
|
base_url: 'http://ops-sentinel',
|
|
reachable: true,
|
|
health: { ok: true },
|
|
state: {
|
|
active_alerts: [],
|
|
recent_transitions: [],
|
|
},
|
|
},
|
|
{
|
|
service: 'strategy-engine',
|
|
label: 'Strategy Engine',
|
|
base_url: 'http://strategy-engine',
|
|
reachable: true,
|
|
health: { ok: true },
|
|
state: {
|
|
armed: true,
|
|
paused: false,
|
|
threshold_pct: 2,
|
|
max_notional_eure: 5,
|
|
latest_decision: {
|
|
decision_id: 'decision-1',
|
|
quote_id: 'quote-1',
|
|
pair: config.activePair,
|
|
decision: 'rejected',
|
|
decision_reason: 'strategy_disarmed',
|
|
},
|
|
recent_decisions: [{
|
|
decision_id: 'decision-1',
|
|
quote_id: 'quote-1',
|
|
pair: config.activePair,
|
|
decision: 'rejected',
|
|
decision_reason: 'strategy_disarmed',
|
|
}],
|
|
skipped_counts: {},
|
|
},
|
|
},
|
|
{
|
|
service: 'trade-executor',
|
|
label: 'Trade Executor',
|
|
base_url: 'http://trade-executor',
|
|
reachable: true,
|
|
health: { ok: true },
|
|
state: {
|
|
armed: true,
|
|
paused: false,
|
|
draining: false,
|
|
in_flight_count: 0,
|
|
submitted_count: 1,
|
|
},
|
|
},
|
|
{
|
|
service: 'history-writer',
|
|
label: 'History Writer',
|
|
base_url: 'http://history-writer',
|
|
reachable: true,
|
|
health: { ok: true },
|
|
state: {
|
|
database_connectivity: true,
|
|
offsets: {},
|
|
},
|
|
},
|
|
],
|
|
});
|
|
|
|
assert.equal(bootstrap.default_page, 'funds');
|
|
assert.equal(bootstrap.funds.profitability.computed_at, '2026-04-04T09:05:00.000Z');
|
|
assert.equal(bootstrap.funds.profitability.last_submission_at, '2026-04-04T09:30:00.000Z');
|
|
assert.equal(bootstrap.funds.funding.control_state.withdrawals_frozen, true);
|
|
assert.equal(bootstrap.funds.funding.handles[0].address, 'btc-address');
|
|
assert.deepEqual(bootstrap.funds.recent_submission_terms, []);
|
|
assert.deepEqual(bootstrap.funds.submission_ledger.items, []);
|
|
assert.equal(bootstrap.status_bar.strategy_armed, true);
|
|
assert.equal(bootstrap.status_bar.executor_armed, true);
|
|
assert.equal(bootstrap.status_bar.recent_submission_count, 1);
|
|
assert.equal(bootstrap.strategy.strategy_state.recent_decisions[0].decision_at, '2026-04-04T09:10:00.000Z');
|
|
assert.equal(bootstrap.strategy.strategy_state.recent_decisions[0].decision_reason, 'strategy_disarmed');
|
|
assert.equal(bootstrap.strategy.strategy_state.recent_lifecycle_rows[0].lifecycle_state, 'rejected');
|
|
assert.equal(bootstrap.strategy.strategy_state.recent_lifecycle_rows[0].reason_code, 'strategy_disarmed');
|
|
});
|
|
|
|
test('bootstrap normalizes actionable decision vocabulary before exposing it to the dashboard', () => {
|
|
const config = buildConfig();
|
|
const bootstrap = buildDashboardBootstrap({
|
|
config,
|
|
auth: { authenticated: true, subject: 'local-operator', mode: 'stub', roles: ['operator'] },
|
|
portfolioMetric: null,
|
|
inventorySnapshot: null,
|
|
marketPrice: null,
|
|
recentQuotes: [],
|
|
submissionPage: {
|
|
page: 1,
|
|
page_size: 20,
|
|
total: 1,
|
|
total_pages: 1,
|
|
items: [{
|
|
quote_id: 'quote-1',
|
|
pair: config.activePair,
|
|
observed_at: '2026-04-04T09:10:03.000Z',
|
|
status: 'submitted',
|
|
result_code: 'quote_response_ok',
|
|
decision_reason: 'actionable',
|
|
}],
|
|
},
|
|
submissionSummary: {
|
|
total: 1,
|
|
last_submission_at: '2026-04-04T09:10:03.000Z',
|
|
},
|
|
fundingObservations: [],
|
|
recentDepositStatuses: [],
|
|
recentTradeDecisions: [{
|
|
observed_at: '2026-04-04T09:10:00.000Z',
|
|
payload: {
|
|
decision_id: 'decision-1',
|
|
quote_id: 'quote-1',
|
|
pair: config.activePair,
|
|
decision: 'actionable',
|
|
decision_reason: 'actionable',
|
|
},
|
|
}],
|
|
recentExecuteTradeCommands: [{
|
|
observed_at: '2026-04-04T09:10:01.000Z',
|
|
command_id: 'cmd-1',
|
|
decision_id: 'decision-1',
|
|
quote_id: 'quote-1',
|
|
pair: config.activePair,
|
|
}],
|
|
recentExecutionResults: [{
|
|
command_id: 'cmd-1',
|
|
decision_id: 'decision-1',
|
|
quote_id: 'quote-1',
|
|
pair: config.activePair,
|
|
result_at: '2026-04-04T09:10:03.000Z',
|
|
status: 'submitted',
|
|
result_code: 'quote_response_ok',
|
|
}],
|
|
recentAlertTransitions: [],
|
|
serviceSnapshots: [],
|
|
});
|
|
|
|
assert.equal(bootstrap.funds.submission_ledger.items[0].decision_reason, 'strategy_approved');
|
|
assert.equal(bootstrap.strategy.strategy_state.recent_decisions[0].decision, 'approved');
|
|
assert.equal(bootstrap.strategy.strategy_state.recent_lifecycle_rows[0].reason_code, 'quote_response_ok');
|
|
assert.equal(bootstrap.strategy.strategy_state.trade_funnel.successful_trade_count, 0);
|
|
assert.equal(bootstrap.strategy.strategy_state.trade_funnel.unresolved_submission_count, 1);
|
|
assert.equal(bootstrap.strategy.strategy_state.trade_funnel.counts.submitted, 1);
|
|
assert.match(bootstrap.strategy.strategy_state.trade_funnel.caveat, /No quote currently has linked terminal outcome/);
|
|
assert.doesNotMatch(JSON.stringify(bootstrap), /Actionable/);
|
|
});
|
|
|
|
test('submitted lifecycle evidence never becomes completed by itself', () => {
|
|
const rows = deriveQuoteLifecycleRows({
|
|
recentExecutionResults: [
|
|
{
|
|
command_id: 'cmd-submitted',
|
|
quote_id: 'quote-submitted',
|
|
result_at: '2026-04-09T09:00:00.000Z',
|
|
status: 'submitted',
|
|
result_code: 'quote_response_ok',
|
|
},
|
|
],
|
|
});
|
|
|
|
const completed = rows.filter((row) => row.lifecycle_state === 'completed');
|
|
const submitted = rows.filter((row) => row.lifecycle_state === 'submitted');
|
|
|
|
assert.equal(completed.length, 0);
|
|
assert.equal(submitted.length, 1);
|
|
assert.equal(submitted[0].quote_id, 'quote-submitted');
|
|
assert.equal(submitted[0].has_settlement_evidence, false);
|
|
assert.doesNotMatch(`${submitted[0].lifecycle_label} ${submitted[0].reason_text}`, /completed|successful trade|asset delta/i);
|
|
});
|
|
|
|
test('successful trade rows require completed outcome with linked settled inventory evidence', () => {
|
|
const config = buildConfig();
|
|
const bootstrap = buildDashboardBootstrap({
|
|
config,
|
|
auth: {
|
|
authenticated: true,
|
|
subject: 'local-operator',
|
|
mode: 'stub',
|
|
roles: ['operator'],
|
|
},
|
|
portfolioMetric: null,
|
|
inventorySnapshot: null,
|
|
marketPrice: null,
|
|
recentQuotes: [],
|
|
submissionPage: { page: 1, page_size: 20, total: 0, total_pages: 1, items: [] },
|
|
submissionSummary: { total: 0, last_submission_at: null },
|
|
fundingObservations: [],
|
|
recentDepositStatuses: [],
|
|
recentTradeDecisions: [],
|
|
recentExecuteTradeCommands: [],
|
|
recentExecutionResults: [{
|
|
command_id: 'cmd-submitted',
|
|
quote_id: 'quote-submitted',
|
|
result_at: '2026-04-09T09:00:00.000Z',
|
|
status: 'submitted',
|
|
result_code: 'quote_response_ok',
|
|
}],
|
|
recentQuoteOutcomes: [
|
|
{
|
|
command_id: 'cmd-completed',
|
|
quote_id: 'quote-completed',
|
|
pair: config.activePair,
|
|
outcome_status: 'completed',
|
|
outcome_reason: 'matched_inventory_delta',
|
|
outcome_observed_at: '2026-04-09T09:01:00.000Z',
|
|
outcome_source: 'intent_inventory_spendable_delta',
|
|
attribution_status: 'heuristic_match',
|
|
attribution_method: 'exact_asset_delta_within_window',
|
|
attributed_inventory_delta: {
|
|
observed_at: '2026-04-09T09:01:00.000Z',
|
|
delta_units: {
|
|
[config.tradingBtc.assetId]: '37014',
|
|
[config.tradingEure.assetId]: '-21000021200021200022',
|
|
},
|
|
},
|
|
},
|
|
{
|
|
command_id: 'cmd-completed-no-delta',
|
|
quote_id: 'quote-completed-no-delta',
|
|
pair: config.activePair,
|
|
outcome_status: 'completed',
|
|
outcome_reason: 'settled',
|
|
outcome_observed_at: '2026-04-09T09:02:00.000Z',
|
|
outcome_source: 'venue_status_without_settlement',
|
|
attribution_status: 'unattributed',
|
|
attribution_method: null,
|
|
attributed_inventory_delta: null,
|
|
},
|
|
],
|
|
recentAlertTransitions: [],
|
|
serviceSnapshots: [],
|
|
});
|
|
|
|
const funnel = bootstrap.strategy.strategy_state.trade_funnel;
|
|
assert.equal(funnel.successful_trade_count, 1);
|
|
assert.equal(funnel.successful_trades[0].quote_id, 'quote-completed');
|
|
assert.match(funnel.successful_trades[0].settlement_summary.text, /\+0\.00037014 BTC/);
|
|
assert.equal(funnel.counts.submitted, 1);
|
|
assert.equal(funnel.counts.completed, 2);
|
|
});
|
|
|
|
test('executor blocking is distinct from strategy rejection', () => {
|
|
const [row] = deriveQuoteLifecycleRows({
|
|
recentTradeDecisions: [{
|
|
observed_at: '2026-04-09T09:00:01.000Z',
|
|
payload: {
|
|
decision_id: 'decision-1',
|
|
quote_id: 'quote-1',
|
|
pair: 'btc->eure',
|
|
decision: 'actionable',
|
|
decision_reason: 'actionable',
|
|
},
|
|
}],
|
|
recentExecuteTradeCommands: [{
|
|
observed_at: '2026-04-09T09:00:02.000Z',
|
|
command_id: 'cmd-1',
|
|
decision_id: 'decision-1',
|
|
quote_id: 'quote-1',
|
|
pair: 'btc->eure',
|
|
}],
|
|
recentExecutionResults: [{
|
|
command_id: 'cmd-1',
|
|
decision_id: 'decision-1',
|
|
quote_id: 'quote-1',
|
|
pair: 'btc->eure',
|
|
result_at: '2026-04-09T09:00:03.000Z',
|
|
status: 'rejected',
|
|
result_code: 'executor_disarmed',
|
|
note: 'executor is disarmed',
|
|
}],
|
|
});
|
|
|
|
assert.equal(row.lifecycle_state, 'blocked');
|
|
assert.equal(row.lifecycle_label, 'Blocked before submit');
|
|
assert.equal(row.reason_code, 'executor_disarmed');
|
|
assert.notEqual(row.lifecycle_label, 'Rejected by strategy');
|
|
});
|
|
|
|
test('system service state ignores sentinel alert severity and keeps alert surfaces empty', () => {
|
|
const config = buildConfig();
|
|
const bootstrap = buildDashboardBootstrap({
|
|
config,
|
|
auth: {
|
|
authenticated: true,
|
|
subject: 'local-operator',
|
|
mode: 'stub',
|
|
roles: ['operator'],
|
|
},
|
|
portfolioMetric: null,
|
|
inventorySnapshot: null,
|
|
marketPrice: null,
|
|
recentQuotes: [],
|
|
submissionPage: {
|
|
page: 1,
|
|
page_size: 20,
|
|
total: 0,
|
|
total_pages: 1,
|
|
items: [],
|
|
},
|
|
submissionSummary: {
|
|
total: 0,
|
|
last_submission_at: null,
|
|
},
|
|
fundingObservations: [],
|
|
recentTradeDecisions: [],
|
|
recentAlertTransitions: [],
|
|
serviceSnapshots: [
|
|
{
|
|
service: 'near-intents-ingest',
|
|
label: 'Intents Ingest',
|
|
base_url: 'http://near-intents-ingest',
|
|
reachable: true,
|
|
health: { ok: true },
|
|
state: {
|
|
ingest: {
|
|
connected: true,
|
|
last_message_at: '2026-04-04T09:00:00.000Z',
|
|
last_matching_quote_at: '2026-04-04T09:00:00.000Z',
|
|
last_published_at: '2026-04-03T02:12:00.000Z',
|
|
},
|
|
},
|
|
},
|
|
{
|
|
service: 'ops-sentinel',
|
|
label: 'Ops Sentinel',
|
|
base_url: 'http://ops-sentinel',
|
|
reachable: true,
|
|
health: { ok: true },
|
|
state: {
|
|
active_alerts: [{
|
|
alert_code: 'near_intents_publish_stale',
|
|
status: 'raised',
|
|
severity: 'critical',
|
|
reason: 'published quote freshness is stale',
|
|
service_scope: 'near-intents-ingest',
|
|
pair: config.activePair,
|
|
raised_at: '2026-04-04T09:30:00.000Z',
|
|
first_raised_at: '2026-04-04T09:30:00.000Z',
|
|
cleared_at: null,
|
|
last_evaluated_at: '2026-04-04T09:30:00.000Z',
|
|
details: {
|
|
publish_age_ms: 110_880_000,
|
|
},
|
|
}],
|
|
recent_transitions: [],
|
|
service_health: [{
|
|
service: 'near-intents-ingest',
|
|
status: 'warning',
|
|
label: 'no recent quotes',
|
|
reachable: true,
|
|
paused: false,
|
|
armed: null,
|
|
health_ok: false,
|
|
highest_alert_severity: 'critical',
|
|
reasons: ['connected, no recent quotes for active pair'],
|
|
freshness_at: '2026-04-03T02:12:00.000Z',
|
|
freshness_age_ms: 110_880_000,
|
|
}],
|
|
},
|
|
},
|
|
],
|
|
});
|
|
|
|
const ingest = bootstrap.system.service_health.find((service) => service.service === 'near-intents-ingest');
|
|
assert.equal(ingest.health_ok, true);
|
|
assert.equal(ingest.health_status, 'online');
|
|
assert.equal(ingest.health_label, 'online');
|
|
assert.deepEqual(ingest.health_reasons, []);
|
|
assert.equal(bootstrap.status_bar.highest_alert_severity, null);
|
|
assert.deepEqual(bootstrap.system.alerts.active, []);
|
|
assert.deepEqual(bootstrap.system.alerts.recent, []);
|
|
});
|
|
|
|
test('ingest disconnected renders as basic reachability state without alert severity', () => {
|
|
const config = buildConfig();
|
|
const bootstrap = buildDashboardBootstrap({
|
|
config,
|
|
auth: {
|
|
authenticated: true,
|
|
subject: 'local-operator',
|
|
mode: 'stub',
|
|
roles: ['operator'],
|
|
},
|
|
portfolioMetric: null,
|
|
inventorySnapshot: null,
|
|
marketPrice: null,
|
|
recentQuotes: [],
|
|
submissionPage: {
|
|
page: 1,
|
|
page_size: 20,
|
|
total: 0,
|
|
total_pages: 1,
|
|
items: [],
|
|
},
|
|
submissionSummary: {
|
|
total: 0,
|
|
last_submission_at: null,
|
|
},
|
|
fundingObservations: [],
|
|
recentTradeDecisions: [],
|
|
recentAlertTransitions: [],
|
|
serviceSnapshots: [
|
|
{
|
|
service: 'near-intents-ingest',
|
|
label: 'Intents Ingest',
|
|
base_url: 'http://near-intents-ingest',
|
|
reachable: true,
|
|
health: { ok: false, connected: false, reason: 'websocket disconnected' },
|
|
state: {
|
|
ingest: {
|
|
connected: false,
|
|
last_message_at: '2026-04-04T09:00:00.000Z',
|
|
},
|
|
},
|
|
},
|
|
{
|
|
service: 'ops-sentinel',
|
|
label: 'Ops Sentinel',
|
|
base_url: 'http://ops-sentinel',
|
|
reachable: true,
|
|
health: { ok: true },
|
|
state: {
|
|
active_alerts: [{
|
|
alert_code: 'near_intents_ingest_disconnected',
|
|
status: 'raised',
|
|
severity: 'critical',
|
|
reason: 'websocket disconnected',
|
|
service_scope: 'near-intents-ingest',
|
|
pair: config.activePair,
|
|
raised_at: '2026-04-04T09:30:00.000Z',
|
|
first_raised_at: '2026-04-04T09:30:00.000Z',
|
|
cleared_at: null,
|
|
last_evaluated_at: '2026-04-04T09:30:00.000Z',
|
|
details: {},
|
|
}],
|
|
recent_transitions: [],
|
|
service_health: [{
|
|
service: 'near-intents-ingest',
|
|
status: 'critical',
|
|
label: 'disconnected',
|
|
reachable: true,
|
|
paused: false,
|
|
armed: null,
|
|
health_ok: false,
|
|
highest_alert_severity: 'critical',
|
|
reasons: ['websocket disconnected', 'critical alert active (near_intents_ingest_disconnected)'],
|
|
freshness_at: '2026-04-04T09:00:00.000Z',
|
|
freshness_age_ms: 60_000,
|
|
}],
|
|
},
|
|
},
|
|
],
|
|
});
|
|
|
|
const ingest = bootstrap.system.service_health.find((service) => service.service === 'near-intents-ingest');
|
|
assert.equal(ingest.health_status, 'reachable');
|
|
assert.equal(ingest.health_label, 'reachable');
|
|
assert.deepEqual(ingest.health_reasons, []);
|
|
});
|
|
|
|
test('recent alert history remains empty even when sentinel exposes flapping transitions', () => {
|
|
const config = buildConfig();
|
|
const bootstrap = buildDashboardBootstrap({
|
|
config,
|
|
auth: {
|
|
authenticated: true,
|
|
subject: 'local-operator',
|
|
mode: 'stub',
|
|
roles: ['operator'],
|
|
},
|
|
portfolioMetric: null,
|
|
inventorySnapshot: null,
|
|
marketPrice: null,
|
|
recentQuotes: [],
|
|
submissionPage: {
|
|
page: 1,
|
|
page_size: 20,
|
|
total: 0,
|
|
total_pages: 1,
|
|
items: [],
|
|
},
|
|
submissionSummary: {
|
|
total: 0,
|
|
last_submission_at: null,
|
|
},
|
|
fundingObservations: [],
|
|
recentTradeDecisions: [],
|
|
recentAlertTransitions: [],
|
|
serviceSnapshots: [
|
|
{
|
|
service: 'ops-sentinel',
|
|
label: 'Ops Sentinel',
|
|
base_url: 'http://ops-sentinel',
|
|
reachable: true,
|
|
health: { ok: true },
|
|
state: {
|
|
active_alerts: [],
|
|
recent_transitions: [
|
|
{
|
|
alert_code: 'near_intents_quotes_stale',
|
|
status: 'raised',
|
|
severity: 'critical',
|
|
reason: 'quote truth stale',
|
|
service_scope: 'near-intents-ingest',
|
|
pair: config.activePair,
|
|
raised_at: '2026-04-04T09:33:00.000Z',
|
|
first_raised_at: '2026-04-04T09:30:00.000Z',
|
|
cleared_at: null,
|
|
last_evaluated_at: '2026-04-04T09:33:00.000Z',
|
|
details: {},
|
|
},
|
|
{
|
|
alert_code: 'near_intents_quotes_stale',
|
|
status: 'cleared',
|
|
severity: 'critical',
|
|
reason: 'quote truth stale',
|
|
service_scope: 'near-intents-ingest',
|
|
pair: config.activePair,
|
|
raised_at: '2026-04-04T09:31:00.000Z',
|
|
first_raised_at: '2026-04-04T09:30:00.000Z',
|
|
cleared_at: '2026-04-04T09:32:00.000Z',
|
|
last_evaluated_at: '2026-04-04T09:32:00.000Z',
|
|
details: {},
|
|
},
|
|
{
|
|
alert_code: 'near_intents_quotes_stale',
|
|
status: 'raised',
|
|
severity: 'critical',
|
|
reason: 'quote truth stale',
|
|
service_scope: 'near-intents-ingest',
|
|
pair: config.activePair,
|
|
raised_at: '2026-04-04T09:31:00.000Z',
|
|
first_raised_at: '2026-04-04T09:30:00.000Z',
|
|
cleared_at: null,
|
|
last_evaluated_at: '2026-04-04T09:31:00.000Z',
|
|
details: {},
|
|
},
|
|
],
|
|
},
|
|
},
|
|
],
|
|
});
|
|
|
|
assert.deepEqual(bootstrap.system.alerts.recent, []);
|
|
});
|
|
|
|
test('funding summary includes credited bridge deposits without observer-backed funding observations', () => {
|
|
const config = buildConfig();
|
|
const bootstrap = buildDashboardBootstrap({
|
|
config,
|
|
auth: {
|
|
authenticated: true,
|
|
subject: 'local-operator',
|
|
mode: 'stub',
|
|
roles: ['operator'],
|
|
},
|
|
portfolioMetric: null,
|
|
inventorySnapshot: null,
|
|
marketPrice: null,
|
|
recentQuotes: [],
|
|
submissionPage: {
|
|
page: 1,
|
|
page_size: 20,
|
|
total: 0,
|
|
total_pages: 1,
|
|
items: [],
|
|
},
|
|
submissionSummary: {
|
|
total: 0,
|
|
last_submission_at: null,
|
|
},
|
|
fundingObservations: [],
|
|
recentDepositStatuses: [
|
|
{
|
|
observed_at: '2026-04-07T15:20:00.000Z',
|
|
ingested_at: '2026-04-07T15:20:01.000Z',
|
|
payload: {
|
|
action_type: 'deposit_status_observed',
|
|
chain: config.tradingEure.chain,
|
|
asset_id: config.tradingEure.assetId,
|
|
status: 'COMPLETED',
|
|
details: {
|
|
tx_hash: 'eth-tx-1',
|
|
address: '0xdeposit',
|
|
amount: '24999999800000000000',
|
|
},
|
|
},
|
|
},
|
|
],
|
|
recentTradeDecisions: [],
|
|
recentAlertTransitions: [],
|
|
serviceSnapshots: [
|
|
{
|
|
service: 'liquidity-manager',
|
|
label: 'Liquidity Manager',
|
|
base_url: 'http://liquidity-manager',
|
|
reachable: true,
|
|
health: { ok: true },
|
|
state: {
|
|
paused: false,
|
|
funding_observer_paused: false,
|
|
withdrawals_frozen: true,
|
|
withdrawal_defaults: {},
|
|
deposit_addresses: {
|
|
[config.tradingEure.chain]: {
|
|
address: '0xdeposit',
|
|
refreshed_at: '2026-04-07T15:20:10.000Z',
|
|
},
|
|
},
|
|
deposits: {
|
|
eurDeposit: {
|
|
tx_hash: 'eth-tx-1',
|
|
chain: config.tradingEure.chain,
|
|
asset_id: config.tradingEure.assetId,
|
|
amount: '24999999800000000000',
|
|
address: '0xdeposit',
|
|
status: 'COMPLETED',
|
|
},
|
|
},
|
|
tracked_withdrawals: {},
|
|
last_refresh_at: '2026-04-07T15:20:10.000Z',
|
|
},
|
|
},
|
|
{
|
|
service: 'ops-sentinel',
|
|
label: 'Ops Sentinel',
|
|
base_url: 'http://ops-sentinel',
|
|
reachable: true,
|
|
health: { ok: true },
|
|
state: {
|
|
active_alerts: [],
|
|
recent_transitions: [],
|
|
},
|
|
},
|
|
{
|
|
service: 'strategy-engine',
|
|
label: 'Strategy Engine',
|
|
base_url: 'http://strategy-engine',
|
|
reachable: true,
|
|
health: { ok: true },
|
|
state: {
|
|
armed: true,
|
|
paused: false,
|
|
recent_decisions: [],
|
|
skipped_counts: {},
|
|
},
|
|
},
|
|
{
|
|
service: 'trade-executor',
|
|
label: 'Trade Executor',
|
|
base_url: 'http://trade-executor',
|
|
reachable: true,
|
|
health: { ok: true },
|
|
state: {
|
|
armed: true,
|
|
paused: false,
|
|
draining: false,
|
|
in_flight_count: 0,
|
|
submitted_count: 0,
|
|
},
|
|
},
|
|
{
|
|
service: 'history-writer',
|
|
label: 'History Writer',
|
|
base_url: 'http://history-writer',
|
|
reachable: true,
|
|
health: { ok: true },
|
|
state: {
|
|
database_connectivity: true,
|
|
offsets: {},
|
|
},
|
|
},
|
|
],
|
|
});
|
|
|
|
assert.equal(bootstrap.funds.funding.latest_observed_at, '2026-04-07T15:20:00.000Z');
|
|
assert.equal(bootstrap.funds.funding.credited_deposits[0].asset_id, config.tradingEure.assetId);
|
|
assert.equal(bootstrap.funds.funding.credited_deposits[0].amount, '24.9999998');
|
|
assert.equal(bootstrap.funds.funding.recent_observations[0].tx_hash, 'eth-tx-1');
|
|
assert.equal(bootstrap.funds.recent_deposits[0].tx_hash, 'eth-tx-1');
|
|
});
|
|
|
|
test('bootstrap lifecycle rows preserve quote terms, submitted terms, and gross edge estimate', () => {
|
|
const config = buildConfig();
|
|
const bootstrap = buildDashboardBootstrap({
|
|
config,
|
|
auth: { authenticated: true, subject: 'local-operator', mode: 'stub', roles: ['operator'] },
|
|
portfolioMetric: null,
|
|
inventorySnapshot: null,
|
|
marketPrice: null,
|
|
recentQuotes: [{
|
|
quote_id: 'quote-terms-1',
|
|
pair: config.activePair,
|
|
asset_in: config.tradingBtc.assetId,
|
|
asset_out: config.tradingEure.assetId,
|
|
request_kind: 'exact_in',
|
|
amount_in: '123208',
|
|
amount_out: null,
|
|
observed_at: '2026-04-09T09:00:00.000Z',
|
|
}],
|
|
submissionPage: { page: 1, page_size: 20, total: 0, total_pages: 1, items: [] },
|
|
submissionSummary: { total: 0, last_submission_at: null },
|
|
fundingObservations: [],
|
|
recentDepositStatuses: [],
|
|
recentTradeDecisions: [{
|
|
observed_at: '2026-04-09T09:00:01.000Z',
|
|
payload: {
|
|
decision_id: 'decision-terms-1',
|
|
quote_id: 'quote-terms-1',
|
|
pair: config.activePair,
|
|
decision: 'actionable',
|
|
decision_reason: 'actionable',
|
|
gross_edge_pct: '1.5',
|
|
eure_notional: '100',
|
|
},
|
|
}],
|
|
recentExecuteTradeCommands: [{
|
|
observed_at: '2026-04-09T09:00:02.000Z',
|
|
payload: {
|
|
command_id: 'cmd-terms-1',
|
|
decision_id: 'decision-terms-1',
|
|
quote_id: 'quote-terms-1',
|
|
pair: config.activePair,
|
|
request_kind: 'exact_in',
|
|
asset_in: config.tradingBtc.assetId,
|
|
asset_out: config.tradingEure.assetId,
|
|
amount_in: '123208',
|
|
amount_out: '76000000000000000000',
|
|
},
|
|
}],
|
|
recentExecutionResults: [],
|
|
recentQuoteOutcomes: [],
|
|
recentAlertTransitions: [],
|
|
serviceSnapshots: [],
|
|
});
|
|
|
|
const row = bootstrap.strategy.strategy_state.recent_lifecycle_rows[0];
|
|
assert.equal(row.quote_id, 'quote-terms-1');
|
|
assert.equal(row.request_terms.amount_in, '0.00123208');
|
|
assert.equal(row.request_terms.asset_in_symbol, 'BTC');
|
|
assert.equal(row.submitted_terms.amount_out, '76');
|
|
assert.equal(row.submitted_terms.asset_out_symbol, 'EURe');
|
|
assert.equal(row.gross_edge_value_eure, '1.5');
|
|
});
|
|
|
|
|
|
test('own request dashboard rows do not label relay accepted evidence as completed trade', () => {
|
|
const config = buildConfig();
|
|
const bootstrap = buildDashboardBootstrap({
|
|
config,
|
|
auth: { authenticated: true, subject: 'local-operator', mode: 'stub', roles: ['operator'] },
|
|
portfolioMetric: null,
|
|
inventorySnapshot: null,
|
|
marketPrice: null,
|
|
recentQuotes: [],
|
|
submissionPage: { page: 1, page_size: 20, total: 0, total_pages: 1, items: [] },
|
|
submissionSummary: { total: 0, last_submission_at: null },
|
|
fundingObservations: [],
|
|
recentDepositStatuses: [],
|
|
recentTradeDecisions: [],
|
|
recentExecuteTradeCommands: [],
|
|
recentExecutionResults: [],
|
|
recentQuoteOutcomes: [],
|
|
recentIntentRequests: [{
|
|
request_id: 'request-accepted-only',
|
|
idempotency_key: 'idem-accepted-only',
|
|
submission_id: 'submission-accepted-only',
|
|
intent_hash: 'intent-hash-accepted-only',
|
|
quote_hash: 'quote-hash-accepted-only',
|
|
created_at: '2026-04-12T10:00:00.000Z',
|
|
submitted_at: '2026-04-12T10:00:01.000Z',
|
|
state: 'awaiting_settlement',
|
|
state_label: 'Awaiting settlement',
|
|
reason_code: 'accepted_by_relay_without_settlement',
|
|
reason_text: 'Relay accepted the signed request. This is not settlement.',
|
|
source_asset_id: config.tradingEure.assetId,
|
|
source_symbol: 'EURe',
|
|
source_decimals: 18,
|
|
destination_asset_id: config.tradingBtc.assetId,
|
|
destination_symbol: 'BTC',
|
|
destination_decimals: 8,
|
|
source_amount_units: '5000000000000000000',
|
|
expected_destination_amount_units: '10000',
|
|
min_destination_amount_units: '9800',
|
|
quoted_destination_amount_units: '10000',
|
|
slippage_bps: 200,
|
|
submission_status: 'accepted_by_relay',
|
|
relay_status: 'PENDING',
|
|
outcome_status: 'awaiting_settlement',
|
|
attribution_status: 'unattributed',
|
|
attribution_method: null,
|
|
attributed_inventory_delta: null,
|
|
has_settlement_evidence: false,
|
|
live_submit_capable: false,
|
|
lifecycle: {
|
|
preflight: { state: 'draft' },
|
|
submission: { status: 'accepted_by_relay' },
|
|
outcome: { outcome_status: 'awaiting_settlement' },
|
|
},
|
|
}],
|
|
recentAlertTransitions: [],
|
|
serviceSnapshots: [{
|
|
service: 'trade-executor',
|
|
label: 'Trade Executor',
|
|
base_url: 'http://trade-executor',
|
|
reachable: true,
|
|
health: { ok: true },
|
|
state: { armed: true, paused: false },
|
|
}],
|
|
});
|
|
|
|
const row = bootstrap.funds.intent_requests.items[0];
|
|
assert.equal(row.state, 'awaiting_settlement');
|
|
assert.equal(row.state_label, 'Awaiting settlement');
|
|
assert.equal(row.submission_status, 'accepted_by_relay');
|
|
assert.equal(row.has_settlement_evidence, false);
|
|
assert.equal(row.settlement_summary.text, 'No settled inventory delta is linked to this request.');
|
|
assert.doesNotMatch(
|
|
[row.state_label, row.reason_text, row.settlement_summary.text].join(' '),
|
|
/successful trade|completed trade|asset delta/i,
|
|
);
|
|
});
|