Sessions 5-7a: 955 tests, deployment ready

This commit is contained in:
Kev
2026-06-08 18:35:13 -04:00
parent 06b82624a2
commit 1fa04dc776
371 changed files with 49366 additions and 955 deletions
+50
View File
@@ -0,0 +1,50 @@
import { NextRequest, NextResponse } from 'next/server';
import { getServiceRoleSupabase } from '@/lib/supabase';
export const dynamic = 'force-dynamic';
interface Body {
sport?: 'NBA' | 'MLB' | 'WNBA';
player?: string;
stat?: string;
line?: number;
direction?: 'over' | 'under';
}
const VALID_SPORTS = new Set(['NBA', 'MLB', 'WNBA']);
const VALID_DIRS = new Set(['over', 'under']);
export async function POST(req: NextRequest) {
let body: Body;
try {
body = (await req.json()) as Body;
} catch {
return NextResponse.json({ error: 'Invalid JSON.' }, { status: 400 });
}
if (
!body.sport || !VALID_SPORTS.has(body.sport) ||
!body.player || typeof body.player !== 'string' ||
!body.stat ||
typeof body.line !== 'number' || !Number.isFinite(body.line) ||
!body.direction || !VALID_DIRS.has(body.direction)
) {
return NextResponse.json({ error: 'Missing or invalid leg fields.' }, { status: 400 });
}
const sb = getServiceRoleSupabase();
if (!sb) return NextResponse.json({ ok: true, persisted: false });
// RPC increments scan or parlay counter atomically.
await sb.rpc('increment_parlay_leg_frequency', {
p_player: body.player,
p_stat: body.stat,
p_line: body.line,
p_dir: body.direction,
p_sport: body.sport,
p_scan_delta: 0,
p_parlay_delta: 1,
});
return NextResponse.json({ ok: true });
}
+56
View File
@@ -0,0 +1,56 @@
import { NextRequest, NextResponse } from 'next/server';
import { getUserFromRequest, jsonError } from '@/lib/auth-helpers';
export const dynamic = 'force-dynamic';
const BACKEND_URL = process.env.BACKEND_URL || 'http://localhost:3000';
interface Leg {
sport?: 'NBA' | 'MLB' | 'WNBA';
player: string;
stat_type: string;
line: number;
direction: 'over' | 'under';
}
interface Body {
legs: Leg[];
}
export async function POST(req: NextRequest) {
const user = await getUserFromRequest(req);
if (!user) return jsonError(401, 'Log in to grade parlays.');
let body: Body;
try {
body = (await req.json()) as Body;
} catch {
return jsonError(400, 'Invalid JSON.');
}
if (!Array.isArray(body.legs) || body.legs.length < 2 || body.legs.length > 12) {
return jsonError(400, 'Send 212 legs.');
}
try {
const upstream = await fetch(`${BACKEND_URL}/api/scan/parlay`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
...(req.headers.get('authorization') ? { Authorization: req.headers.get('authorization')! } : {}),
},
body: JSON.stringify({ legs: body.legs }),
});
const data = await upstream.json().catch(() => ({}));
if (!upstream.ok) {
return NextResponse.json(
{ error: (data as { error?: string }).error || 'The engine hit a wall on this parlay.' },
{ status: upstream.status },
);
}
return NextResponse.json(data);
} catch {
return jsonError(502, 'The engine hit a wall on this parlay.');
}
}