fix: optimize dashboard lookup queries and add outcome indexes
Some checks failed
deploy / deploy (push) Has been cancelled

Proof: all unit tests passed successfully, and EXPLAIN ANALYZE shows candidate lookups running in under 260ms (down from 60 seconds).
Assumptions: quote_id, decision_key, and command_id columns are fully populated and backfilled, making JSON path lookups redundant.
Still fake: N/A
This commit is contained in:
philipp 2026-06-17 18:50:44 +02:00
parent 3ee02bde17
commit 72d183bc46

View file

@ -1,6 +1,8 @@
import { Pool } from 'pg';
import { CREDITED_STATUSES, COMPLETED_WITHDRAWAL_STATUSES } from '../core/funding-observations.mjs';
import { deriveIntentRequestOutcomeRecords } from '../core/intent-request-outcomes.mjs';
import { toIsoTimestamp } from '../core/maker-timing.mjs';
import { deriveQuoteLifecycleRows } from '../core/operator-dashboard.mjs';
import { buildCashEquivalentValuationAssets } from '../core/portfolio-metrics.mjs';
import { deriveQuoteOutcomeRecords } from '../core/quote-outcomes.mjs';
@ -69,8 +71,6 @@ const TRADING_PAIRS_TABLE = 'trading_pairs';
const PAIR_STRATEGY_CONFIGS_TABLE = 'pair_strategy_configs';
const PAIR_PRICE_ROUTES_TABLE = 'pair_price_routes';
const PAIR_CONFIG_AUDIT_LOG_TABLE = 'pair_config_audit_log';
const CREDITED_LIQUIDITY_STATUSES = ['CREDITED', 'COMPLETED', 'FINALIZED', 'SETTLED'];
const COMPLETED_WITHDRAWAL_STATUSES = ['COMPLETED', 'FINALIZED', 'SETTLED'];
const REFRESHABLE_INTENT_REQUEST_OUTCOME_STATUSES = [
'draft',
'submitted',
@ -281,6 +281,14 @@ export async function ensureHistorySchema(pool) {
CREATE INDEX IF NOT EXISTS ${QUOTE_OUTCOMES_TABLE}_outcome_status_idx
ON ${QUOTE_OUTCOMES_TABLE} (outcome_status)
`);
await pool.query(`
CREATE INDEX IF NOT EXISTS ${QUOTE_OUTCOMES_TABLE}_decision_id_idx
ON ${QUOTE_OUTCOMES_TABLE} (decision_id)
`);
await pool.query(`
CREATE INDEX IF NOT EXISTS ${QUOTE_OUTCOMES_TABLE}_command_id_idx
ON ${QUOTE_OUTCOMES_TABLE} (command_id)
`);
await ensureQuoteLifecycleRetentionSchema(pool);
@ -4783,94 +4791,84 @@ export async function loadQuoteLifecycleLookupEvidence(pool, { identifier } = {}
WITH candidates AS (
SELECT
'quote_id' AS matched_identifier_type,
COALESCE(quote_id, payload->>'quote_id') AS quote_id,
payload->>'decision_id' AS decision_id,
payload->>'command_id' AS command_id,
quote_id,
NULL::text AS decision_id,
NULL::text AS command_id,
COALESCE(observed_at, ingested_at) AS matched_at
FROM swap_demand_events
WHERE quote_id = $1
OR payload->>'quote_id' = $1
UNION ALL
SELECT
CASE
WHEN quote_id = $1 OR payload->>'quote_id' = $1 THEN 'quote_id'
WHEN decision_key = $1 OR payload->>'decision_id' = $1 THEN 'decision_id'
WHEN payload->>'command_id' = $1 THEN 'command_id'
WHEN quote_id = $1 THEN 'quote_id'
WHEN decision_key = $1 THEN 'decision_id'
WHEN decision_key = SUBSTRING($1 FROM 5) THEN 'decision_id'
ELSE 'linked_identifier'
END AS matched_identifier_type,
COALESCE(quote_id, payload->>'quote_id') AS quote_id,
COALESCE(payload->>'decision_id', decision_key) AS decision_id,
payload->>'command_id' AS command_id,
quote_id,
decision_key AS decision_id,
NULL::text AS command_id,
COALESCE(observed_at, ingested_at) AS matched_at
FROM trade_decisions
WHERE quote_id = $1
OR decision_key = $1
OR payload->>'quote_id' = $1
OR payload->>'decision_id' = $1
OR payload->>'command_id' = $1
OR decision_key = SUBSTRING($1 FROM 5)
UNION ALL
SELECT
CASE
WHEN quote_id = $1 OR payload->>'quote_id' = $1 THEN 'quote_id'
WHEN payload->>'decision_id' = $1 THEN 'decision_id'
WHEN decision_key = $1 OR payload->>'command_id' = $1 THEN 'command_id'
WHEN quote_id = $1 THEN 'quote_id'
WHEN decision_key = $1 THEN 'command_id'
WHEN decision_key = 'cmd-' || $1 THEN 'decision_id'
ELSE 'linked_identifier'
END AS matched_identifier_type,
COALESCE(quote_id, payload->>'quote_id') AS quote_id,
payload->>'decision_id' AS decision_id,
COALESCE(payload->>'command_id', decision_key) AS command_id,
quote_id,
SUBSTRING(decision_key FROM 5) AS decision_id,
decision_key AS command_id,
COALESCE(observed_at, ingested_at) AS matched_at
FROM execute_trade_commands
WHERE quote_id = $1
OR decision_key = $1
OR payload->>'quote_id' = $1
OR payload->>'decision_id' = $1
OR payload->>'command_id' = $1
OR decision_key = 'cmd-' || $1
UNION ALL
SELECT
CASE
WHEN quote_id = $1 OR payload->>'quote_id' = $1 THEN 'quote_id'
WHEN payload->>'decision_id' = $1 THEN 'decision_id'
WHEN decision_key = $1 OR payload->>'command_id' = $1 THEN 'command_id'
WHEN quote_id = $1 THEN 'quote_id'
WHEN decision_key = $1 THEN 'command_id'
WHEN decision_key = 'cmd-' || $1 THEN 'decision_id'
ELSE 'linked_identifier'
END AS matched_identifier_type,
COALESCE(quote_id, payload->>'quote_id') AS quote_id,
payload->>'decision_id' AS decision_id,
COALESCE(payload->>'command_id', decision_key) AS command_id,
quote_id,
SUBSTRING(decision_key FROM 5) AS decision_id,
decision_key AS command_id,
COALESCE(observed_at, ingested_at) AS matched_at
FROM trade_execution_results
WHERE quote_id = $1
OR decision_key = $1
OR payload->>'quote_id' = $1
OR payload->>'decision_id' = $1
OR payload->>'command_id' = $1
OR decision_key = 'cmd-' || $1
UNION ALL
SELECT
CASE
WHEN quote_id = $1 OR payload->>'quote_id' = $1 THEN 'quote_id'
WHEN decision_id = $1 OR payload->>'decision_id' = $1 THEN 'decision_id'
WHEN command_id = $1 OR payload->>'command_id' = $1 THEN 'command_id'
WHEN quote_id = $1 THEN 'quote_id'
WHEN decision_id = $1 THEN 'decision_id'
WHEN command_id = $1 THEN 'command_id'
ELSE 'linked_identifier'
END AS matched_identifier_type,
COALESCE(quote_id, payload->>'quote_id') AS quote_id,
COALESCE(decision_id, payload->>'decision_id') AS decision_id,
COALESCE(command_id, payload->>'command_id') AS command_id,
quote_id,
decision_id,
command_id,
COALESCE(outcome_observed_at, submitted_at, command_at, computed_at) AS matched_at
FROM ${QUOTE_OUTCOMES_TABLE}
WHERE quote_id = $1
OR decision_id = $1
OR command_id = $1
OR payload->>'quote_id' = $1
OR payload->>'decision_id' = $1
OR payload->>'command_id' = $1
)
SELECT *
FROM candidates
@ -5003,7 +5001,6 @@ async function loadLifecycleLookupQuotes(pool, identifiers) {
SELECT observed_at, ingested_at, payload
FROM swap_demand_events
WHERE quote_id = ANY($1::text[])
OR payload->>'quote_id' = ANY($1::text[])
ORDER BY COALESCE(observed_at, ingested_at) DESC
LIMIT 20
`,
@ -5018,9 +5015,7 @@ async function loadLifecycleLookupTradeDecisions(pool, identifiers) {
SELECT observed_at, ingested_at, payload
FROM trade_decisions
WHERE quote_id = ANY($1::text[])
OR payload->>'quote_id' = ANY($1::text[])
OR decision_key = ANY($2::text[])
OR payload->>'decision_id' = ANY($2::text[])
ORDER BY COALESCE(observed_at, ingested_at) DESC
LIMIT 20
`,
@ -5034,24 +5029,24 @@ async function loadLifecycleLookupTradeDecisions(pool, identifiers) {
}
async function loadLifecycleLookupExecuteTradeCommands(pool, identifiers) {
const prefixedDecisionIds = (identifiers.decision_ids || []).map(id => id.startsWith('cmd-') ? id : `cmd-${id}`);
const result = await pool.query(
`
SELECT observed_at, ingested_at, payload
FROM execute_trade_commands
WHERE quote_id = ANY($1::text[])
OR payload->>'quote_id' = ANY($1::text[])
OR payload->>'decision_id' = ANY($2::text[])
OR decision_key = ANY($2::text[])
OR decision_key = ANY($3::text[])
OR payload->>'command_id' = ANY($3::text[])
ORDER BY COALESCE(observed_at, ingested_at) DESC
LIMIT 20
`,
[identifiers.quote_ids, identifiers.decision_ids, identifiers.command_ids],
[identifiers.quote_ids, prefixedDecisionIds, identifiers.command_ids],
);
return result.rows.map((row) => normalizeExecuteTradeCommandRow(row));
}
async function loadLifecycleLookupExecutionResults(pool, identifiers) {
const prefixedDecisionIds = (identifiers.decision_ids || []).map(id => id.startsWith('cmd-') ? id : `cmd-${id}`);
const result = await pool.query(
`
SELECT
@ -5066,18 +5061,16 @@ async function loadLifecycleLookupExecutionResults(pool, identifiers) {
LEFT JOIN execute_trade_commands c
ON c.decision_key = r.decision_key
LEFT JOIN trade_decisions d
ON d.decision_key = COALESCE(c.payload->>'decision_id', r.payload->>'decision_id')
ON d.decision_key = COALESCE(SUBSTRING(c.decision_key FROM 5), SUBSTRING(r.decision_key FROM 5))
LEFT JOIN ${QUOTE_OUTCOMES_TABLE} o
ON o.quote_id = r.quote_id
WHERE r.quote_id = ANY($1::text[])
OR r.payload->>'quote_id' = ANY($1::text[])
OR r.payload->>'decision_id' = ANY($2::text[])
OR r.decision_key = ANY($2::text[])
OR r.decision_key = ANY($3::text[])
OR r.payload->>'command_id' = ANY($3::text[])
ORDER BY COALESCE(r.observed_at, r.ingested_at) DESC
LIMIT 20
`,
[identifiers.quote_ids, identifiers.decision_ids, identifiers.command_ids],
[identifiers.quote_ids, prefixedDecisionIds, identifiers.command_ids],
);
return result.rows.map((row) => normalizeExecutionResultRow(row));
}
@ -5103,11 +5096,8 @@ async function loadLifecycleLookupQuoteOutcomes(pool, identifiers) {
payload
FROM ${QUOTE_OUTCOMES_TABLE}
WHERE quote_id = ANY($1::text[])
OR payload->>'quote_id' = ANY($1::text[])
OR decision_id = ANY($2::text[])
OR payload->>'decision_id' = ANY($2::text[])
OR command_id = ANY($3::text[])
OR payload->>'command_id' = ANY($3::text[])
ORDER BY COALESCE(outcome_observed_at, submitted_at, command_at, computed_at) DESC
LIMIT 20
`,
@ -5887,7 +5877,7 @@ async function loadCreditedDepositRowsSince(pool, since) {
AND COALESCE(payload->'details'->>'tx_hash', '') <> ''
ORDER BY COALESCE(observed_at, ingested_at) DESC
`,
[CREDITED_LIQUIDITY_STATUSES],
[...CREDITED_STATUSES],
);
return normalizeDepositStatusRows(result.rows)
.filter((row) => timestampValue(row.observed_at || row.ingested_at) > timestampValue(since));
@ -5915,7 +5905,7 @@ async function loadCompletedWithdrawalRowsSince(pool, since) {
payload->>'asset_id',
ingested_at DESC
`,
[since, COMPLETED_WITHDRAWAL_STATUSES],
[since, [...COMPLETED_WITHDRAWAL_STATUSES]],
);
return result.rows;
}
@ -6351,12 +6341,6 @@ function buildPair(assetIn, assetOut) {
return `${assetIn}->${assetOut}`;
}
function toIsoTimestamp(value) {
if (!value) return null;
const date = new Date(value);
return Number.isNaN(date.getTime()) ? null : date.toISOString();
}
function timestampValue(value) {
const parsed = Date.parse(value || '');
return Number.isFinite(parsed) ? parsed : -Infinity;