Wire BookComparison to the prop card (display-only, honest states)
BookComparison.tsx was built but UNROUTED (dead). Route it to the GradeResultCard via a new self-fetching BookComparisonPanel that reads the live /api/books feed (source:'bookprices' — the snapshot-locked, fenced, byte-identical store). Contract fix (Review Zero 0.1): books frequently sit at DIFFERENT lines (WNBA DK 21.5 / FD 18.5; MLB 2/3), so BookComparison now renders EACH book's own line per-row — never one shared header line implying a false same-number comparison. Honest states: single-book (the common case for MLB) → one book, "One book posting this prop.", NO crown/second row; multi-book → all books' own line+price, NONE crowned (BOOK_CROWN_ENABLED=false — no best-price claim, verified live crowned:false); no books → renders NULL (panel self-hides), never a placeholder. No regression: only the always-empty inline d.books section was replaced; grade, projection, PropLine line, and PriceTriplet price are untouched (wiring test asserts them). Freshness (0.4): bookprices is written in the SAME snapshot that locks the grade (intraday refresh touches neither gradedAt.line nor bookprices) — same fresh, no stale-label needed. Web-only → grade byte-identical trivially. Full suite 3851 green, web build exit 0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VsztNChZ7vEvSR61AuMhD1
This commit is contained in:
@@ -78,9 +78,12 @@ describe('Phase D — GradeResultCard (the core moment)', () => {
|
||||
expect(src).toContain('intel-surface');
|
||||
expect(src).toContain('grade-reveal');
|
||||
});
|
||||
it('highlights the best book with green tint + green left border', () => {
|
||||
expect(src).toContain('rgba(0,212,160,.13)');
|
||||
expect(src).toContain("borderLeft: b.best ? '2px solid var(--g-a)'");
|
||||
it('book comparison is the live BookComparisonPanel — no best-book highlight while the crown is gated OFF', () => {
|
||||
// The old inline best-book green tint/border is gone: the crown is
|
||||
// BOOK_CROWN_ENABLED=false, so the card makes NO best-price claim. The grid
|
||||
// is now the wired BookComparisonPanel (honest breadth, no crown).
|
||||
expect(src).toContain('<BookComparisonPanel');
|
||||
expect(src).not.toContain("b.best ? 'rgba(0,212,160,.13)'");
|
||||
});
|
||||
it('renders kill conditions with amber border, gated on non-empty', () => {
|
||||
expect(src).toContain('hasKill');
|
||||
@@ -88,7 +91,9 @@ describe('Phase D — GradeResultCard (the core moment)', () => {
|
||||
expect(src).toContain('KILL CONDITIONS');
|
||||
});
|
||||
it('self-hides books / alt ladder when empty', () => {
|
||||
expect(src).toContain('hasBooks');
|
||||
// Book comparison is now the live BookComparisonPanel (fed by /api/books);
|
||||
// it self-hides (returns null) on honest-absent. Alt ladder still gates on hasAlt.
|
||||
expect(src).toContain('BookComparisonPanel');
|
||||
expect(src).toContain('hasAlt');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user