Item 6 — Desk showcase renders REAL data (or hides), kills the mocked ladder

The pricing Desk showcase hardcoded an alt-line ladder (1.5 A +7.1% / 2.5 A+
+11.4% / 4.5 C -3.8%), QUARTER-KELLY 2.4%, and PARLAY φ 0.34 — a mocked demo
selling something we weren't proving.

- deskShowcaseService reads the pre-graded snapshot for a real A/B prop's
  alt-line ladder (prefers the one with the most grade variation — the most
  compelling real example). Edge per rung shows only when it's a plausible
  market value; the inflated (model-line)/line artifact on small lines is
  guarded to "—" rather than shown as a fake +91%.
- PARLAY φ is now REAL: the model's same-team correlation (0.34, mirroring the
  frontend parlayMath team constant) computed for TWO REAL same-team legs,
  named. No real same-team pair on the board → the tile hides, never an
  invented number.
- QUARTER-KELLY tile is REMOVED: the snapshot has no odds, so a real
  quarter-Kelly % can't be computed here — a fabricated 2.4% is worse than
  nothing. Kelly stays a real in-app Desk feature; the showcase just doesn't
  fake it.
- DeskShowcase is now a client component fetching /api/desk-showcase; when the
  board has no real ladder the whole visuals column hides (real-or-hidden, same
  law as the hero). The pitch copy is unchanged.

