feat: dealer flow, mirror portfolio (M21), options convexity, FINRA short interest, alert producers, vendor gate
CI / Test & Type-Check (push) Canceled after 0s
CI / Test & Type-Check (push) Canceled after 0s
Snapshot of in-progress module work across multiple slices: - Dealer Flow: dealerExposureEngine, dealerMapService, dealerMapExplain, dealerMapIntegrity, dealerMapReplay, dealerStudyEngine, hanStyleLevels - Mirror Portfolio (M21): fundRepository, captureIngest, mirrorAlertProducers, fund holdings strip, live book, position capture ingest - Options: BSM, NormalizedOptionSurface types, OptionsChainRouter, ConvexityGate, option legs panel - Alert producers: vixLevel, rotation, thesis, unlock, portfolioRisk, mirror (fund_capture, fund_13f, mirror_diff) - FINRA short interest adapter + queue integration - SEC company tickers adapter + ingest (symbol search index seed) - Vendor gate (rate-limit-first data plane, ADR-0009) - CUSIP registry, reverse 13F refresh, stock float service - LRU cache, portfolio backtest engine - Frontend: dealer-flow, funds, journal, lab, monitor, plan, portfolio, reports, screener, strategies, theses, guided-start, exits, more pages - Volume profile, workspace profile, visibility-aware poll - ADRs 0010 (mirror math not advice), 0011 (symbol search index) - VENDOR_INTEGRATIONS.md, END_USER_TEST.md - .gitignore: exclude DBs, .DS_Store, local config, agent scratch
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
import { test } from 'node:test';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import { DatabaseSync } from 'node:sqlite';
|
||||
import {
|
||||
curatedCusipForSymbol,
|
||||
resolveCusipLocal,
|
||||
seedCuratedCusips,
|
||||
} from '../cusipRegistry.ts';
|
||||
|
||||
/**
|
||||
* Unit-level tests for CUSIP cache helpers via sec fetch behavior contracts.
|
||||
* Network resolve is not exercised here.
|
||||
*/
|
||||
test('kv_cache can store and read sec:cusip keys', () => {
|
||||
const db = new DatabaseSync(':memory:');
|
||||
db.exec(`
|
||||
CREATE TABLE kv_cache (key TEXT PRIMARY KEY, value TEXT NOT NULL, observed_at TEXT NOT NULL);
|
||||
`);
|
||||
const key = 'sec:cusip:IREN';
|
||||
const cusip = 'Q4982L109';
|
||||
db.prepare('INSERT OR REPLACE INTO kv_cache (key,value,observed_at) VALUES (?,?,?)').run(
|
||||
key,
|
||||
cusip,
|
||||
new Date().toISOString(),
|
||||
);
|
||||
const row = db.prepare('SELECT value FROM kv_cache WHERE key=?').get(key) as { value: string };
|
||||
assert.equal(row.value, cusip);
|
||||
});
|
||||
|
||||
test('curated map resolves IREN offline', () => {
|
||||
assert.equal(curatedCusipForSymbol('IREN'), 'Q4982L109');
|
||||
assert.equal(curatedCusipForSymbol('AAPL'), '037833100');
|
||||
});
|
||||
|
||||
test('resolveCusipLocal seeds cache from curated map', () => {
|
||||
const db = new DatabaseSync(':memory:');
|
||||
db.exec(`
|
||||
CREATE TABLE kv_cache (key TEXT PRIMARY KEY, value TEXT NOT NULL, observed_at TEXT NOT NULL);
|
||||
`);
|
||||
const c = resolveCusipLocal(db, 'IREN');
|
||||
assert.equal(c, 'Q4982L109');
|
||||
const row = db.prepare('SELECT value FROM kv_cache WHERE key=?').get('sec:cusip:IREN') as {
|
||||
value: string;
|
||||
};
|
||||
assert.equal(row.value, 'Q4982L109');
|
||||
});
|
||||
|
||||
test('seedCuratedCusips is idempotent', () => {
|
||||
const db = new DatabaseSync(':memory:');
|
||||
db.exec(`
|
||||
CREATE TABLE kv_cache (key TEXT PRIMARY KEY, value TEXT NOT NULL, observed_at TEXT NOT NULL);
|
||||
`);
|
||||
const n1 = seedCuratedCusips(db);
|
||||
const n2 = seedCuratedCusips(db);
|
||||
assert.ok(n1 > 0);
|
||||
assert.equal(n2, 0);
|
||||
});
|
||||
|
||||
test('isPermanentDataError does not quarantine cusip failures', async () => {
|
||||
const { isPermanentDataError } = await import('../../queue/sourceRatePolicy.ts');
|
||||
assert.equal(
|
||||
isPermanentDataError('sec-fetch:IREN: cusip not resolved - 13F holder refresh blocked'),
|
||||
false,
|
||||
);
|
||||
assert.equal(isPermanentDataError('quote not found for symbol'), true);
|
||||
});
|
||||
Reference in New Issue
Block a user