ff7f5d8d2d
Wiring + one copy pass. No grade, ledger, model or scoring change (diff empty
across intelligence/, ledgerService, outcomeService, gradeSlateService).
REVIEW ZERO — each surface proven with real data BEFORE wiring:
0.1 /intelligence vs /system are NOT duplicates. System.dc.html is a
multi-surface artboard (TERMINAL + INTELLIGENCE + WIRE sections), not the
design for a distinct /system route; its INTELLIGENCE section is already
realised as the live app/intelligence/page.tsx. No /system page exists and
none should be built as a second copy — the prod 404 is correct.
0.2 /intelligence renders live and gates SERVER-side, not by blur: the proxy
requires auth and limits by tier (desk 50 signals / non-desk 8), and
returns 401 to an anonymous caller (verified live). No leak.
0.3 /slip parses a real DraftKings slip end to end: 3/3 legs,
needs_review false, Aaron Judge total_bases over 1.5 @ -115. Honest limit
recorded: parsers are layout-rigid, an unsupported layout yields ZERO legs
rather than wrong ones (never-guess), so real-world OCR hit-rate across
layouts is CANNOT DETERMINE until user slips arrive.
0.4 /parlay direct route hits the real correlation builder on the same
ParlayContext the drawer uses.
0.5 /marketplace advertised four unbuilt things but made NO performance or
profit claim, and its capture was already real (/api/waitlist upserts to a
waitlist table). The gap was tense, not fabrication.
WIRED: Nav MORE gains Intelligence, Slip Reader and Marketplace; Parlay Lab
re-pointed from the drawer hash to /parlay (the drawer is unaffected —
ParlayPanel stays mounted with its floating badge).
GATING: /intelligence added to GATED_ROUTES because its feed 401s signed-out, so
an ungated link would land visitors on a permanently empty page. /parlay stays
OPEN deliberately — it is the free parlay funnel and gating it would be a
monetization regression.
/marketplace honesty pass: every item body now opens "Not built yet." /
"Not written yet." / "Not produced yet." with what is planned; the subhead states
it is not a purchase, not a pre-order and not a promise of a ship date; the
playbook item carries "No profit claim, no promised return". The capture stays
real — no fake button. Unit-locked.
Floor: 315 suites / 3920 tests green (12 new), web build exit 0.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QJs13VsyiSKYQP6rj3NNmc
92 lines
3.8 KiB
JavaScript
92 lines
3.8 KiB
JavaScript
/**
|
|
* WAVE 1 — surfaces wired only after being proven to work with real data
|
|
* (specs/wave1-wiring.md). Existence != works: the populated-path crash and the
|
|
* single-book default both came from surfaces that "existed" but had never run.
|
|
*/
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const read = (p) => fs.readFileSync(path.join(__dirname, '../../', p), 'utf8');
|
|
const routes = require('../../web/src/lib/routes');
|
|
|
|
describe('the three proven surfaces are reachable from nav', () => {
|
|
const nav = read('web/src/components/Nav.tsx');
|
|
|
|
test('/intelligence, /slip and /marketplace have nav entries', () => {
|
|
expect(nav).toMatch(/href: '\/intelligence'/);
|
|
expect(nav).toMatch(/href: '\/slip'/);
|
|
expect(nav).toMatch(/href: '\/marketplace'/);
|
|
});
|
|
|
|
test('Parlay Lab points at the REAL page, not only the drawer hash', () => {
|
|
expect(nav).toMatch(/\{ label: 'Parlay Lab', href: '\/parlay' \}/);
|
|
expect(nav).not.toMatch(/href: '#parlay', action: 'parlay'/);
|
|
});
|
|
});
|
|
|
|
describe('gating is correct for the newly-public surfaces', () => {
|
|
test('/intelligence is GATED — its feed 401s signed-out, so an ungated link would land on an empty page', () => {
|
|
expect(routes.GATED_ROUTES).toContain('/intelligence');
|
|
expect(routes.isGatedRoute('/intelligence')).toBe(true);
|
|
});
|
|
|
|
test('/slip stays gated (personal surface)', () => {
|
|
expect(routes.GATED_ROUTES).toContain('/slip');
|
|
});
|
|
|
|
test('/parlay stays OPEN — it is the free parlay funnel, gating it is a monetization regression', () => {
|
|
expect(routes.OPEN_ROUTES).toContain('/parlay');
|
|
expect(routes.isGatedRoute('/parlay')).toBe(false);
|
|
});
|
|
|
|
test('no route is both gated and open', () => {
|
|
const overlap = routes.GATED_ROUTES.filter((r) => routes.OPEN_ROUTES.includes(r));
|
|
expect(overlap).toEqual([]);
|
|
});
|
|
});
|
|
|
|
describe('/slip actually parses a real slip end to end (the works-with-real-data proof)', () => {
|
|
const { parseSlipText } = require('../../src/services/slipReader');
|
|
const fixture = fs.readFileSync(
|
|
path.join(__dirname, '..', 'fixtures', 'slips', 'draftkings.txt'), 'utf8',
|
|
);
|
|
|
|
test('extracts every leg from the real DraftKings grammar', () => {
|
|
const out = parseSlipText(fixture);
|
|
expect(out.book).toBe('draftkings');
|
|
expect(out.legs).toHaveLength(3);
|
|
expect(out.needs_review).toBe(false);
|
|
expect(out.legs[0]).toMatchObject({ player: 'Aaron Judge', stat: 'total_bases', line: 1.5, side: 'over', odds: -115 });
|
|
});
|
|
|
|
test('an UNRECOGNISED layout yields NO legs rather than wrong ones (never-guess)', () => {
|
|
// A layout the parser does not support must degrade to empty, not fabricate.
|
|
const out = parseSlipText('DraftKings\nAaron Judge\nHome Runs\nOver 0.5 +285');
|
|
expect(out.legs).toHaveLength(0);
|
|
});
|
|
});
|
|
|
|
describe('/marketplace is honest interest-capture', () => {
|
|
const src = read('web/src/app/marketplace/page.tsx');
|
|
|
|
test('every item states it is NOT built yet', () => {
|
|
const bodies = src.match(/body: '[^']+'/g) || [];
|
|
expect(bodies.length).toBeGreaterThanOrEqual(4);
|
|
for (const b of bodies) expect(b).toMatch(/Not built yet|Not written yet|Not produced yet/);
|
|
});
|
|
|
|
test('the page says plainly it is not a purchase, pre-order, or ship-date promise', () => {
|
|
expect(src).toMatch(/None of the below is built yet/);
|
|
expect(src).toMatch(/not a pre-order/);
|
|
});
|
|
|
|
test('makes NO performance / edge / profit claim', () => {
|
|
expect(src).toMatch(/No profit claim, no promised return/);
|
|
expect(src).not.toMatch(/guaranteed|win rate|ROI of|beat the book/i);
|
|
});
|
|
|
|
test('the capture is REAL — it posts to the live waitlist endpoint', () => {
|
|
expect(src).toMatch(/fetch\('\/api\/waitlist'/);
|
|
expect(fs.existsSync(path.join(__dirname, '../../web/src/app/api/waitlist/route.ts'))).toBe(true);
|
|
});
|
|
});
|