feat: add logging to cards/deck endpoints

Log method, path, steamId, card count, deck names, and errors for
all card-levels and decks API calls to help debug persistence issues.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
achmad
2026-05-30 05:41:26 +07:00
parent 2ca87af1b5
commit 998c3b5f8f
+47 -12
View File
@@ -1,60 +1,91 @@
import { route, HandlerContext, HttpError } from '@/lib/router';
import { getDb } from '@/lib/db';
function log(method: string, path: string, steamId: string, msg: string) {
console.log(`[Cards] ${method} ${path} steam=${steamId}${msg}`);
}
route('player/:steamId/card-levels', ['GET'], (ctx: HandlerContext) => {
const steamId = ctx.params.steamId;
log('GET', 'card-levels', steamId, 'loading card levels');
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) : {} };
const row = db.prepare('SELECT card_levels FROM card_levels WHERE steam_id = ?').get(steamId) as any;
const result = { card_levels: row ? JSON.parse(row.card_levels) : {} };
log('GET', 'card-levels', steamId, `returned ${Object.keys(result.card_levels).length} card levels`);
return result;
});
route('player/:steamId/card-levels', ['PUT'], (ctx: HandlerContext) => {
const steamId = ctx.params.steamId;
const { card_levels } = ctx.body as any;
const keys = card_levels ? Object.keys(card_levels) : [];
log('PUT', 'card-levels', steamId, `saving ${keys.length} card levels: ${JSON.stringify(keys.slice(0, 10))}${keys.length > 10 ? '...' : ''}`);
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 || {}));
`).run(steamId, JSON.stringify(card_levels || {}), JSON.stringify(card_levels || {}));
log('PUT', 'card-levels', steamId, 'saved successfully');
return { success: true };
});
route('player/:steamId/decks', ['GET'], (ctx: HandlerContext) => {
const steamId = ctx.params.steamId;
const db = getDb();
const rows = db.prepare('SELECT * FROM decks WHERE steam_id = ? ORDER BY deck_index').all(ctx.params.steamId) as any[];
const rows = db.prepare('SELECT * FROM decks WHERE steam_id = ? ORDER BY deck_index').all(steamId) as any[];
const decks: Record<string, any> = {};
for (const r of rows) {
decks[r.deck_index] = { name: r.name, cards: JSON.parse(r.cards || '[]') };
}
log('GET', 'decks', steamId, `returned ${Object.keys(decks).length} decks: indices=[${Object.keys(decks).join(',')}]`);
return { decks };
});
route('player/:steamId/decks/:index', ['GET'], (ctx: HandlerContext) => {
const steamId = ctx.params.steamId;
const idx = ctx.params.index;
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 || '[]') };
const deck = db.prepare('SELECT * FROM decks WHERE steam_id = ? AND deck_index = ?').get(steamId, parseInt(idx)) as any;
if (!deck) {
log('GET', `decks/${idx}`, steamId, 'not found, returning empty deck');
return { name: 'New Deck', cards: [] };
}
const cards = JSON.parse(deck.cards || '[]');
log('GET', `decks/${idx}`, steamId, `found deck="${deck.name}" with ${cards.length} cards`);
return { ...deck, cards };
});
route('player/:steamId/decks/:index', ['PUT'], (ctx: HandlerContext) => {
const steamId = ctx.params.steamId;
const idx = ctx.params.index;
const { name, cards } = ctx.body as any;
const cardCount = Array.isArray(cards) ? cards.length : 0;
log('PUT', `decks/${idx}`, steamId, `saving deck="${name || 'unnamed'}" with ${cardCount} cards: ${JSON.stringify(cards?.slice(0, 10))}${cardCount > 10 ? '...' : ''}`);
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 || []));
`).run(steamId, parseInt(idx), name || 'My Deck', JSON.stringify(cards || []), name || 'My Deck', JSON.stringify(cards || []));
log('PUT', `decks/${idx}`, steamId, 'saved successfully');
return { success: true };
});
route('player/:steamId/decks/:index', ['DELETE'], (ctx: HandlerContext) => {
const steamId = ctx.params.steamId;
const idx = ctx.params.index;
log('DELETE', `decks/${idx}`, steamId, 'deleting deck');
const db = getDb();
const idx = parseInt(ctx.params.index);
db.prepare('DELETE FROM decks WHERE steam_id = ? AND deck_index = ?').run(ctx.params.steamId, idx);
db.prepare('DELETE FROM decks WHERE steam_id = ? AND deck_index = ?').run(steamId, parseInt(idx));
log('DELETE', `decks/${idx}`, steamId, 'deleted successfully');
return { success: true };
});
route('player/:steamId/decks', ['PUT'], (ctx: HandlerContext) => {
const steamId = ctx.params.steamId;
const { decks: decksToSave } = ctx.body as any;
if (!decksToSave) throw new HttpError(400, 'decks required');
const indices = Object.keys(decksToSave);
log('PUT', 'decks (batch)', steamId, `saving ${indices.length} decks: indices=[${indices.join(',')}]`);
const db = getDb();
const upsert = db.prepare(`
INSERT INTO decks (steam_id, deck_index, name, cards, updated_at) VALUES (?, ?, ?, ?, datetime('now'))
@@ -63,9 +94,13 @@ route('player/:steamId/decks', ['PUT'], (ctx: HandlerContext) => {
const tx = db.transaction(() => {
for (const [indexStr, deck] of Object.entries(decksToSave)) {
const d = deck as any;
upsert.run(ctx.params.steamId, parseInt(indexStr), d.name || 'My Deck', JSON.stringify(d.cards || []), d.name || 'My Deck', JSON.stringify(d.cards || []));
const cards = d.cards || [];
const cardCount = Array.isArray(cards) ? cards.length : 0;
log('PUT', `decks/${indexStr} (batch)`, steamId, `deck="${d.name || 'unnamed'}" with ${cardCount} cards`);
upsert.run(steamId, parseInt(indexStr), d.name || 'My Deck', JSON.stringify(cards), d.name || 'My Deck', JSON.stringify(cards));
}
});
tx();
log('PUT', 'decks (batch)', steamId, `batch save of ${indices.length} decks completed`);
return { success: true };
});