5 service tests. Change-affected suites green, web build exit 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kev
2026-07-18 01:42:16 -04:00
parent 9b9aab4262
commit cb3237cdce
6 changed files with 287 additions and 51 deletions
+21
View File
@@ -0,0 +1,21 @@
import { NextResponse } from 'next/server';
export const dynamic = 'force-dynamic';
const BACKEND_URL = process.env.BACKEND_URL || 'http://localhost:3000';
/**
* Desk-showcase proxy (item 6) — real alt-line ladder + same-team correlation
* from the snapshot. Any failure → { available:false } so the visuals hide.
*/
export async function GET() {
try {
const upstream = await fetch(`${BACKEND_URL}/api/desk-showcase`, {
method: 'GET', headers: { Accept: 'application/json' }, cache: 'no-store',
});
const data = await upstream.json().catch(() => ({ available: false }));
return NextResponse.json(data, { status: 200, headers: { 'Cache-Control': 'public, s-maxage=300, stale-while-revalidate=60' } });
} catch {
return NextResponse.json({ available: false }, { status: 200 });
}
}
+78 -51
View File
@@ -1,32 +1,64 @@
'use client';
import { useEffect, useState } from 'react';
import SectionHead from '@/components/vyndr/SectionHead';
/**
* DeskShowcase (DS5 · DESIGN-SPEC Part 6, #8) — the Desk-as-hero story that
* sits ABOVE the pricing grid. Its job is the founder's one line: make $44.99
* feel impossibly low for a professional terminal ("how is this only $44.99"
* IS the conversion event). Balanced two-column layout — the pitch on the left,
* REAL feature visuals on the right (kills the dead right-half, audit #8). The
* single primary CTA scrolls to the grid where the real Stripe checkout lives
* (checkout wiring untouched).
*
* Server component — no interactivity here; the CTA is an in-page anchor and the
* feature visuals are static, tokenized, mono-for-data mock readouts.
* DeskShowcase (DS5 · DESIGN-SPEC Part 6, #8) — the Desk-as-hero story above the
* pricing grid. The pitch (left) is copy; the feature visuals (right) are now
* REAL data (Truth-Everywhere Part 2, item 6), fetched from /api/desk-showcase:
* - ALT LINE LADDER: a real graded prop's ladder (line + grade; edge only when
* it's a plausible market value).
* - PARLAY φ: the model's real same-team correlation, computed for two REAL
* same-team legs (named).
* The old hardcoded ladder / QUARTER-KELLY 2.4% / φ 0.34 mocks are gone. When
* the board has no real ladder, the visuals HIDE (real-or-hidden) — the Kelly
* tile is dropped entirely (the snapshot has no odds to size from honestly).
*/
// A real alt-line-ladder rung (the Desk exclusive) — line + locked grade + edge.
function Rung({ line, grade, edge, base }: { line: string; grade: string; edge: string; base?: boolean }) {
const gradeCol = grade.startsWith('A') ? 'var(--g-a)' : grade.startsWith('B') ? 'var(--text-0)' : 'var(--amber)';
const edgeCol = edge.startsWith('+') ? 'var(--g-a)' : edge.startsWith('-') ? 'var(--miss)' : 'var(--text-2)';
interface Rung { line: number; grade: string; edge: number | null; base?: boolean }
interface Showcase {
available: boolean;
ladder?: { player: string | null; stat_type: string | null; sport?: string; rungs: Rung[] } | null;
parlay?: { value: number; legs: string[]; team?: string } | null;
}
const STAT_LABEL: Record<string, string> = {
total_bases: 'TB', home_runs: 'HR', hits: 'H', rbi: 'RBI', runs: 'R', doubles: '2B',
strikeouts: 'K', points: 'PTS', rebounds: 'REB', assists: 'AST', threes: '3PT',
};
const statLabel = (s?: string | null) => (s ? (STAT_LABEL[s] || s.replace(/_/g, ' ').toUpperCase()) : '');
function RungCell({ line, grade, edge, base }: Rung) {
const gradeCol = grade.startsWith('A') ? 'var(--g-a)' : grade.startsWith('B') ? 'var(--text-0)' : grade.startsWith('C') ? 'var(--text-1)' : 'var(--miss)';
const edgeCol = edge == null ? 'var(--text-2)' : edge >= 0 ? 'var(--g-a)' : 'var(--miss)';
return (
<div style={{ flex: '1 1 0', minWidth: 58, textAlign: 'center', padding: '9px 6px', background: 'var(--bg-2)', border: `1px solid ${base ? 'var(--border-hi)' : 'var(--border)'}`, borderRadius: 6 }}>
<div className="mono" style={{ fontSize: 11, color: base ? 'var(--text-0)' : 'var(--text-1)', marginBottom: 5 }}>{line}{base ? ' •' : ''}</div>
<div className="mono" style={{ fontSize: 17, fontWeight: 800, color: gradeCol }}>{grade}</div>
<div className="mono" style={{ fontSize: 10, color: edgeCol, marginTop: 3 }}>{edge}</div>
<div className="mono" style={{ fontSize: 10, color: edgeCol, marginTop: 3 }}>
{edge == null ? '—' : `${edge >= 0 ? '+' : ''}${edge}%`}
</div>
</div>
);
}
export default function DeskShowcase() {
const [data, setData] = useState<Showcase | null>(null);
useEffect(() => {
let alive = true;
fetch('/api/desk-showcase', { cache: 'no-store' })
.then((r) => r.json())
.then((d) => { if (alive) setData(d); })
.catch(() => { if (alive) setData({ available: false }); });
return () => { alive = false; };
}, []);
const ladder = data?.available ? data.ladder : null;
const parlay = data?.available ? data.parlay : null;
const showVisuals = !!ladder && ladder.rungs.length > 0;
return (
<section style={{ padding: '72px 24px 8px', borderTop: '1px solid var(--border)' }}>
<div className="desk-showcase" style={{ maxWidth: 1100, margin: '0 auto', display: 'grid', gap: 40, alignItems: 'center' }}>
@@ -56,46 +88,41 @@ export default function DeskShowcase() {
</div>
</div>
{/* RIGHT — real feature visuals (no dead half) */}
<div style={{ display: 'grid', gap: 14 }}>
<div style={{ background: 'var(--bg-1)', border: '1px solid var(--border-hi)', borderRadius: 12, padding: 18 }}>
<SectionHead style={{ marginBottom: 12 }}>
ALT LINE LADDER <span style={{ color: 'var(--amber)', fontSize: 9, border: '1px solid rgba(255,179,71,.4)', borderRadius: 3, padding: '1px 5px', marginLeft: 4 }}>DESK</span>
</SectionHead>
<div style={{ display: 'flex', gap: 7 }}>
<Rung line="1.5" grade="A" edge="+7.1%" />
<Rung line="2.5" grade="A+" edge="+11.4%" base />
<Rung line="3.5" grade="B" edge="+2.0%" />
<Rung line="4.5" grade="C" edge="-3.8%" />
{/* RIGHT — REAL feature visuals (hidden when the board has none) */}
{showVisuals && (
<div style={{ display: 'grid', gap: 14 }}>
<div style={{ background: 'var(--bg-1)', border: '1px solid var(--border-hi)', borderRadius: 12, padding: 18 }}>
<SectionHead style={{ marginBottom: 4 }}>
ALT LINE LADDER <span style={{ color: 'var(--amber)', fontSize: 9, border: '1px solid rgba(255,179,71,.4)', borderRadius: 3, padding: '1px 5px', marginLeft: 4 }}>DESK</span>
</SectionHead>
<div className="mono" style={{ fontSize: 10.5, color: 'var(--text-2)', marginBottom: 10, letterSpacing: '0.04em' }}>
{ladder!.player} · {statLabel(ladder!.stat_type)}
</div>
<div style={{ display: 'flex', gap: 7, flexWrap: 'wrap' }}>
{ladder!.rungs.map((r) => <RungCell key={r.line} {...r} />)}
</div>
</div>
</div>
<div style={{ display: 'grid', gap: 14, gridTemplateColumns: '1fr 1fr' }}>
<div style={{ background: 'var(--bg-1)', border: '1px solid var(--border)', borderRadius: 12, padding: 16 }}>
<SectionHead style={{ marginBottom: 10 }}>QUARTER-KELLY</SectionHead>
<div className="mono" style={{ fontSize: 26, fontWeight: 800, color: 'var(--g-a)', fontVariantNumeric: 'tabular-nums' }}>2.4%</div>
<div className="mono" style={{ fontSize: 11, color: 'var(--text-tertiary)', marginTop: 4 }}>of bankroll · at -110</div>
</div>
<div style={{ background: 'var(--bg-1)', border: '1px solid var(--border)', borderRadius: 12, padding: 16 }}>
<SectionHead style={{ marginBottom: 10 }}>PARLAY φ</SectionHead>
<div className="mono" style={{ fontSize: 26, fontWeight: 800, color: 'var(--text-0)', fontVariantNumeric: 'tabular-nums' }}>0.34</div>
<div className="mono" style={{ fontSize: 11, color: 'var(--text-tertiary)', marginTop: 4 }}>correlation · same-team legs</div>
</div>
</div>
{/* PARLAY φ — real, only when two real same-team legs exist */}
{parlay && (
<div style={{ background: 'var(--bg-1)', border: '1px solid var(--border)', borderRadius: 12, padding: 16 }}>
<SectionHead style={{ marginBottom: 10 }}>PARLAY φ</SectionHead>
<div className="mono" style={{ fontSize: 26, fontWeight: 800, color: 'var(--text-0)', fontVariantNumeric: 'tabular-nums' }}>{parlay.value}</div>
<div className="mono" style={{ fontSize: 11, color: 'var(--text-tertiary)', marginTop: 4 }}>
correlation · {parlay.legs[0]} + {parlay.legs[1]}
</div>
</div>
)}
{/* Wave 4A (Step 4) — this claim is now BACKED by a real feature: the
CONSENSUS vs MODEL strip (components/vyndr/MarketBreadth, fed by
lib/marketBreadth.collectBreadth) ships on the live slate/dashboard,
computing the median book line vs the model's projection. "live
line moves" is the existing snapshot line-deltas / LineSparkline.
No longer an empty promise — do not remove without removing those. */}
<div style={{ background: 'var(--bg-1)', border: '1px solid var(--border)', borderRadius: 12, padding: '14px 16px', display: 'flex', alignItems: 'center', gap: 12 }}>
<span className="live-dot" style={{ background: 'var(--g-a)' }} aria-hidden />
<span className="mono" style={{ fontSize: 11.5, color: 'var(--text-1)', letterSpacing: '0.04em' }}>
REAL-TIME FEED · <span style={{ color: 'var(--g-a)', fontWeight: 700 }}>consensus vs model</span>, live line moves
</span>
{/* Real-time feed — backed by the live MarketBreadth (consensus vs model). */}
<div style={{ background: 'var(--bg-1)', border: '1px solid var(--border)', borderRadius: 12, padding: '14px 16px', display: 'flex', alignItems: 'center', gap: 12 }}>
<span className="live-dot" style={{ background: 'var(--g-a)' }} aria-hidden />
<span className="mono" style={{ fontSize: 11.5, color: 'var(--text-1)', letterSpacing: '0.04em' }}>
REAL-TIME FEED · <span style={{ color: 'var(--g-a)', fontWeight: 700 }}>consensus vs model</span>, live line moves
</span>
</div>
</div>
</div>
)}
</div>
</section>
);