1 line
45 KiB
JSON
1 line
45 KiB
JSON
{"repo": "carlosvfv/dk-lotto-ai-", "files": {"supabase/functions/generate-premium/index.ts": {"c1f91f8bce5cc9cc1789e9430bf1597ed5c2ee49": {"t": 1785745609.343787, "n": 8951, "h": "b968bb637a7c844f", "c": "// Supabase Edge Function: Generate Premium Numbers (Redeploy trigger)\nimport { serve } from \"https://deno.land/std@0.168.0/http/server.ts\"\nimport { createClient } from 'https://esm.sh/@supabase/supabase-js@2'\n\nconst corsHeaders = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',\n}\n\nserve(async (req) => {\n // Handle CORS\n if (req.method === 'OPTIONS') {\n return new Response('ok', { headers: corsHeaders })\n }\n\n try {\n const { game, licenseKey } = await req.json()\n\n // Initialize Supabase client\n const supabaseClient = createClient(\n Deno.env.get('SUPABASE_URL') ?? '',\n Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? ''\n )\n\n // --- LICENSE VALIDATION ---\n\n let isTrial = false\n let license = null\n\n if (!licenseKey) {\n return new Response(\n JSON.stringify({ error: 'License key required', code: 'MISSING_KEY' }),\n { status: 401, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n }\n\n if (licenseKey === 'FREE-TRIAL-GIFT') {\n isTrial = true\n license = { active: true, credits: 1, id: 'trial' }\n } else {\n const { data: dbLic, error: fetchError } = await supabaseClient\n .from('licenses')\n .select('*')\n .eq('key_code', licenseKey)\n .single()\n\n if (fetchError || !dbLic) {\n return new Response(\n JSON.stringify({ error: 'Invalid license key', code: 'INVALID_KEY' }),\n { status: 403, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n }\n license = dbLic\n }\n\n if (!license.active) {\n return new Response(\n JSON.stringify({ error: 'License inactive', code: 'INACTIVE_KEY' }),\n { status: 403, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n }\n\n if (license.credits <= 0) {\n return new Response(\n JSON.stringify({ error: 'No credits', code: 'NO_CREDITS' }),\n { status: 402, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n }\n\n // Deduct credit\n let newCredits = license.credits\n if (!isTrial && license.credits < 900000) {\n newCredits = license.credits - 1\n await supabaseClient\n .from('licenses')\n .update({ credits: newCredits })\n .eq('id', license.id)\n }\n\n // --- GET CACHED LOTTERY DATA ---\n const { data: cachedData } = await supabaseClient\n .from('lottery_cache')\n .select('*')\n .eq('game', game)\n .single()\n\n let historicalData: any, analysis: any;\n\n if (!cachedData) {\n // FALLBACK TO REAL STATISTICAL DATA IF DB IS EMPTY\n // This ensures the AI always has valid input data\n console.log('Using embedded statistical data fallback');\n\n const realStats = {\n lotto: {\n hotNumbers: [21, 36, 11, 12, 15, 33, 18, 24, 7, 28, 31, 14, 9, 23, 6],\n coldNumbers: [1, 2, 5, 10, 13, 17, 19, 20, 22, 25, 27, 29, 30, 32, 34, 35],\n totalDraws: 100\n },\n vikinglotto: {\n hotNumbers: [15, 28, 42, 11, 33, 21, 38, 7, 44, 19, 27, 31, 9, 18, 24],\n coldNumbers: [1, 2, 4, 8, 10, 13, 17, 20, 23, 26, 29, 32, 35, 37, 40, 43, 46, 48],\n totalDraws: 100\n },\n eurojackpot: {\n hotNumbers: [19, 27, 35, 21, 33, 38, 15, 42, 7, 11, 28, 31, 44, 18, 9],\n coldNumbers: [1, 2, 4, 6, 8, 10, 13, 16, 20, 23, 26, 29, 32, 36, 40, 43, 46, 48, 50],\n totalDraws: 100\n }\n };\n\n analysis = realStats[game] || realStats.lotto;\n historicalData = []; // Fallback empty history if cache missing\n } else {\n historicalData = cachedData.data;\n analysis = cachedData.analysis;\n }\n\n // --- CALL DEEPSEEK AI ---\n const gameConfig = getGameConfig(game)\n const aiResult = await generateAINumbers(game, analysis, gameConfig, historicalData)\n\n // Save to history\n await supabaseClient\n .from('prediction_history')\n .insert({\n game,\n numbers: aiResult.numbers,\n stars: aiResult.stars || [],\n confidence: aiResult.confidence,\n license_key: licenseKey,\n ai_reasoning: aiResult.reasoning\n })\n\n return new Response(\n JSON.stringify({\n success: true,\n remainingCredits: isTrial ? 0 : newCredits,\n game,\n numbers: aiResult.numbers,\n stars: aiResult.stars || [],\n analysis: {\n hotNumbers: analysis.hotNumbers,\n coldNumbers: analysis.coldNumbers,\n totalDrawsAnalyzed: analysis.totalDraws,\n },\n ai: {\n confidence: aiResult.confidence,\n reasoning: aiResult.reasoning,\n }\n }),\n { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n\n } catch (error) {\n return new Response(\n JSON.stringify({ error: error.message }),\n { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n }\n})\n\nfunction getGameConfig(game: string) {\n const configs = {\n lotto: { range: 36, count: 7 },\n vikinglotto: { range: 48, count: 6, vikingRange: 5 },\n eurojackpot: { range: 50, count: 5, starRange: 12, starCount: 2 }\n }\n return configs[game] || configs.lotto\n}\n\nasync function generateAINumbers(game: string, analysis: any, gameConfig: any, historicalData: any) {\n const DEEPSEEK_API_KEY = Deno.env.get('DEEPSEEK_API_KEY')\n\n const prompt = `You are analyzing ${game} lottery data. Based on this statistical analysis:\nHot numbers: ${analysis.hotNumbers.join(', ')}\nCold numbers: ${analysis.coldNumbers.join(', ')}\nTotal draws analyzed: ${analysis.totalDraws}\n\nGenerate ${gameConfig.count} numbers between 1-${gameConfig.range} using \"Mean Reversion Theory\".\nRespond ONLY with JSON: {\"numbers\": [1,2,3...], \"confidence\": 0.85, \"reasoning\": \"brief explanation\"}`\n\n try {\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), 30000) // 30s timeout\n\n const response = await fetch('https://api.deepseek.com/v1/chat/completions', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${DEEPSEEK_API_KEY}`\n },\n body: JSON.stringify({\n model: 'deepseek-reasoner',\n messages: [{ role: 'user', content: prompt }],\n max_tokens: 500\n }),\n signal: controller.signal\n })\n\n clearTimeout(timeout)\n\n const data = await response.json()\n const aiText = data.choices[0].message.content\n const aiData = JSON.parse(aiText)\n\n return {\n numbers: aiData.numbers,\n stars: gameConfig.starCount ? Array(gameConfig.starCount).fill(0).map(() => Math.floor(Math.random() * gameConfig.starRange) + 1) : [],\n confidence: aiData.confidence || 0.75,\n reasoning: aiData.reasoning || 'AI generated prediction'\n }\n } catch (error) {\n // Fallback: generate smart random\n console.error('DeepSeek timeout, using fallback')\n const numbers = generateSmartRandom(gameConfig.range, gameConfig.count, analysis)\n return {\n numbers,\n stars: gameConfig.starCount ? Array(gameConfig.starCount).fill(0).map(() => Math.floor(Math.random() * gameConfig.starRange) + 1) : [],\n confidence: 0.65,\n reasoning: 'Generated using statistical fallback method'\n }\n }\n}\n\nfunction generateSmartRandom(range: number, count: number, analysis: any) {\n const pool = []\n\n // Mix: 40% cold, 30% hot, 30% random\n const coldNums = analysis.coldNumbers.slice(0, Math.ceil(count * 0.4))\n const hotNums = analysis.hotNumbers.slice(0, Math.ceil(count * 0.3))\n\n pool.push(...coldNums)\n pool.push(...hotNums)\n\n while (pool.length < count) {\n const rand = Math.floor(Math.random() * range) + 1\n if (!pool.includes(rand)) pool.push(rand)\n }\n\n return pool.slice(0, count).sort((a, b) => a - b)\n}\n"}, "afc096702c2afcd1793258eb7747caf122649536": {"t": 1785754758.070444, "n": 8951, "h": "b968bb637a7c844f", "c": "// Supabase Edge Function: Generate Premium Numbers (Redeploy trigger)\nimport { serve } from \"https://deno.land/std@0.168.0/http/server.ts\"\nimport { createClient } from 'https://esm.sh/@supabase/supabase-js@2'\n\nconst corsHeaders = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',\n}\n\nserve(async (req) => {\n // Handle CORS\n if (req.method === 'OPTIONS') {\n return new Response('ok', { headers: corsHeaders })\n }\n\n try {\n const { game, licenseKey } = await req.json()\n\n // Initialize Supabase client\n const supabaseClient = createClient(\n Deno.env.get('SUPABASE_URL') ?? '',\n Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? ''\n )\n\n // --- LICENSE VALIDATION ---\n\n let isTrial = false\n let license = null\n\n if (!licenseKey) {\n return new Response(\n JSON.stringify({ error: 'License key required', code: 'MISSING_KEY' }),\n { status: 401, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n }\n\n if (licenseKey === 'FREE-TRIAL-GIFT') {\n isTrial = true\n license = { active: true, credits: 1, id: 'trial' }\n } else {\n const { data: dbLic, error: fetchError } = await supabaseClient\n .from('licenses')\n .select('*')\n .eq('key_code', licenseKey)\n .single()\n\n if (fetchError || !dbLic) {\n return new Response(\n JSON.stringify({ error: 'Invalid license key', code: 'INVALID_KEY' }),\n { status: 403, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n }\n license = dbLic\n }\n\n if (!license.active) {\n return new Response(\n JSON.stringify({ error: 'License inactive', code: 'INACTIVE_KEY' }),\n { status: 403, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n }\n\n if (license.credits <= 0) {\n return new Response(\n JSON.stringify({ error: 'No credits', code: 'NO_CREDITS' }),\n { status: 402, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n }\n\n // Deduct credit\n let newCredits = license.credits\n if (!isTrial && license.credits < 900000) {\n newCredits = license.credits - 1\n await supabaseClient\n .from('licenses')\n .update({ credits: newCredits })\n .eq('id', license.id)\n }\n\n // --- GET CACHED LOTTERY DATA ---\n const { data: cachedData } = await supabaseClient\n .from('lottery_cache')\n .select('*')\n .eq('game', game)\n .single()\n\n let historicalData: any, analysis: any;\n\n if (!cachedData) {\n // FALLBACK TO REAL STATISTICAL DATA IF DB IS EMPTY\n // This ensures the AI always has valid input data\n console.log('Using embedded statistical data fallback');\n\n const realStats = {\n lotto: {\n hotNumbers: [21, 36, 11, 12, 15, 33, 18, 24, 7, 28, 31, 14, 9, 23, 6],\n coldNumbers: [1, 2, 5, 10, 13, 17, 19, 20, 22, 25, 27, 29, 30, 32, 34, 35],\n totalDraws: 100\n },\n vikinglotto: {\n hotNumbers: [15, 28, 42, 11, 33, 21, 38, 7, 44, 19, 27, 31, 9, 18, 24],\n coldNumbers: [1, 2, 4, 8, 10, 13, 17, 20, 23, 26, 29, 32, 35, 37, 40, 43, 46, 48],\n totalDraws: 100\n },\n eurojackpot: {\n hotNumbers: [19, 27, 35, 21, 33, 38, 15, 42, 7, 11, 28, 31, 44, 18, 9],\n coldNumbers: [1, 2, 4, 6, 8, 10, 13, 16, 20, 23, 26, 29, 32, 36, 40, 43, 46, 48, 50],\n totalDraws: 100\n }\n };\n\n analysis = realStats[game] || realStats.lotto;\n historicalData = []; // Fallback empty history if cache missing\n } else {\n historicalData = cachedData.data;\n analysis = cachedData.analysis;\n }\n\n // --- CALL DEEPSEEK AI ---\n const gameConfig = getGameConfig(game)\n const aiResult = await generateAINumbers(game, analysis, gameConfig, historicalData)\n\n // Save to history\n await supabaseClient\n .from('prediction_history')\n .insert({\n game,\n numbers: aiResult.numbers,\n stars: aiResult.stars || [],\n confidence: aiResult.confidence,\n license_key: licenseKey,\n ai_reasoning: aiResult.reasoning\n })\n\n return new Response(\n JSON.stringify({\n success: true,\n remainingCredits: isTrial ? 0 : newCredits,\n game,\n numbers: aiResult.numbers,\n stars: aiResult.stars || [],\n analysis: {\n hotNumbers: analysis.hotNumbers,\n coldNumbers: analysis.coldNumbers,\n totalDrawsAnalyzed: analysis.totalDraws,\n },\n ai: {\n confidence: aiResult.confidence,\n reasoning: aiResult.reasoning,\n }\n }),\n { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n\n } catch (error) {\n return new Response(\n JSON.stringify({ error: error.message }),\n { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n }\n})\n\nfunction getGameConfig(game: string) {\n const configs = {\n lotto: { range: 36, count: 7 },\n vikinglotto: { range: 48, count: 6, vikingRange: 5 },\n eurojackpot: { range: 50, count: 5, starRange: 12, starCount: 2 }\n }\n return configs[game] || configs.lotto\n}\n\nasync function generateAINumbers(game: string, analysis: any, gameConfig: any, historicalData: any) {\n const DEEPSEEK_API_KEY = Deno.env.get('DEEPSEEK_API_KEY')\n\n const prompt = `You are analyzing ${game} lottery data. Based on this statistical analysis:\nHot numbers: ${analysis.hotNumbers.join(', ')}\nCold numbers: ${analysis.coldNumbers.join(', ')}\nTotal draws analyzed: ${analysis.totalDraws}\n\nGenerate ${gameConfig.count} numbers between 1-${gameConfig.range} using \"Mean Reversion Theory\".\nRespond ONLY with JSON: {\"numbers\": [1,2,3...], \"confidence\": 0.85, \"reasoning\": \"brief explanation\"}`\n\n try {\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), 30000) // 30s timeout\n\n const response = await fetch('https://api.deepseek.com/v1/chat/completions', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${DEEPSEEK_API_KEY}`\n },\n body: JSON.stringify({\n model: 'deepseek-reasoner',\n messages: [{ role: 'user', content: prompt }],\n max_tokens: 500\n }),\n signal: controller.signal\n })\n\n clearTimeout(timeout)\n\n const data = await response.json()\n const aiText = data.choices[0].message.content\n const aiData = JSON.parse(aiText)\n\n return {\n numbers: aiData.numbers,\n stars: gameConfig.starCount ? Array(gameConfig.starCount).fill(0).map(() => Math.floor(Math.random() * gameConfig.starRange) + 1) : [],\n confidence: aiData.confidence || 0.75,\n reasoning: aiData.reasoning || 'AI generated prediction'\n }\n } catch (error) {\n // Fallback: generate smart random\n console.error('DeepSeek timeout, using fallback')\n const numbers = generateSmartRandom(gameConfig.range, gameConfig.count, analysis)\n return {\n numbers,\n stars: gameConfig.starCount ? Array(gameConfig.starCount).fill(0).map(() => Math.floor(Math.random() * gameConfig.starRange) + 1) : [],\n confidence: 0.65,\n reasoning: 'Generated using statistical fallback method'\n }\n }\n}\n\nfunction generateSmartRandom(range: number, count: number, analysis: any) {\n const pool = []\n\n // Mix: 40% cold, 30% hot, 30% random\n const coldNums = analysis.coldNumbers.slice(0, Math.ceil(count * 0.4))\n const hotNums = analysis.hotNumbers.slice(0, Math.ceil(count * 0.3))\n\n pool.push(...coldNums)\n pool.push(...hotNums)\n\n while (pool.length < count) {\n const rand = Math.floor(Math.random() * range) + 1\n if (!pool.includes(rand)) pool.push(rand)\n }\n\n return pool.slice(0, count).sort((a, b) => a - b)\n}\n"}, "2902f096ec19143292890e55ad9f1c24a497045f": {"t": 1785754760.9022357, "n": 8932, "h": "2bd65f9abd19eaf1", "c": "// Supabase Edge Function: Generate Premium Numbers\nimport { serve } from \"https://deno.land/std@0.168.0/http/server.ts\"\nimport { createClient } from 'https://esm.sh/@supabase/supabase-js@2'\n\nconst corsHeaders = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',\n}\n\nserve(async (req) => {\n // Handle CORS\n if (req.method === 'OPTIONS') {\n return new Response('ok', { headers: corsHeaders })\n }\n\n try {\n const { game, licenseKey } = await req.json()\n\n // Initialize Supabase client\n const supabaseClient = createClient(\n Deno.env.get('SUPABASE_URL') ?? '',\n Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? ''\n )\n\n // --- LICENSE VALIDATION ---\n\n let isTrial = false\n let license = null\n\n if (!licenseKey) {\n return new Response(\n JSON.stringify({ error: 'License key required', code: 'MISSING_KEY' }),\n { status: 401, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n }\n\n if (licenseKey === 'FREE-TRIAL-GIFT') {\n isTrial = true\n license = { active: true, credits: 1, id: 'trial' }\n } else {\n const { data: dbLic, error: fetchError } = await supabaseClient\n .from('licenses')\n .select('*')\n .eq('key_code', licenseKey)\n .single()\n\n if (fetchError || !dbLic) {\n return new Response(\n JSON.stringify({ error: 'Invalid license key', code: 'INVALID_KEY' }),\n { status: 403, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n }\n license = dbLic\n }\n\n if (!license.active) {\n return new Response(\n JSON.stringify({ error: 'License inactive', code: 'INACTIVE_KEY' }),\n { status: 403, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n }\n\n if (license.credits <= 0) {\n return new Response(\n JSON.stringify({ error: 'No credits', code: 'NO_CREDITS' }),\n { status: 402, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n }\n\n // Deduct credit\n let newCredits = license.credits\n if (!isTrial && license.credits < 900000) {\n newCredits = license.credits - 1\n await supabaseClient\n .from('licenses')\n .update({ credits: newCredits })\n .eq('id', license.id)\n }\n\n // --- GET CACHED LOTTERY DATA ---\n const { data: cachedData } = await supabaseClient\n .from('lottery_cache')\n .select('*')\n .eq('game', game)\n .single()\n\n let historicalData: any, analysis: any;\n\n if (!cachedData) {\n // FALLBACK TO REAL STATISTICAL DATA IF DB IS EMPTY\n // This ensures the AI always has valid input data\n console.log('Using embedded statistical data fallback');\n\n const realStats = {\n lotto: {\n hotNumbers: [21, 36, 11, 12, 15, 33, 18, 24, 7, 28, 31, 14, 9, 23, 6],\n coldNumbers: [1, 2, 5, 10, 13, 17, 19, 20, 22, 25, 27, 29, 30, 32, 34, 35],\n totalDraws: 100\n },\n vikinglotto: {\n hotNumbers: [15, 28, 42, 11, 33, 21, 38, 7, 44, 19, 27, 31, 9, 18, 24],\n coldNumbers: [1, 2, 4, 8, 10, 13, 17, 20, 23, 26, 29, 32, 35, 37, 40, 43, 46, 48],\n totalDraws: 100\n },\n eurojackpot: {\n hotNumbers: [19, 27, 35, 21, 33, 38, 15, 42, 7, 11, 28, 31, 44, 18, 9],\n coldNumbers: [1, 2, 4, 6, 8, 10, 13, 16, 20, 23, 26, 29, 32, 36, 40, 43, 46, 48, 50],\n totalDraws: 100\n }\n };\n\n analysis = realStats[game] || realStats.lotto;\n historicalData = []; // Fallback empty history if cache missing\n } else {\n historicalData = cachedData.data;\n analysis = cachedData.analysis;\n }\n\n // --- CALL DEEPSEEK AI ---\n const gameConfig = getGameConfig(game)\n const aiResult = await generateAINumbers(game, analysis, gameConfig, historicalData)\n\n // Save to history\n await supabaseClient\n .from('prediction_history')\n .insert({\n game,\n numbers: aiResult.numbers,\n stars: aiResult.stars || [],\n confidence: aiResult.confidence,\n license_key: licenseKey,\n ai_reasoning: aiResult.reasoning\n })\n\n return new Response(\n JSON.stringify({\n success: true,\n remainingCredits: isTrial ? 0 : newCredits,\n game,\n numbers: aiResult.numbers,\n stars: aiResult.stars || [],\n analysis: {\n hotNumbers: analysis.hotNumbers,\n coldNumbers: analysis.coldNumbers,\n totalDrawsAnalyzed: analysis.totalDraws,\n },\n ai: {\n confidence: aiResult.confidence,\n reasoning: aiResult.reasoning,\n }\n }),\n { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n\n } catch (error) {\n return new Response(\n JSON.stringify({ error: error.message }),\n { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n }\n})\n\nfunction getGameConfig(game: string) {\n const configs = {\n lotto: { range: 36, count: 7 },\n vikinglotto: { range: 48, count: 6, vikingRange: 5 },\n eurojackpot: { range: 50, count: 5, starRange: 12, starCount: 2 }\n }\n return configs[game] || configs.lotto\n}\n\nasync function generateAINumbers(game: string, analysis: any, gameConfig: any, historicalData: any) {\n const DEEPSEEK_API_KEY = Deno.env.get('DEEPSEEK_API_KEY')\n\n const prompt = `You are analyzing ${game} lottery data. Based on this statistical analysis:\nHot numbers: ${analysis.hotNumbers.join(', ')}\nCold numbers: ${analysis.coldNumbers.join(', ')}\nTotal draws analyzed: ${analysis.totalDraws}\n\nGenerate ${gameConfig.count} numbers between 1-${gameConfig.range} using \"Mean Reversion Theory\".\nRespond ONLY with JSON: {\"numbers\": [1,2,3...], \"confidence\": 0.85, \"reasoning\": \"brief explanation\"}`\n\n try {\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), 30000) // 30s timeout\n\n const response = await fetch('https://api.deepseek.com/v1/chat/completions', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${DEEPSEEK_API_KEY}`\n },\n body: JSON.stringify({\n model: 'deepseek-reasoner',\n messages: [{ role: 'user', content: prompt }],\n max_tokens: 500\n }),\n signal: controller.signal\n })\n\n clearTimeout(timeout)\n\n const data = await response.json()\n const aiText = data.choices[0].message.content\n const aiData = JSON.parse(aiText)\n\n return {\n numbers: aiData.numbers,\n stars: gameConfig.starCount ? Array(gameConfig.starCount).fill(0).map(() => Math.floor(Math.random() * gameConfig.starRange) + 1) : [],\n confidence: aiData.confidence || 0.75,\n reasoning: aiData.reasoning || 'AI generated prediction'\n }\n } catch (error) {\n // Fallback: generate smart random\n console.error('DeepSeek timeout, using fallback')\n const numbers = generateSmartRandom(gameConfig.range, gameConfig.count, analysis)\n return {\n numbers,\n stars: gameConfig.starCount ? Array(gameConfig.starCount).fill(0).map(() => Math.floor(Math.random() * gameConfig.starRange) + 1) : [],\n confidence: 0.65,\n reasoning: 'Generated using statistical fallback method'\n }\n }\n}\n\nfunction generateSmartRandom(range: number, count: number, analysis: any) {\n const pool = []\n\n // Mix: 40% cold, 30% hot, 30% random\n const coldNums = analysis.coldNumbers.slice(0, Math.ceil(count * 0.4))\n const hotNums = analysis.hotNumbers.slice(0, Math.ceil(count * 0.3))\n\n pool.push(...coldNums)\n pool.push(...hotNums)\n\n while (pool.length < count) {\n const rand = Math.floor(Math.random() * range) + 1\n if (!pool.includes(rand)) pool.push(rand)\n }\n\n return pool.slice(0, count).sort((a, b) => a - b)\n}\n"}, "fcb9569776a5dc668fcc3c2879df8597a17a2e98": {"t": 1785754762.082267, "n": 9918, "h": "e3b55278c1cd73af", "c": "// Supabase Edge Function: Generate Premium Numbers\nimport { serve } from \"https://deno.land/std@0.168.0/http/server.ts\"\nimport { createClient } from 'https://esm.sh/@supabase/supabase-js@2'\n\nconst corsHeaders = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',\n}\n\nserve(async (req) => {\n // Handle CORS\n if (req.method === 'OPTIONS') {\n return new Response('ok', { headers: corsHeaders })\n }\n\n try {\n const { game, licenseKey } = await req.json()\n\n // Initialize Supabase client\n const supabaseClient = createClient(\n Deno.env.get('SUPABASE_URL') ?? '',\n Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? ''\n )\n\n // --- LICENSE VALIDATION ---\n // --- DIAGNOSTIC BYPASS ---\n if (licenseKey === 'FREE-TRIAL-GIFT') {\n const dummyStats = {}; // Mock stats\n return new Response(\n JSON.stringify({\n success: true,\n numbers: [10, 20, 30, 40, 50, 55, 60],\n stars: [1, 2],\n confidence: 99,\n remainingCredits: 999,\n ai: {\n reasoning: \"✅ DIAGNOSTIC MODE: Connection successful! The issue is likely in the DeepSeek API call or DB write. This proves the Frontend <-> Cloud link is working.\",\n confidence: 99,\n hotNumbersUsed: [10, 20],\n coldNumbersUsed: [60]\n },\n stats: dummyStats\n }),\n { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n }\n // -------------------------\n\n let isTrial = false\n let license = null\n\n if (!licenseKey) {\n return new Response(\n JSON.stringify({ error: 'License key required', code: 'MISSING_KEY' }),\n { status: 401, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n }\n\n if (licenseKey === 'FREE-TRIAL-GIFT') {\n isTrial = true\n license = { active: true, credits: 1, id: 'trial' }\n } else {\n const { data: dbLic, error: fetchError } = await supabaseClient\n .from('licenses')\n .select('*')\n .eq('key_code', licenseKey)\n .single()\n\n if (fetchError || !dbLic) {\n return new Response(\n JSON.stringify({ error: 'Invalid license key', code: 'INVALID_KEY' }),\n { status: 403, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n }\n license = dbLic\n }\n\n if (!license.active) {\n return new Response(\n JSON.stringify({ error: 'License inactive', code: 'INACTIVE_KEY' }),\n { status: 403, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n }\n\n if (license.credits <= 0) {\n return new Response(\n JSON.stringify({ error: 'No credits', code: 'NO_CREDITS' }),\n { status: 402, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n }\n\n // Deduct credit\n let newCredits = license.credits\n if (!isTrial && license.credits < 900000) {\n newCredits = license.credits - 1\n await supabaseClient\n .from('licenses')\n .update({ credits: newCredits })\n .eq('id', license.id)\n }\n\n // --- GET CACHED LOTTERY DATA ---\n const { data: cachedData } = await supabaseClient\n .from('lottery_cache')\n .select('*')\n .eq('game', game)\n .single()\n\n let historicalData: any, analysis: any;\n\n if (!cachedData) {\n // FALLBACK TO REAL STATISTICAL DATA IF DB IS EMPTY\n // This ensures the AI always has valid input data\n console.log('Using embedded statistical data fallback');\n\n const realStats = {\n lotto: {\n hotNumbers: [21, 36, 11, 12, 15, 33, 18, 24, 7, 28, 31, 14, 9, 23, 6],\n coldNumbers: [1, 2, 5, 10, 13, 17, 19, 20, 22, 25, 27, 29, 30, 32, 34, 35],\n totalDraws: 100\n },\n vikinglotto: {\n hotNumbers: [15, 28, 42, 11, 33, 21, 38, 7, 44, 19, 27, 31, 9, 18, 24],\n coldNumbers: [1, 2, 4, 8, 10, 13, 17, 20, 23, 26, 29, 32, 35, 37, 40, 43, 46, 48],\n totalDraws: 100\n },\n eurojackpot: {\n hotNumbers: [19, 27, 35, 21, 33, 38, 15, 42, 7, 11, 28, 31, 44, 18, 9],\n coldNumbers: [1, 2, 4, 6, 8, 10, 13, 16, 20, 23, 26, 29, 32, 36, 40, 43, 46, 48, 50],\n totalDraws: 100\n }\n };\n\n analysis = realStats[game] || realStats.lotto;\n historicalData = []; // Fallback empty history if cache missing\n } else {\n historicalData = cachedData.data;\n analysis = cachedData.analysis;\n }\n\n // --- CALL DEEPSEEK AI ---\n const gameConfig = getGameConfig(game)\n const aiResult = await generateAINumbers(game, analysis, gameConfig, historicalData)\n\n // Save to history\n await supabaseClient\n .from('prediction_history')\n .insert({\n game,\n numbers: aiResult.numbers,\n stars: aiResult.stars || [],\n confidence: aiResult.confidence,\n license_key: licenseKey,\n ai_reasoning: aiResult.reasoning\n })\n\n return new Response(\n JSON.stringify({\n success: true,\n remainingCredits: isTrial ? 0 : newCredits,\n game,\n numbers: aiResult.numbers,\n stars: aiResult.stars || [],\n analysis: {\n hotNumbers: analysis.hotNumbers,\n coldNumbers: analysis.coldNumbers,\n totalDrawsAnalyzed: analysis.totalDraws,\n },\n ai: {\n confidence: aiResult.confidence,\n reasoning: aiResult.reasoning,\n }\n }),\n { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n\n } catch (error) {\n return new Response(\n JSON.stringify({ error: error.message }),\n { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n }\n})\n\nfunction getGameConfig(game: string) {\n const configs = {\n lotto: { range: 36, count: 7 },\n vikinglotto: { range: 48, count: 6, vikingRange: 5 },\n eurojackpot: { range: 50, count: 5, starRange: 12, starCount: 2 }\n }\n return configs[game] || configs.lotto\n}\n\nasync function generateAINumbers(game: string, analysis: any, gameConfig: any, historicalData: any) {\n const DEEPSEEK_API_KEY = Deno.env.get('DEEPSEEK_API_KEY')\n\n const prompt = `You are analyzing ${game} lottery data. Based on this statistical analysis:\nHot numbers: ${analysis.hotNumbers.join(', ')}\nCold numbers: ${analysis.coldNumbers.join(', ')}\nTotal draws analyzed: ${analysis.totalDraws}\n\nGenerate ${gameConfig.count} numbers between 1-${gameConfig.range} using \"Mean Reversion Theory\".\nRespond ONLY with JSON: {\"numbers\": [1,2,3...], \"confidence\": 0.85, \"reasoning\": \"brief explanation\"}`\n\n try {\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), 30000) // 30s timeout\n\n const response = await fetch('https://api.deepseek.com/v1/chat/completions', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${DEEPSEEK_API_KEY}`\n },\n body: JSON.stringify({\n model: 'deepseek-reasoner',\n messages: [{ role: 'user', content: prompt }],\n max_tokens: 500\n }),\n signal: controller.signal\n })\n\n clearTimeout(timeout)\n\n const data = await response.json()\n const aiText = data.choices[0].message.content\n const aiData = JSON.parse(aiText)\n\n return {\n numbers: aiData.numbers,\n stars: gameConfig.starCount ? Array(gameConfig.starCount).fill(0).map(() => Math.floor(Math.random() * gameConfig.starRange) + 1) : [],\n confidence: aiData.confidence || 0.75,\n reasoning: aiData.reasoning || 'AI generated prediction'\n }\n } catch (error) {\n // Fallback: generate smart random\n console.error('DeepSeek timeout, using fallback')\n const numbers = generateSmartRandom(gameConfig.range, gameConfig.count, analysis)\n return {\n numbers,\n stars: gameConfig.starCount ? Array(gameConfig.starCount).fill(0).map(() => Math.floor(Math.random() * gameConfig.starRange) + 1) : [],\n confidence: 0.65,\n reasoning: 'Generated using statistical fallback method'\n }\n }\n}\n\nfunction generateSmartRandom(range: number, count: number, analysis: any) {\n const pool = []\n\n // Mix: 40% cold, 30% hot, 30% random\n const coldNums = analysis.coldNumbers.slice(0, Math.ceil(count * 0.4))\n const hotNums = analysis.hotNumbers.slice(0, Math.ceil(count * 0.3))\n\n pool.push(...coldNums)\n pool.push(...hotNums)\n\n while (pool.length < count) {\n const rand = Math.floor(Math.random() * range) + 1\n if (!pool.includes(rand)) pool.push(rand)\n }\n\n return pool.slice(0, count).sort((a, b) => a - b)\n}\n"}, "1479ffe81772d030ac331b6371d6586eca14d4a2": {"t": 1785754763.2973852, "n": 7891, "h": "cb27263ac761c95a", "c": "// Supabase Edge Function: Generate Premium Numbers\nimport { serve } from \"https://deno.land/std@0.168.0/http/server.ts\"\nimport { createClient } from 'https://esm.sh/@supabase/supabase-js@2'\n\nconst corsHeaders = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',\n}\n\nserve(async (req) => {\n // Handle CORS\n if (req.method === 'OPTIONS') {\n return new Response('ok', { headers: corsHeaders })\n }\n\n try {\n const { game, licenseKey } = await req.json()\n\n // Initialize Supabase client\n const supabaseClient = createClient(\n Deno.env.get('SUPABASE_URL') ?? '',\n Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? ''\n )\n\n // --- LICENSE VALIDATION ---\n let isTrial = false\n let license = null\n\n if (!licenseKey) {\n return new Response(\n JSON.stringify({ error: 'License key required', code: 'MISSING_KEY' }),\n { status: 401, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n }\n\n if (licenseKey === 'FREE-TRIAL-GIFT') {\n isTrial = true\n license = { active: true, credits: 1, id: 'trial' }\n } else {\n const { data: dbLic, error: fetchError } = await supabaseClient\n .from('licenses')\n .select('*')\n .eq('key_code', licenseKey)\n .single()\n\n if (fetchError || !dbLic) {\n return new Response(\n JSON.stringify({ error: 'Invalid license key', code: 'INVALID_KEY' }),\n { status: 403, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n }\n license = dbLic\n }\n\n if (!license.active) {\n return new Response(\n JSON.stringify({ error: 'License inactive', code: 'INACTIVE_KEY' }),\n { status: 403, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n }\n\n if (license.credits <= 0) {\n return new Response(\n JSON.stringify({ error: 'No credits', code: 'NO_CREDITS' }),\n { status: 402, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n }\n\n // Deduct credit\n let newCredits = license.credits\n if (!isTrial && license.credits < 900000) {\n newCredits = license.credits - 1\n await supabaseClient\n .from('licenses')\n .update({ credits: newCredits })\n .eq('id', license.id)\n }\n\n // --- GET CACHED LOTTERY DATA ---\n const { data: cachedData } = await supabaseClient\n .from('lottery_cache')\n .select('*')\n .eq('game', game)\n .single()\n\n if (!cachedData) {\n return new Response(\n JSON.stringify({ error: 'Data not available. Please try again later.' }),\n { status: 503, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n }\n\n const historicalData = cachedData.data\n const analysis = cachedData.analysis\n\n // --- CALL DEEPSEEK AI ---\n const gameConfig = getGameConfig(game)\n const aiResult = await generateAINumbers(game, analysis, gameConfig, historicalData)\n\n // Save to history\n await supabaseClient\n .from('prediction_history')\n .insert({\n game,\n numbers: aiResult.numbers,\n stars: aiResult.stars || [],\n confidence: aiResult.confidence,\n license_key: licenseKey,\n ai_reasoning: aiResult.reasoning\n })\n\n return new Response(\n JSON.stringify({\n success: true,\n remainingCredits: isTrial ? 0 : newCredits,\n game,\n numbers: aiResult.numbers,\n stars: aiResult.stars || [],\n analysis: {\n hotNumbers: analysis.hotNumbers,\n coldNumbers: analysis.coldNumbers,\n totalDrawsAnalyzed: analysis.totalDraws,\n },\n ai: {\n confidence: aiResult.confidence,\n reasoning: aiResult.reasoning,\n }\n }),\n { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n\n } catch (error) {\n return new Response(\n JSON.stringify({ error: error.message }),\n { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }\n )\n }\n})\n\nfunction getGameConfig(game: string) {\n const configs = {\n lotto: { range: 36, count: 7 },\n vikinglotto: { range: 48, count: 6, vikingRange: 5 },\n eurojackpot: { range: 50, count: 5, starRange: 12, starCount: 2 }\n }\n return configs[game] || configs.lotto\n}\n\nasync function generateAINumbers(game: string, analysis: any, gameConfig: any, historicalData: any) {\n const DEEPSEEK_API_KEY = Deno.env.get('DEEPSEEK_API_KEY')\n\n const prompt = `You are analyzing ${game} lottery data. Based on this statistical analysis:\nHot numbers: ${analysis.hotNumbers.join(', ')}\nCold numbers: ${analysis.coldNumbers.join(', ')}\nTotal draws analyzed: ${analysis.totalDraws}\n\nGenerate ${gameConfig.count} numbers between 1-${gameConfig.range} using \"Mean Reversion Theory\".\nRespond ONLY with JSON: {\"numbers\": [1,2,3...], \"confidence\": 0.85, \"reasoning\": \"brief explanation\"}`\n\n try {\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), 30000) // 30s timeout\n\n const response = await fetch('https://api.deepseek.com/v1/chat/completions', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${DEEPSEEK_API_KEY}`\n },\n body: JSON.stringify({\n model: 'deepseek-reasoner',\n messages: [{ role: 'user', content: prompt }],\n max_tokens: 500\n }),\n signal: controller.signal\n })\n\n clearTimeout(timeout)\n\n const data = await response.json()\n const aiText = data.choices[0].message.content\n const aiData = JSON.parse(aiText)\n\n return {\n numbers: aiData.numbers,\n stars: gameConfig.starCount ? Array(gameConfig.starCount).fill(0).map(() => Math.floor(Math.random() * gameConfig.starRange) + 1) : [],\n confidence: aiData.confidence || 0.75,\n reasoning: aiData.reasoning || 'AI generated prediction'\n }\n } catch (error) {\n // Fallback: generate smart random\n console.error('DeepSeek timeout, using fallback')\n const numbers = generateSmartRandom(gameConfig.range, gameConfig.count, analysis)\n return {\n numbers,\n stars: gameConfig.starCount ? Array(gameConfig.starCount).fill(0).map(() => Math.floor(Math.random() * gameConfig.starRange) + 1) : [],\n confidence: 0.65,\n reasoning: 'Generated using statistical fallback method'\n }\n }\n}\n\nfunction generateSmartRandom(range: number, count: number, analysis: any) {\n const pool = []\n\n // Mix: 40% cold, 30% hot, 30% random\n const coldNums = analysis.coldNumbers.slice(0, Math.ceil(count * 0.4))\n const hotNums = analysis.hotNumbers.slice(0, Math.ceil(count * 0.3))\n\n pool.push(...coldNums)\n pool.push(...hotNums)\n\n while (pool.length < count) {\n const rand = Math.floor(Math.random() * range) + 1\n if (!pool.includes(rand)) pool.push(rand)\n }\n\n return pool.slice(0, count).sort((a, b) => a - b)\n}\n"}}}} |