diff --git a/backend/src/lib/handlers/cards.ts b/backend/src/lib/handlers/cards.ts new file mode 100644 index 0000000..1bea5f8 --- /dev/null +++ b/backend/src/lib/handlers/cards.ts @@ -0,0 +1,42 @@ +import { route, HandlerContext, HttpError } from '@/lib/router'; +import { getDb } from '@/lib/db'; + +route('player/:steamId/card-levels', ['GET'], (ctx: HandlerContext) => { + const db = getDb(); + const row = db.prepare('SELECT card_levels FROM card_levels WHERE steam_id = ?').get(ctx.params.steamId) as any; + return { card_levels: row ? JSON.parse(row.card_levels) : {} }; +}); + +route('player/:steamId/card-levels', ['PUT'], (ctx: HandlerContext) => { + const { card_levels } = ctx.body as any; + const db = getDb(); + db.prepare(` + INSERT INTO card_levels (steam_id, card_levels, updated_at) VALUES (?, ?, datetime('now')) + ON CONFLICT(steam_id) DO UPDATE SET card_levels = ?, updated_at = datetime('now') + `).run(ctx.params.steamId, JSON.stringify(card_levels || {}), JSON.stringify(card_levels || {})); + return { success: true }; +}); + +route('player/:steamId/decks', ['GET'], (ctx: HandlerContext) => { + const db = getDb(); + const decks = db.prepare('SELECT * FROM decks WHERE steam_id = ? ORDER BY deck_index').all(ctx.params.steamId); + return decks.map((d: any) => ({ ...d, cards: JSON.parse(d.cards || '[]') })); +}); + +route('player/:steamId/decks/:index', ['GET'], (ctx: HandlerContext) => { + const db = getDb(); + const deck = db.prepare('SELECT * FROM decks WHERE steam_id = ? AND deck_index = ?').get(ctx.params.steamId, parseInt(ctx.params.index)) as any; + if (!deck) return { name: 'New Deck', cards: [] }; + return { ...deck, cards: JSON.parse(deck.cards || '[]') }; +}); + +route('player/:steamId/decks/:index', ['PUT'], (ctx: HandlerContext) => { + const { name, cards } = ctx.body as any; + const db = getDb(); + const idx = parseInt(ctx.params.index); + db.prepare(` + INSERT INTO decks (steam_id, deck_index, name, cards, updated_at) VALUES (?, ?, ?, ?, datetime('now')) + ON CONFLICT(steam_id, deck_index) DO UPDATE SET name = ?, cards = ?, updated_at = datetime('now') + `).run(ctx.params.steamId, idx, name || 'My Deck', JSON.stringify(cards || []), name || 'My Deck', JSON.stringify(cards || [])); + return { success: true }; +}); diff --git a/backend/src/lib/handlers/leaderboard.ts b/backend/src/lib/handlers/leaderboard.ts new file mode 100644 index 0000000..94f8989 --- /dev/null +++ b/backend/src/lib/handlers/leaderboard.ts @@ -0,0 +1,33 @@ +import { route, HandlerContext } from '@/lib/router'; +import { getDb } from '@/lib/db'; + +route('leaderboard', ['GET'], (ctx: HandlerContext) => { + const limit = parseInt(ctx.searchParams.get('limit') || '20'); + const offset = parseInt(ctx.searchParams.get('offset') || '0'); + const board = ctx.searchParams.get('board') || 'rating'; + const db = getDb(); + + let rows: any[]; + if (board === 'wealth') { + rows = db.prepare( + 'SELECT steam_id, player_name, (free_currency + donate_currency) as score, free_currency, donate_currency FROM players ORDER BY score DESC LIMIT ? OFFSET ?' + ).all(limit, offset); + } else { + rows = db.prepare(` + SELECT p.steam_id, p.player_name, + COUNT(CASE WHEN gh.result = 'win' THEN 1 END) as wins, + COUNT(gh.id) as total_games + FROM players p + LEFT JOIN game_history gh ON p.steam_id = gh.steam_id + GROUP BY p.steam_id + ORDER BY wins DESC + LIMIT ? OFFSET ? + `).all(limit, offset); + } + + return { + leaderboard: rows, + total: (db.prepare('SELECT COUNT(*) as c FROM players').get() as any).c, + board, + }; +});