Ship item nicknames, Tiny fear override, and ensure-match API.

Add 冰眼/蛇矛 aliases, correct Tiny fears to Hydra's Breath, and fix production match detail POST 405.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
voson
2026-08-01 04:05:48 +08:00
co-authored by Cursor
parent cafd0651b1
commit 820c3fb1f1
17 changed files with 656 additions and 53 deletions
@@ -1,8 +1,10 @@
/**
* GET /api/players/:account_id/:match_id — match detail from R2 (authz via D1).
* If R2 missing/raw, fetch+normalize from OpenDota (same shape as local ensure-match).
*/
import { sessionFromRequest } from "../../auth/_steam_common.js";
import { jsonResponse } from "../_db.js";
import { ensureNormalizedMatch } from "../_match.js";
export async function onRequestGet(context) {
try {
@@ -23,27 +25,16 @@ export async function onRequestGet(context) {
if (!user) return jsonResponse({ error: "not found" }, 404);
if (!self && !user.public_share) return jsonResponse({ error: "private" }, 404);
const row = await env.DB.prepare(
`SELECT r2_key FROM player_matches WHERE account_id = ? AND match_id = ?`
)
.bind(accountId, matchId)
.first();
const key = (row && row.r2_key) || `matches/${matchId}.json`;
if (!env.MATCHES) return jsonResponse({ error: "storage not configured" }, 503);
const obj = await env.MATCHES.get(key);
if (!obj) return jsonResponse({ error: "match not found" }, 404);
const text = await obj.text();
return new Response(text, {
status: 200,
headers: {
"Content-Type": "application/json; charset=utf-8",
"Cache-Control": "no-store",
},
});
const { match, error } = await ensureNormalizedMatch(env, accountId, matchId);
if (!match) {
return jsonResponse({ error: error || "match not found" }, 404);
}
return jsonResponse(match);
} catch (e) {
return jsonResponse(
{ error: "match get failed", detail: String((e && e.message) || e) },
500
);
}
}
}