# VYNDR — Build State ## Last Updated 2026-05-18 ## Current Phase SHIP BUILD v6.0 — Web Tier Complete (Dashboard + Game Pages + Intelligence Feed + PWA + NexaPay) ## Web Tier v6 (2026-05-18) — SHIPPED Complete frontend overhaul. 18 pages, 22 API routes. `npm run build` passes with zero errors. ### New pages - `/dashboard` — post-login slate (sport tabs, top grades, tonight's games, most parlayed, recent scans, first-time onboarding) - `/game/[id]` — game preview with spread/total/ML, starting lineups with injury flags, expandable prop list, add-to-parlay - `/profile` — tier status, subscription state, founder badge, cancel-at-period-end flow - `/intelligence` — Desk-tier timeline of evolution/coaching/cascade/ABS/line-movement signals (blurred for non-Desk) - `/terms`, `/privacy`, `/responsible-gambling` — branded legal pages with brand voice - `/scan` — full rebuild (sport tabs, real /api/scan with tier gating, parlay tray hook) - `/login`, `/signup` — wired to Supabase Auth via AuthContext (Google OAuth + email/password + age check) - `/marketplace` — coming-soon waitlist (API access, custom alerts, capsule drop) - `/ledger`, `/tracker` — design system refresh, accuracy buckets, miss autopsy, quick-slip - `/` — auth-aware: logged-in users redirect to `/dashboard`; anonymous see marketing ### New API routes - `/api/games/tonight`, `/api/games/[id]`, `/api/games/[id]/props` - `/api/props/top-graded`, `/api/props/most-parlayed` - `/api/players/search` - `/api/user/recent-scans` - `/api/intelligence/feed` - `/api/parlay/add-leg`, `/api/parlay/grade` - `/api/ledger`, `/api/ledger/accuracy` - All cached via Supabase `odds_cache` table (5-min TTL) — never hit Odds API directly ### Services + middleware - `services/odds-cache.ts` — Supabase-backed TTL cache for upstream calls (loader + stale-fallback) - `services/email.ts` — Resend wrapper: `sendWelcomeEmail`, `sendPaymentReceipt`, `sendRenewalReminder` - `middleware/rateLimit.ts` — per-tier per-minute scan throttle (5/30/60 free/analyst/desk) - `services/nexapay.ts` — already shipped (createPaymentLink + HMAC webhook verify), now wired to email receipts ### Components - `GradeCard.tsx` — premium grade card with tier-gated blur (factors locked for free; alt-lines locked for non-Desk) - `ParlayContext.tsx` + `ParlayTray.tsx` — cross-page parlay state, slide-up tray, /api/parlay/grade integration - `BottomTabBar.tsx` — mobile-only 5-tab navigation (Home/Scan/Parlay/Ledger/Profile) with parlay badge - `ShareCard.tsx` — canvas-rendered 1200x630 OG share image with grade letter; download + copy-to-clipboard - `Nav.tsx`, `Hero.tsx`, `LivePropsStrip.tsx`, `Features.tsx`, `Pricing.tsx`, `HowItWorks.tsx`, `FAQ.tsx`, `Footer.tsx` — design system refresh already shipped ### PWA + meta - `public/manifest.json` (192/512/maskable icons) - `public/icons/icon-{192,512,maskable-512}.png`, `apple-touch-icon.png`, `favicon.ico`, `favicon.png` - `public/og-image.png` — 1200x630 social share card - `appleWebApp` + `manifest` + theme-color wired in `layout.tsx` ### Supabase migrations - `011_user_profiles_web.sql` (already deployed): `user_profiles` (+RLS+trigger), `parlay_leg_frequency` (+RPC), `scan_history` - `012_web_caching_waitlist.sql` (NEW): `odds_cache` (TTL cache), `waitlist_signups`, `founder_pricing_seats` view, `prune_expired_odds_cache()` helper ### Backend - `src/app.js` — CORS middleware added (localhost dev + vyndr.app + *.vercel.app + FRONTEND_ORIGINS env var) - `package.json` — added `cors@2.8.5` ### Bug fixes - Scan page sibling-div JSX bug fixed (rewritten from scratch) - Lockfile warning silenced via `next.config.ts` `turbopack.root` (already in place) - Auth callback rewritten to use Supabase JS session API instead of raw localStorage parse ## Environment variables (set in Vercel + Railway) ### Vercel (Next.js) - `NEXT_PUBLIC_SUPABASE_URL` — Supabase project URL - `NEXT_PUBLIC_SUPABASE_ANON_KEY` — Supabase anon key - `SUPABASE_SERVICE_ROLE_KEY` — service role (server-only, NEVER expose to client) - `NEXT_PUBLIC_SITE_URL` — `https://vyndr.app` - `BACKEND_URL` — Railway URL of Express grading engine - `NEXT_PUBLIC_API_URL` — same as BACKEND_URL (for legacy client fetches) - `NEXT_PUBLIC_NBA_SERVICE_URL` — FastAPI nba_api wrapper URL - `NEXAPAY_API_KEY` — bearer token from NexaPay dashboard - `NEXAPAY_WEBHOOK_SECRET` — HMAC secret from NexaPay dashboard - `NEXAPAY_API_URL` — defaults to `https://api.nexapay.one/v1` - `RESEND_API_KEY` — from resend.com - `RESEND_FROM_EMAIL` — defaults to `VYNDR ` - `NEXT_PUBLIC_POSTHOG_KEY` — PostHog project key (optional) - `NEXT_PUBLIC_POSTHOG_HOST` — defaults to `https://us.i.posthog.com` ### Railway (Express backend) - All existing engine vars (Odds API key, Supabase, etc.) - `FRONTEND_ORIGINS` — comma-separated additional CORS origins (optional; defaults cover localhost + vyndr.app + *.vercel.app) ## Vercel deployment 1. Repo root → `/home/kev/mastermind/vyndr` 2. Root Directory in Vercel project settings: `web` 3. Framework Preset: Next.js (auto-detected) 4. Build Command: `npm run build` (default) 5. Install Command: `npm install` (default) 6. Output Directory: `.next` (default; we use `output: 'standalone'`) 7. Node version: 20.x or 22.x 8. Add all env vars from the list above ## Railway deployment (backend) 1. `railway.toml` already configured in repo root 2. Connect GitHub → Deploy from `main` 3. Set env vars (same as Vercel backend list) 4. Get URL → set `BACKEND_URL` in Vercel ## NexaPay configuration 1. Create NexaPay account → get API key + webhook secret 2. Webhook URL: `https://vyndr.app/api/webhook/nexapay` 3. Webhook events to enable: `payment.succeeded`, `payment.failed`, `payment.refunded`, `subscription.canceled` 4. Settlement wallet: USDC on Polygon (or your preferred chain) 5. Set `NEXAPAY_*` env vars in Vercel ## Resend configuration 1. Create Resend account → verify `vyndr.app` domain 2. Add DNS records (SPF, DKIM, DMARC) from Resend dashboard 3. Create API key → set `RESEND_API_KEY` in Vercel 4. Test: trigger a signup, check the welcome email arrives ## Supabase Auth setup 1. Run migrations `011_user_profiles_web.sql` and `012_web_caching_waitlist.sql` (Supabase SQL editor or CLI) 2. Auth → Providers → enable Email/Password (default) 3. Auth → Providers → enable Google: paste client ID/secret from Google Cloud Console 4. Auth → URL Configuration → Site URL: `https://vyndr.app` 5. Auth → URL Configuration → Redirect URLs: `https://vyndr.app/auth/callback`, `http://localhost:3001/auth/callback` --- ## What Has Shipped (Backend — Already Live) ### Phase 1 — Foundation (COMPLETE) - Feature 1.1 — Odds API Integration - Feature 1.2 — NBA_API Stats Wrapper (FastAPI microservice) - Feature 1.3 — Prop Analysis Engine (6-step grading pipeline) - Feature 1.4 — Database Schema (9 tables, RLS, triggers) - Feature 1.5 — Bet Submission (3 methods + performance tracking) ### Phase 2 — Core Product (COMPLETE) - Feature 2.1 — Parlay Scan (correlation detection, monetization) - Feature 2.2 — Line Movement + Cascade Detection ### Phase 3 — Web MVP (COMPLETE) - Feature 3.1 — Landing Page + Blog (Next.js, MDX, VYNDR voice, SEO) - Feature 3.2 — Scan UI (leg builder, grade results, upgrade pitch) - Feature 3.3 — Bet Tracker (performance dashboard, quick slip, settle flow) - Feature 3.4 — Stripe Integration (checkout, webhooks, portal, founder codes) ## Also Shipped (Separate Repo) ### Mastermind Agency Site - `/home/kev/mastermind/agency-site/` - Glitch aesthetic, scan lines, CRT flicker, JetBrains Mono - Home, VYNDR case study, Contact pages ### Phase 1 Additions — Intelligence Engine (COMPLETE) - Addition 1 — Stats endpoints (parlays-graded, public, live props) - Addition 2 — Dynamic role profile system (8 roles, Shannon entropy, conditional profiles) - Addition 3 — Player selector (placeholder — Cowork handles design) - Addition 4 — Parlay probability (phi coefficient, juice-adjusted EV, correlation math) - Addition 5 — MLB prop grading (14 stat types, 10 kill conditions, 30 parks, weather API) - Addition 6 — Intelligence engine (similarity, evolution/PELT, line discrepancy, alt line, Bayesian, model trainer) - Addition 7 — Lineup watch speed (role activation detection framework) - Addition 8 — Database additions (7 new tables, migration 003, indexes, RLS) - Addition 9 — Design system update (forest green, Hero tagline, live props strip, DemoScan result card) - Addition 10 — Accuracy ledger page (/ledger) - Addition 11 — Marketplace page (/marketplace, waitlist, honeypot) - Addition 12 — ARCHITECTURE.md v1.0 - Permanent: FOUNDER_NOTE constant (immutable, tested for integrity) - Permanent: X-VYNDR-Mission header on all API responses ## Also Shipped (Separate Repo) ### Mastermind Agency Site - `/home/kev/mastermind/agency-site/` - Glitch aesthetic, scan lines, CRT flicker, JetBrains Mono - Home, VYNDR case study, Contact pages ## Test Summary - Node.js: 662 tests passing (unit + integration) — 357 original + 187 ship + 65 supplement + 35 patch + 45 security - Python: 27 tests passing - Total: 689 tests, all green - 8 new test files: shipInfrastructure, shipGradingEngine, shipDataSources, shipResolution, shipSchemeClassifier, supplementSystems, patchIntegration, securityAudit - Next.js project builds (pending Vercel deploy) ## Active Blockers - BLOCKER-003: WSL2 DNS cannot resolve *.supabase.co - Migrations 003-010 need manual apply via Supabase SQL Editor ### Phase 1 Additions Part 2 (COMPLETE) - Addition 13 — Simplified scan selector (sport toggle NBA/MLB, player search, stat dropdown, line pre-fill from Odds API) - Addition 14 — PostHog analytics integration (5 events: scan_completed, grade_viewed, upgrade_cta_clicked, prop_shared, alt_line_viewed) - Addition 15 — Affiliate database (Migration 004: referral_codes, referral_conversions, affiliate_payouts, wallet_addresses, RLS on all) - Addition 16 — Scheme intelligence data layer (schemeClassifier.js: PnR coverage classification DROP/SWITCH/HEDGE/MIXED/UNKNOWN, 8-possession min, 6hr cache, graceful degradation, silent logging to model_predictions_extended) - **Scheme intelligence: data layer active, user activation pending Day 31** ## Phase 2 Pending - Model learning loop (Feature 4.1 spec exists) - Player selector UI completion (Cowork handles design) - Full parlay probability UI integration - Real-time lineup watch CRON implementation - Evolution watch UI on ledger page - Pre-registered predictions system activation - Physical ledger fulfillment - Education library content ## Manual Actions Required 1. Paste SQL migrations 003-010 in Supabase SQL Editor (in order) 2. Run `node scripts/seedRoleProfiles.js` after NBA API access configured 3. Set Stripe env vars (STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, price IDs) 4. Set NEXT_PUBLIC_POSTHOG_KEY env var for PostHog analytics 5. Set ODDS_API_KEY env var for Odds API 6. Set SUPABASE_URL + SUPABASE_SERVICE_ROLE_KEY for Python service 7. Deploy Next.js frontend to Vercel 8. Start Python service: `cd src/services/python && pip install -r requirements.txt && python3 app.py` 9. Set up GitHub Actions crons: lineup monitoring (15min), morning odds (10am ET), pre-game odds (90min), weather (30min), nightly resolution (2am ET) 10. Run cold_start_boot() on first launch (seeds reporters, loads data files) 11. SHADOW_MODE=True for first 2 weeks — grades logged but not published to capper ## Session Log ### Sessions 1-6 — 2026-03-21/22 - Built all backend: Phase 1 + Phase 2 + Feature 1.5 - 221 backend tests passing ### Session 7 — 2026-03-22 - Built Feature 3.1: Landing page + blog (Hero, Pricing, Blog/MDX, Auth pages) - Built Mastermind Agency Site (glitch aesthetic, 5 pages) - Built Features 3.2 + 3.3: Scan UI + Bet Tracker - Built Feature 3.4: Stripe Integration (checkout, webhooks, portal, founder codes) - ALL FEATURES COMPLETE - Total: 237 tests (210 Node.js + 27 Python), all green ### Session 8 — 2026-03-28 - Built all 12 Phase 1 additions in single session - 68 new tests (305 total), all green - New services: roleProfileEngine, roleStabilityEngine, similarityEngine, evolutionEngine, lineDiscrepancyDetector, altLineScanner, bayesianEngine, modelTrainer, correlationMath, mlbGrader, mlbKillConditions, mlbStatsClient - New routes: stats, props, waitlist - New frontend: LivePropsStrip, ledger page, marketplace page - New constants: founderNote, mlbParks - New middleware: mission header - Migration 003: 7 new tables with indexes and RLS - Python microservice: evolutionEngine.py (Flask/PELT on port 5001) - ARCHITECTURE.md v1.0 created ### Session 9 — 2026-04-12 - Built 4 Phase 1 Part 2 additions - 52 new tests (357 total), all green - New component: SimplifiedSelector (sport toggle, player search, stat dropdown, line pre-fill) - PostHog analytics: 5 tracked events, initialized in layout.tsx - Migration 004: 4 affiliate tables (referral_codes, referral_conversions, affiliate_payouts, wallet_addresses) - New service: schemeClassifier.js (PnR coverage classification, 6hr cache, graceful degradation) - Scheme intelligence: data layer active, user activation pending Day 31 ### Session 10 — 2026-04-13 (SHIP BUILD v5.1) - Built complete dual-sport grading engine from vyndr-SHIP.md spec - 187 new tests (544 total), all green across 38 test suites - **Phase 1 — Infrastructure:** - Flask app.py with blueprints, health check, rate limiting (60/min default, 20/min grade), flask-cors, /api/docs - evolutionEngine.py moved to blueprints/evolution.py (structural only — logic unchanged) - utils: retry.py, data_warehouse.py (game-day TTL), bayesian.py (per-stat-type weights, skewness, data sufficiency curve), edge_calculator.py (real edge + quarter-Kelly), context_aggregator.py (15 factors), similarity.py (min 0.7), regime_detector.py (disabled <20 games), blind_spot_detector.py (worst 5%), supabase_client.py - Data files: park_factors.json (30 parks, lat/lng, roof_status), reporter_database.json (80+ handles), timezone_map.json (30 arenas), grade_thresholds.json, odds_api_config.json - requirements.txt with all 15 dependencies - Cold start boot sequence with reporter seeding - **Phase 2 — Data Sources:** - blueprints/synergy.py (team play types, matchup, tracking, defensive scheme) - blueprints/nba_context.py (teammate impact, game script, home/road, rest/travel, matchup pace, foul trouble, B2B stat-specific, positional defense, usage-efficiency, playoff modifiers, NBA sub-scores endpoint) - blueprints/lineup_intelligence.py (3-source architecture, reporter trust tiers, tweet parsing, two-stage grading, reporter-line correlation) - blueprints/odds_scanner.py (free tier 2 pulls/day, odds warehouse, line movement detection, slate scanner) - utils/weather.py (Open-Meteo, continuous 30min, dome detection, regrade triggers) - utils/archetypes.py (5 pitcher dimensions, 5 batter dimensions, 6 NBA dimensions — ALL with weight_profiles, batting order, batter approach, pitcher identity, weight blending) - schemeClassifier.js enhanced: Synergy-first with regex fallback, backward compatible - **Phase 3 — Grading Engines:** - blueprints/mlb.py (14-step pipeline, pitcher/batter profiles, ABS challenge system with player-specific discipline score, TTO decay, platoon-specific opponent quality, lineup protection, day/night, bullpen state, catcher framing) - blueprints/image_grade.py (OCR pipeline with low-confidence confirmation) - utils/sportsbooks.py (10 books, parlay grading with correlation check, phi coefficient) - utils/capper.py (pick numbers, breaking alerts, daily recap, miss autopsy) - **Phase 4 — Self-Improving Loop:** - blueprints/resolution.py (nightly job: actuals from nba_api/MLB-StatsAPI, hit/miss, CLV, alignment, joint outcomes, calibration triggers) - blueprints/calibration.py (point-biserial weights, global offset, Brier score, blind spots, CLV/alignment reports) - **Phase 5 — Database + Tests:** - Migration 005: lineup_scheme_data - Migration 006: nba_data_cache, mlb_data_cache, grade_outcomes (ALL ship columns incl discipline_score, CLV, alignment), player_calibrated_weights - Migration 007: lineup_updates, reporter_trust (with source_type + starting_trust), odds_warehouse, ship_line_movements, reporter_line_correlation, api_health_log, global_calibration, ship_joint_outcomes - 5 new test files covering infrastructure, grading engine, data sources, resolution pipeline, scheme classifier enhancement - **Key Spec Compliance:** - Grade thresholds LOCKED (A+ through F) - SHADOW_MODE = True (first 2 weeks) - Bayesian weights are INITIAL ESTIMATES (marked as such) - Abstention check BEFORE data cap - Point-biserial bounds 0.05-0.50, global offset ±0.15 - Real edge with vig + quarter-Kelly - Brier + CLV from day one - Capper A- and above ONLY - ABS is CHALLENGE system (successful challenges don't deplete) - Foul trouble widens std, not mean - Stat-specific B2B adjustments - Matchup-specific pace (home 60/40) - Positional defense (tracking > roster position) - Usage-efficiency tradeoff (-1.5% TS per +5% usage) - Tier limits documented but NOT enforced (gate manually later) - Node.js stays Node.js, Python is data/utility layer via HTTP ### Session 10c — 2026-04-13 (FINAL INTEGRATION PATCH) - Applied 15-item integration patch — wiring + features + infrastructure - 35 new tests (644 total), all green across 40 test suites - **Wiring (items 1-5):** - Scratch → redistribution → re-grade → alt line scan → alert chain in lineup_intelligence.py - Slate scan → alt line auto-scan for A-grades in odds_scanner.py - Nightly resolution steps 14-18: coaching update, player-out history, evolution scan, unconventional data collection, monthly validation - Migration 009: supplement columns on grade_outcomes (coaching_context, redistribution_context, evolution_flag, alt_line_opportunity, unconventional_factors) + unconventional_factor_data table - API docs updated with 7 supplement endpoints - **Features (items 6-10):** - MLB lineup shift logic (PA multiplier changes when player scratched) - high_leverage_hook_tendency added to MLB coaching schema - Evolution persistence check (3 games before public promotion, false positive detection) - Unconventional daily data collection + monthly validation functions - Alt line ladder mode (ALT_LINE_MODE env var — 'manual' generates probability ladder) - **Infrastructure (items 11-15):** - 5 GitHub Actions YAML files: nightly (2am ET), morning odds (10am ET), pre-game (3pm/5pm/6:30pm ET), reporter poll (every 15min), weather (every 30min) - scripts/seed_historical.py — one-time historical data seeder (NBA 2024-25 + MLB 2024) - railway.toml (Flask service, port 5001, health check) - web/vercel.json (Next.js deployment) - MLB coaching helper functions for historical seeding - **Product is DEPLOYMENT-READY** ### Session 10d — 2026-04-13 (SECURITY AUDIT) - Applied 19-item security hardening pass — Ryan Montgomery panel reviewed - 45 new tests (689 total), all green across 41 test suites - **Authentication (items 1, 8, 11):** - utils/auth.py: require_auth (JWT with issuer check) + require_service_role (BETONBLK_INTERNAL_KEY) - PyJWT added to requirements.txt - BETONBLK_INTERNAL_KEY separates cron auth from service key — service key never leaves Railway - **Input Security (items 3, 10, 13):** - utils/validation.py: whitelist stat types, sanitize strings (strip SQL/HTML), validate line 0-500, image upload (magic bytes, 10MB max, PNG/JPEG/GIF), parlay legs 2-12 - OCR rate limit 3/min, max 2 concurrent - MAX_CONTENT_LENGTH 1MB globally, 413 JSON response - **Network Security (items 2, 12):** - CORS locked to ALLOWED_ORIGINS env var (no more wildcard) - Real IP from X-Forwarded-For for rate limiter and security logger - **Error Handling (item 9):** - Production returns generic "Internal server error" — no stack traces - 404, 405, 413, 429 all return JSON - **Monitoring (items 4, 5, 6, 15, 17, 18):** - Security headers: X-Frame-Options DENY, HSTS, CSP, nosniff, XSS protection, Server removed - utils/security_logger.py: request logging, rate tracking, SQL injection detection, security_events table - utils/env_check.py: startup validation, exits on missing required vars, never logs secrets - security-scan.yml: weekly pip-audit + npm audit - security.txt: /.well-known/security.txt with contact - 90-day security event retention cleanup + weekly security digest (50+ events per IP = action required) - **Infrastructure (items 7, 14, 16, 19):** - Migration 010: security_events table with RLS - Supabase client timeout guidance, retry with 30s default timeout - Source code secret scan test (sk_live_, eyJhbGci, sbp_) - .gitignore: .env, .env.local, .env.production, *.pem, *.key, .vercel/ ### Session 10b — 2026-04-13 (SUPPLEMENT BUILD) - Built 5 intelligence supplement systems — ADDITIVE, no existing code modified - 65 new tests (609 total), all green across 39 test suites - **System 1 — Coaching Tendency Database:** - blueprints/coaching.py (NEW) — per-coach NBA + MLB tendencies, nightly update from game logs, shift detection (15%+ threshold on last 15 vs season baseline) - 12 NBA fields (pace, 3PT rate, ISO freq, PnR usage, rotation depth, late-game player, score-state lineups, second-unit patterns, redistribution profile, shot location, timeout tendency) - 10 MLB fields (starter hook, quick hook, bullpen philosophy, IBB rate, PH freq, bunts, closer-only, platoon, lineup consistency, challenge aggressiveness) - **System 2 — Usage Redistribution Engine:** - blueprints/redistribution.py (NEW) — two-layer calculation (Layer A: minutes redistribution from historical player-out data + coaching rotation depth; Layer B: offensive system change from archetype shifts) - Uses coaching database, applies usage-efficiency tradeoff (-1.5% TS per +5% usage) - Three tiers: primary (>=0.20 boost, >=0.75 confidence), secondary (>=0.10, >=0.60), tertiary (>=0.05) - Auto-grades at 15%+ boost / 0.65+ confidence, formats 60-second absorption alerts - **System 3 — Alt Line Scanner:** - Added to existing odds_scanner.py — auto-runs on A-grade props after slate scan - Pulls alt lines from odds_warehouse, calculates model probability via Bayesian norm_cdf - Real edge with vig on each alt, finds optimal (best EV/dollar) - Only recommends if alt edge exceeds standard by 3%+ - **System 4 — Unconventional Data Pipeline:** - blueprints/unconventional.py (NEW) — validation gate for non-traditional correlates - 500 instance minimum, Pearson r > 0.15, Bonferroni-corrected p-value - 5 tracked factors: altitude, contract year, referee crew history, travel distance (pre-validated), arena altitude - Factors only enter grading engine AFTER passing validation - **System 5 — Player Evolution Alerting:** - Added to existing evolution.py — daily scan across multiple metrics simultaneously - NBA: usage_rate, assist_rate, three_pa_rate, fg_pct, minutes - MLB: k_rate, bb_rate, exit_velocity, hard_hit_pct, fb_velo - PLAYER_EVOLUTION_DETECTED when 2+ metrics show concurrent inflection (10%+ change, 15 game minimum) - Timestamped records in evolution_detections table, Evolution Watch content formatter - **Migration 008:** coaching_tendencies, player_out_history, evolution_detections, unconventional_validations (all with indexes + RLS) - **Integration:** 3 new blueprints registered in app.py (coaching_bp, redistribution_bp, unconventional_bp), evolution + odds_scanner extended with new endpoints