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>
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* 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
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user