S3 (a1): affiliate + partner plumbing
Zero out-of-pocket; everything config-flip-ready but DISABLED/organic. - BOOK IT deep links: web/src/lib/bookLinks.js + affiliateConfig.js (all books enabled:false, Impact/Partnerize param shapes documented, empty params skipped). Wired into StatStrip BookItTeaser (real anchor now) + scan hand-off links. Every book anchor renders rel="sponsored noopener noreferrer" (BOOK_LINK_REL). - Best-price marker: slateAdapter.detectBestBook (only when >=2 books post the SAME line and prices differ — absent beats wrong) + subtle signal-green dot in StatStrip. Slate.groupByGame threads the grouped per-book rows (books[]) onto PropRowProp instead of discarding them. - Partner refs: ?ref=CODE -> vyndr_ref cookie (90d, first-touch, PartnerRefCapture in layout) -> signup metadata partner_ref -> internal GET /api/partners/report/:code (requireInternalAuth; honest zeros + note until the TODO migration in docs/PARTNERS.md adds user_profiles.partner_ref — NOT run). Stripe promo-code convention: partner code == promotion code, verbatim. - Tests: +41 (2398 -> 2439, 209 suites); bookItTeaser + vyndrCoreScreens invariants updated to the new (stronger) rel contract. Web build exit 0. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
||||
import type { Session, User } from '@supabase/supabase-js';
|
||||
import { getBrowserSupabase } from '@/lib/supabase';
|
||||
import { readRefCookie } from '@/lib/partnerRef';
|
||||
|
||||
export type Tier = 'free' | 'analyst' | 'desk';
|
||||
|
||||
@@ -135,10 +136,17 @@ export default function AuthProvider({ children }: { children: React.ReactNode }
|
||||
async (email, password, ageVerified) => {
|
||||
if (!ageVerified) return { error: 'You must confirm you are 21 or older.' };
|
||||
if (!supabase) return { error: 'Auth is not configured. Set Supabase env vars.' };
|
||||
// A1 S3 — partner attribution: forward the first-touch vyndr_ref
|
||||
// cookie (set by PartnerRefCapture on a ?ref=CODE visit) into the
|
||||
// signup metadata. The internal /api/partners report reads it.
|
||||
const partnerRef = readRefCookie(document.cookie);
|
||||
const { error } = await supabase.auth.signUp({
|
||||
email,
|
||||
password,
|
||||
options: { emailRedirectTo: `${window.location.origin}/auth/callback` },
|
||||
options: {
|
||||
emailRedirectTo: `${window.location.origin}/auth/callback`,
|
||||
...(partnerRef ? { data: { partner_ref: partnerRef } } : {}),
|
||||
},
|
||||
});
|
||||
if (error) return { error: error.message };
|
||||
return {};
|
||||
|
||||
Reference in New Issue
Block a user