unrip/test/inventory-and-history.test.mjs
philipp 348c4f9b0b
All checks were successful
deploy / deploy (push) Successful in 47s
Batch durable history writes
Proof: History-writer now writes routed event batches with one bulk insert per table, preserving decision and normalized quote history while reducing Kafka lag that delayed durable strategy decision rows.

Assumptions: Kafka message order within a topic partition remains sufficient for durability; environment status events keep their dedicated dedupe path; this change does not alter strategy, edge, notional, inventory, arming, or relay submission behavior.

Still fake: Venue-native terminal fill ids and fee-complete realized PnL remain unavailable; historical decision rows can still lag until the deployed batch writer drains existing backlog.
2026-05-19 15:53:52 +02:00

114 lines
3.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 } 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']);
});
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,
};
}