// Unit coverage for sizing/risk product contracts used by tRPC routers. import { test } from 'node:test'; import { strict as assert } from 'node:assert'; import { sizePosition } from '../../sizing/SizingEngine.ts'; import { assessRisk, ADR_0007_FOOTER } from '../RiskEngine.ts'; test('sizing.compute contract: math implies shares, ADR-0007 footer-ready', () => { const result = sizePosition( { symbol: 'NVDA', tier: 'B', riskFraction: 0.01, stopPerShare: 5 }, { equity: 100_000, complexity: 'beginner' }, { holdings: [], regime: 'trending-up', clusterCaps: { uncategorized: 25_000 }, aStarUnlocked: false, }, ); // 100000 * 0.01 / 5 = 200 shares * B(×1) = 200 assert.equal(result.shares, 200); assert.equal(result.blocked, false); assert.ok(result.explanations.some((e) => /math implies/i.test(e))); assert.ok(result.explanations.some((e) => /not investment advice/i.test(e))); }); test('risk.posture contract: peak breach yields halt + consideration', () => { const posture = assessRisk({ portfolio: [ { symbol: 'NVDA', shares: 100, avgCost: 100, cluster: 'uncategorized', stopPrice: 90, rewardTarget: 130 }, ], account: { equity: 80_000, drawdownTolerancePct: 15, complexity: 'beginner' }, peakEquity: 100_000, regime: 'trending-down', sizingContext: { clusterCaps: { uncategorized: 20_000 } }, }); assert.equal(posture.halted, true); assert.ok(posture.recommendedActions.length > 0); assert.ok(posture.recommendedActions.every((a) => a.explanation.includes(ADR_0007_FOOTER) || a.explanation.toLowerCase().includes('trade-off'))); assert.ok(!JSON.stringify(posture.recommendedActions).toLowerCase().includes('you should sell')); });