Files
vosonandCursor f5b7011c45 Ship Steam login, D1 player sync, and cached「我」dashboard.
Players get a fast TTL-backed homepage (local profile / Cloudflare D1) with dense UI polish; login unlocks /home without blocking on every OpenDota refresh.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-01 01:24:30 +08:00

93 lines
2.6 KiB
JavaScript

/**
* GET /api/players/me — logged-in user's profile from D1; enqueue refresh if stale.
*/
import { sessionFromRequest } from "../auth/_steam_common.js";
import {
enqueueRefresh,
isStale,
jsonResponse,
loadPlayerBundle,
} from "./_db.js";
export async function onRequestGet(context) {
try {
const session = await sessionFromRequest(context);
if (!session || !session.account_id) {
return jsonResponse({ authenticated: false }, 401);
}
const env = context.env || {};
const accountId = Number(session.account_id);
if (!env.DB) {
return jsonResponse(
{ error: "database not configured", account_id: accountId },
503
);
}
// Ensure user row exists for first login.
const now = new Date().toISOString().replace(/\.\d{3}Z$/, "Z");
await env.DB.prepare(
`INSERT INTO users (account_id, steamid, personaname, avatar, public_share, created_at, last_login_at)
VALUES (?, ?, ?, ?, 0, ?, ?)
ON CONFLICT(account_id) DO UPDATE SET
personaname=COALESCE(excluded.personaname, users.personaname),
avatar=COALESCE(excluded.avatar, users.avatar),
last_login_at=excluded.last_login_at`
)
.bind(
accountId,
String(session.steamid || ""),
session.personaname || null,
session.avatar || null,
now,
now
)
.run();
let bundle = await loadPlayerBundle(env.DB, accountId);
const fetchedAt =
(bundle && bundle.availability && bundle.availability.fetched_at) ||
(bundle && bundle.enriched_at) ||
null;
let stale = !bundle || isStale(fetchedAt);
if (stale) {
await enqueueRefresh(env, {
kind: "login_refresh",
account_id: accountId,
steamid: session.steamid,
personaname: session.personaname,
avatar: session.avatar,
});
}
if (!bundle) {
return jsonResponse({
authenticated: true,
account_id: accountId,
personaname: session.personaname || null,
avatar: session.avatar || null,
public_share: false,
recent: [],
career: null,
recent_20: null,
top_heroes: [],
peers: [],
activity_180: null,
availability: {
status: "unknown",
note: "正在同步…",
complete: false,
stale: true,
},
stale: true,
});
}
if (bundle.availability) bundle.availability.stale = stale;
return jsonResponse({ ...bundle, authenticated: true, stale });
} catch (e) {
return jsonResponse(
{ error: "me failed", detail: String((e && e.message) || e) },
500
);
}
}