const { savePick, getUserStats, saveUserStats, getProfile, saveProfile } = require('./_storage'); const corsHeaders = { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'POST, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization', }; function err(code, msg) { return { statusCode: code, headers: corsHeaders, body: JSON.stringify({ error: msg }) }; } function genPickId() { return Date.now().toString(36) + Math.random().toString(36).slice(2, 8); } exports.handler = async function(event) { if (event.httpMethod === 'OPTIONS') return { statusCode: 204, headers: corsHeaders, body: '' }; if (event.httpMethod !== 'POST') return err(405, 'Method not allowed'); let body; try { body = JSON.parse(event.body || '{}'); } catch { return err(400, 'Invalid JSON'); } const { user_id, // Memberstack member.id user_email, username, // display name (opcionális, profilból jön) match_id, // odds API match ID sport_key, // pl. soccer_epl home_team, away_team, commence_time, // ISO string market, // 'h2h' | 'totals' | 'spreads' selection, // h2h: 'home'|'away'|'draw'; totals: 'over'|'under'; spreads: 'home'|'away' odds, // szám, pl. 1.95 point, // totals: 2.5, 3.5...; spreads: -1.5, +1.5...; h2h: null/undefined stake_units = 1, // virtuális tét egységben } = body; // Alap validáció if (!user_id) return err(401, 'Nincs bejelentkezve'); if (!match_id || !sport_key || !selection || !odds) return err(400, 'Hiányos adatok'); if (typeof odds !== 'number' || odds < 1.01 || odds > 1000) return err(400, 'Érvénytelen odds'); if (stake_units !== 1) return err(400, 'A tét egységben 1 lehet'); // Market és selection összepárosítás const allowedMarkets = ['h2h', 'totals', 'spreads']; const mkt = market || 'h2h'; if (!allowedMarkets.includes(mkt)) return err(400, 'Érvénytelen market'); if (mkt === 'h2h') { if (!['home', 'away', 'draw'].includes(selection)) return err(400, 'Érvénytelen 1X2 tipp'); } else if (mkt === 'totals') { if (!['over', 'under'].includes(selection)) return err(400, 'Érvénytelen O/U tipp'); if (typeof point !== 'number') return err(400, 'Hiányzó határérték'); } else if (mkt === 'spreads') { if (!['home', 'away'].includes(selection)) return err(400, 'Érvénytelen spread tipp'); if (typeof point !== 'number') return err(400, 'Hiányzó hendikep'); } // Időbeli validáció: meccs nem kezdődhetett még el const matchTime = new Date(commence_time).getTime(); if (!matchTime || isNaN(matchTime)) return err(400, 'Érvénytelen időpont'); if (matchTime <= Date.now()) return err(400, 'A meccs már elkezdődött'); // Duplikáció check — ugyanaz a market+selection ugyanazon meccsen 2× ne legyen const { listUserPicks } = require('./_storage'); const existingPicks = await listUserPicks(user_id); const dup = existingPicks.find(p => p.match_id === match_id && p.market === mkt && p.selection === selection && (p.point ?? null) === (point ?? null) ); if (dup) return err(400, 'Erre a tippre már leadtál fogadást'); // Profile mentése/frissítése (ha névvel jött) if (username) { const existing = await getProfile(user_id); if (!existing || existing.username !== username) { await saveProfile(user_id, { user_id, email: user_email || existing?.email || null, username: username.trim().slice(0, 32), updated_at: new Date().toISOString(), }); } } // Pick tárolása const pickId = genPickId(); const pick = { pick_id: pickId, user_id, match_id, sport_key, home_team, away_team, commence_time, market: mkt, selection, odds, point: point ?? null, stake_units, status: 'pending', // pending | won | lost | push | void created_at: new Date().toISOString(), graded_at: null, result_score: null, }; await savePick(user_id, pickId, pick); // User stats inkrementálás (pending) const stats = await getUserStats(user_id); stats.total += 1; stats.pending += 1; stats.last_updated = new Date().toISOString(); await saveUserStats(user_id, stats); return { statusCode: 200, headers: corsHeaders, body: JSON.stringify({ ok: true, pick }), }; };