feat: add leaderboard and cards handlers

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
achmad
2026-05-29 16:37:18 +07:00
parent 88c69f534c
commit ee09d4037c
2 changed files with 75 additions and 0 deletions
+42
View File
@@ -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 };
});
+33
View File
@@ -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,
};
});