unrip/test/quote-lifecycle-statistics.test.mjs
philipp 2e95c95246
All checks were successful
deploy / deploy (push) Successful in 1m0s
Persist quote lifecycle statistics
Proof: Added PostgreSQL-backed quote lifecycle statistics for all-time, monthly, weekly, daily, hourly, and five-minute windows; wired authenticated dashboard API, live WebSocket counters, history-writer refresh before pruning, and dashboard controls; validated with targeted tests, full npm test, and operator dashboard build.

Assumptions: Unique quote counts are keyed by durable quote_id, quote windows use the first durable lifecycle timestamp in UTC with Monday UTC weeks, and missing identifiers or timestamps are represented as unavailable evidence instead of fabricated quote identities.

Still fake: Fee-aware PnL, cashflow, oracle-deviation, size distribution, matched-only analytics, and reconstruction of already-pruned detail remain outside this turn.
2026-06-12 20:02:09 +02:00

106 lines
3.8 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import {
buildQuoteLifecycleStatistics,
classifyQuoteLifecycleStatisticsBucket,
quoteLifecycleStatisticWindow,
} from '../src/core/quote-lifecycle-statistics.mjs';
test('quote lifecycle statistics classify states without upgrading submitted-only rows to success', () => {
assert.equal(classifyQuoteLifecycleStatisticsBucket({
lifecycle_state: 'submitted',
execution: { status: 'submitted', result_code: 'quote_response_ok' },
}), 'submitted_no_reply');
assert.equal(classifyQuoteLifecycleStatisticsBucket({
lifecycle_state: 'failed',
execution: { status: 'failed', failure_category: 'quote_not_found_or_finished' },
}), 'submission_failed');
assert.equal(classifyQuoteLifecycleStatisticsBucket({
lifecycle_state: 'command_emitted',
}), 'awaiting_executor');
assert.equal(classifyQuoteLifecycleStatisticsBucket({
lifecycle_state: 'completed',
outcome_status: 'completed',
has_settlement_evidence: true,
}), 'success');
});
test('quote lifecycle statistics use UTC grain boundaries with Monday UTC weeks', () => {
assert.deepEqual(quoteLifecycleStatisticWindow('2026-06-12T17:34:44.123Z', 'five_minute'), {
grain: 'five_minute',
window_start: '2026-06-12T17:30:00.000Z',
window_end: '2026-06-12T17:35:00.000Z',
});
assert.deepEqual(quoteLifecycleStatisticWindow('2026-06-14T23:59:00.000Z', 'week'), {
grain: 'week',
window_start: '2026-06-08T00:00:00.000Z',
window_end: '2026-06-15T00:00:00.000Z',
});
assert.deepEqual(quoteLifecycleStatisticWindow('2026-06-01T00:00:00.000Z', 'month'), {
grain: 'month',
window_start: '2026-06-01T00:00:00.000Z',
window_end: '2026-07-01T00:00:00.000Z',
});
});
test('quote lifecycle statistics dedupe quotes and refresh later results in the original quote window', () => {
const rows = [
{
quote_id: 'quote-follow',
lifecycle_state: 'command_emitted',
quote_activity_at: '2026-06-12T17:31:01.000Z',
latest_stage_at: '2026-06-12T17:31:03.000Z',
},
{
quote_id: 'quote-follow',
lifecycle_state: 'failed',
quote_activity_at: '2026-06-12T17:31:01.000Z',
latest_stage_at: '2026-06-12T17:36:10.000Z',
execution: {
status: 'failed',
failure_category: 'quote_not_found_or_finished',
},
},
];
const statistics = buildQuoteLifecycleStatistics({
lifecycleRows: rows,
computedAt: '2026-06-12T17:40:00.000Z',
});
const allTime = statistics.find((row) => row.grain === 'all_time');
const fiveMinute = statistics.find((row) => (
row.grain === 'five_minute'
&& row.window_start === '2026-06-12T17:30:00.000Z'
));
const laterFiveMinute = statistics.find((row) => (
row.grain === 'five_minute'
&& row.window_start === '2026-06-12T17:35:00.000Z'
));
assert.equal(allTime.quote_count, 1);
assert.equal(allTime.bucket_counts.submission_failed, 1);
assert.equal(allTime.bucket_counts.awaiting_executor, 0);
assert.equal(fiveMinute.quote_count, 1);
assert.equal(fiveMinute.bucket_counts.submission_failed, 1);
assert.equal(laterFiveMinute, undefined);
});
test('quote lifecycle statistics preserve missing identifiers as unavailable evidence', () => {
const statistics = buildQuoteLifecycleStatistics({
lifecycleRows: [{
quote_id: null,
lifecycle_state: 'observed',
quote_activity_at: '2026-06-12T17:31:01.000Z',
}],
computedAt: '2026-06-12T17:40:00.000Z',
});
const allTime = statistics.find((row) => row.grain === 'all_time');
const fiveMinute = statistics.find((row) => row.grain === 'five_minute');
assert.equal(allTime.quote_count, 0);
assert.equal(allTime.missing_identifier_count, 1);
assert.equal(allTime.bucket_counts.unavailable, 1);
assert.equal(fiveMinute.quote_count, 0);
assert.equal(fiveMinute.missing_identifier_count, 1);
});