All checks were successful
deploy / deploy (push) Successful in 50s
Proof: reproduced live quote lifecycle statistics refresh stalling while persisted subject and window counts remained nonzero; fixed refresh to incrementally scan recent durable source evidence from the retained subject table, canonicalized statistic window ids, de-duped duplicate persisted grain/window rows on load, and validated with targeted stats/dashboard tests, full npm test, and dashboard bundle build. Assumptions: quote lifecycle statistics are durable retained unique quote subjects, and a 5 minute source overlap is enough to catch ordinary insert/refresh races without re-reading the whole retained history on every dashboard refresh. Still fake: this does not create venue-native fill truth where no durable settlement evidence exists, does not repair WebSocket client backpressure from high live quote volume, and does not reconstruct pruned raw quote detail.
139 lines
4.9 KiB
JavaScript
139 lines
4.9 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
|
|
import {
|
|
buildQuoteLifecycleStatistics,
|
|
classifyQuoteLifecycleStatisticsBucket,
|
|
quoteLifecycleStatisticId,
|
|
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 can aggregate retained quote subject buckets', () => {
|
|
const rows = buildQuoteLifecycleStatistics({
|
|
computedAt: '2026-06-12T14:20:00.000Z',
|
|
lifecycleRows: [{
|
|
quote_id: 'quote-retained-success',
|
|
quote_activity_at: '2026-06-12T14:11:01.000Z',
|
|
latest_stage_at: '2026-06-12T14:11:10.000Z',
|
|
statistics_bucket: 'success',
|
|
}],
|
|
});
|
|
|
|
const allTime = rows.find((row) => row.grain === 'all_time');
|
|
const fiveMinute = rows.find((row) => (
|
|
row.grain === 'five_minute'
|
|
&& row.window_start === '2026-06-12T14:10:00.000Z'
|
|
));
|
|
assert.equal(allTime.quote_count, 1);
|
|
assert.equal(allTime.bucket_counts.success, 1);
|
|
assert.equal(fiveMinute.quote_count, 1);
|
|
assert.equal(fiveMinute.bucket_counts.success, 1);
|
|
});
|
|
|
|
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 statistic ids canonicalize Date window values', () => {
|
|
assert.equal(
|
|
quoteLifecycleStatisticId({
|
|
grain: 'five_minute',
|
|
window_start: new Date('2026-06-14T18:40:00.000Z'),
|
|
}),
|
|
'quote-lifecycle-stat:five_minute:2026-06-14T18:40: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);
|
|
});
|