All checks were successful
deploy / deploy (push) Successful in 1m17s
Proof: Raw NEAR Intents quote history is now pruned from the history writer on the raw firehose path, retaining recent rows and rows linked to maker decisions, commands, execution results, or quote outcomes; targeted raw-retention tests pass and full npm test passes. Assumptions: raw quote firehose rows are debug evidence, while normalized swap demand, strategy decisions, executor commands/results, quote outcomes, inventory, funding, alerts, and config history remain the durable trading evidence for this turn. Still fake: venue-native terminal fill ids and fee-complete realized PnL remain unavailable; historical raw quote firehose rows pruned during the incident are intentionally no longer readable.
141 lines
4.4 KiB
JavaScript
141 lines
4.4 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
|
|
import { buildInventorySnapshot } from '../src/core/inventory.mjs';
|
|
import { routeHistoryRecord } from '../src/core/history-records.mjs';
|
|
import { insertHistoryEvents, pruneRawNearIntentsQuoteHistory } from '../src/lib/postgres.mjs';
|
|
|
|
test('inventory snapshot keeps pending funding out of spendable balances', () => {
|
|
const snapshot = buildInventorySnapshot({
|
|
accountId: 'solver.near',
|
|
balances: {
|
|
'nep141:btc.omft.near': '1000',
|
|
'nep141:eure.omft.near': '2000',
|
|
},
|
|
recentDeposits: [
|
|
{
|
|
asset_id: 'nep141:eure.omft.near',
|
|
amount: '300',
|
|
status: 'PENDING',
|
|
},
|
|
],
|
|
trackedWithdrawals: [
|
|
{
|
|
withdrawal_hash: 'wd-1',
|
|
asset_id: 'nep141:btc.omft.near',
|
|
amount: '25',
|
|
status: 'PENDING',
|
|
},
|
|
],
|
|
assetRegistry: new Map([
|
|
['nep141:btc.omft.near', { decimals: 8 }],
|
|
['nep141:eure.omft.near', { decimals: 18 }],
|
|
]),
|
|
observedAt: '2026-04-02T10:00:00.000Z',
|
|
});
|
|
|
|
assert.equal(snapshot.spendable['nep141:eure.omft.near'], '2000');
|
|
assert.equal(snapshot.pending_inbound['nep141:eure.omft.near'], '300');
|
|
assert.equal(snapshot.pending_outbound['nep141:btc.omft.near'], '25');
|
|
});
|
|
|
|
test('history writer routes decision events into the decision table family', () => {
|
|
const routed = routeHistoryRecord({
|
|
topic: 'decision.trade_decision',
|
|
event: {
|
|
event_id: 'evt-1',
|
|
event_type: 'trade_decision',
|
|
venue: 'near-intents',
|
|
schema_version: 1,
|
|
ingested_at: '2026-04-02T10:00:00.000Z',
|
|
payload: {
|
|
decision_id: 'decision-1',
|
|
quote_id: 'quote-1',
|
|
pair: 'a->b',
|
|
direction: 'btc_to_eure',
|
|
decision: 'rejected',
|
|
decision_reason: 'strategy_disarmed',
|
|
},
|
|
},
|
|
});
|
|
|
|
assert.equal(routed.table, 'trade_decisions');
|
|
assert.equal(routed.record.decision_key, 'decision-1');
|
|
assert.equal(routed.record.quote_id, 'quote-1');
|
|
});
|
|
|
|
test('bulk history insert writes multiple routed events in one table statement', async () => {
|
|
const queries = [];
|
|
const pool = {
|
|
async query(sql, params) {
|
|
queries.push({ sql, params });
|
|
return {
|
|
rows: [
|
|
{ event_id: params[0] },
|
|
{ event_id: params[12] },
|
|
],
|
|
rowCount: 2,
|
|
};
|
|
},
|
|
};
|
|
|
|
const result = await insertHistoryEvents(pool, [
|
|
{
|
|
table: 'trade_decisions',
|
|
topic: 'decision.trade_decision',
|
|
event: historyEvent('evt-1', { decision_id: 'decision-1', quote_id: 'quote-1' }),
|
|
record: { quote_id: 'quote-1', pair: 'a->b', decision_key: 'decision-1' },
|
|
},
|
|
{
|
|
table: 'trade_decisions',
|
|
topic: 'decision.trade_decision',
|
|
event: historyEvent('evt-2', { decision_id: 'decision-2', quote_id: 'quote-2' }),
|
|
record: { quote_id: 'quote-2', pair: 'a->b', decision_key: 'decision-2' },
|
|
},
|
|
]);
|
|
|
|
assert.equal(queries.length, 1);
|
|
assert.match(queries[0].sql, /INSERT INTO trade_decisions/);
|
|
assert.match(queries[0].sql, /RETURNING event_id/);
|
|
assert.equal(queries[0].params.length, 24);
|
|
assert.deepEqual([...result.insertedEventIds].sort(), ['evt-1', 'evt-2']);
|
|
});
|
|
|
|
test('raw quote retention preserves rows linked to maker lifecycle evidence', async () => {
|
|
const queries = [];
|
|
const pool = {
|
|
async query(sql, params) {
|
|
queries.push({ sql, params });
|
|
return { rows: [], rowCount: 42 };
|
|
},
|
|
};
|
|
|
|
const result = await pruneRawNearIntentsQuoteHistory(pool, {
|
|
now: '2026-05-21T12:00:00.000Z',
|
|
retainRecentMs: 6 * 60 * 60 * 1000,
|
|
batchSize: 123,
|
|
});
|
|
|
|
assert.equal(result.deletedCount, 42);
|
|
assert.equal(result.cutoff, '2026-05-21T06:00:00.000Z');
|
|
assert.equal(result.batchSize, 123);
|
|
assert.equal(queries.length, 1);
|
|
assert.match(queries[0].sql, /DELETE FROM raw_near_intents_quotes/);
|
|
assert.match(queries[0].sql, /trade_decisions/);
|
|
assert.match(queries[0].sql, /execute_trade_commands/);
|
|
assert.match(queries[0].sql, /trade_execution_results/);
|
|
assert.match(queries[0].sql, /quote_outcome_attributions/);
|
|
assert.deepEqual(queries[0].params, ['2026-05-21T06:00:00.000Z', 123]);
|
|
});
|
|
|
|
function historyEvent(eventId, payload) {
|
|
return {
|
|
event_id: eventId,
|
|
event_type: 'trade_decision',
|
|
venue: 'near-intents',
|
|
source: 'strategy-engine',
|
|
observed_at: '2026-04-02T10:00:00.000Z',
|
|
ingested_at: '2026-04-02T10:00:00.001Z',
|
|
payload,
|
|
};
|
|
}
|