The tally: what the ledgers add up to, in the about panel
Ported from the game kit (7aa0553). GET /api/tally scans the ledgers, replays each duel, and returns the counts, cached a minute; the duel's own lines come from tallyOf on the final state (wins by slaying or by surrender, draws, wizards slain and yielded, stopped moments). The hall fetches it when the about panel opens. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0141G6xqLeNRYEtviLWSB5Up
This commit is contained in:
1 parent
66dd3bc10e
commit
7c60d19ad3
6 files changed
+205
-1
No files matched your search
@@ -20,6 +20,7 @@
|
||||
// POST /api/rooms/:id/report {token?, happened, expected} a report to the keeper, pinned to the turn
|
||||
// POST /api/reports/:id/image <image bytes> a screenshot for a report just filed
|
||||
// POST /api/reports/mine {seats: [{roomId, token}]} your reports and the keeper's replies
|
||||
// GET /api/tally what the ledgers add up to, for the hall
|
||||
// POST /api/reports/:id/answer {roomId, token, text} your word under the keeper's reply
|
||||
//
|
||||
// Caddy serves the static site and proxies /api and /ws here.
|
||||
@@ -31,6 +32,7 @@ import { RateLimit } from './ratelimit';
|
||||
import { IMAGE_MAX_BYTES, Reports } from './reports';
|
||||
import { RoomError, Rooms, SPECTATOR } from './rooms';
|
||||
import { Store } from './store';
|
||||
import { Tallies } from './tally';
|
||||
import { dirname } from 'node:path';
|
||||
|
||||
const PORT = Number(process.env.PORT ?? 8788);
|
||||
@@ -53,6 +55,7 @@ process.on('unhandledRejection', (reason) => {
|
||||
const rooms = new Rooms(new Store(DATA_DIR), { name: KEEPER, zone: KEEPER_TZ });
|
||||
/** Reports live beside the room ledgers, not among them. */
|
||||
const reports = new Reports(dirname(DATA_DIR));
|
||||
const tallies = new Tallies(new Store(DATA_DIR));
|
||||
const PUBLIC_URL = (process.env.WH_PUBLIC_URL ?? 'https://hands.kestrelsnest.social').replace(/\/$/, '');
|
||||
/** Opening rooms and taking seats are open to anyone; a script gets a few dozen an hour, not thousands. */
|
||||
const doors = new RateLimit(40, 60 * 60 * 1000);
|
||||
@@ -196,6 +199,7 @@ async function handle(req: IncomingMessage, res: ServerResponse): Promise<void>
|
||||
const url = new URL(req.url ?? '/', 'http://localhost');
|
||||
const parts = url.pathname.split('/').filter(Boolean);
|
||||
if (parts[0] === 'api' && parts[1] === 'reports') return handleReports(req, res, parts);
|
||||
if (parts[0] === 'api' && parts[1] === 'tally' && parts.length === 2 && req.method === 'GET') return send(res, 200, tallies.get());
|
||||
if (parts[0] === 'api' && parts[1] === 'transfer' && parts.length === 2 && req.method === 'POST') {
|
||||
if (!claims.allow(clientOf(req))) throw new RoomError('Too many claims from here just now; try again later.', 429);
|
||||
const body = await readBody(req);
|
||||
|
||||
Reference in new issue
Block a user