Diagnose stalled administrator decisions from the operations page

Add an owner-only, read-only sample of at most ten live rooms whose public
pending interaction — decision, response, Truthtrance or phase opening — has
been idle longest, with the room code, idle duration, interaction kind, turn
and phase. GET /api/admin/operations?stalled=1 repeats live owner authority,
answers no-store, rejects any other query combination and repairs nothing;
paused, closed, removed and archived rooms are excluded and no private game
content is selected. The aggregate sample adds stalledRooms and
oldestStalledChange for the same predicate.

Owner-only unit coverage asserts the counters, the oldest stalled write, the
bounded oldest-first order, every exclusion boundary, idle arithmetic, the
absence of private content and the owner recheck after demotion. The anonymous
HTTP boundary denies the new read, and the full HTTP integration suite passes
55/55 against a local build of this revision. The panel was verified in the
real browser against six hours of genuine idle rooms, which caught and fixed a
missing threshold field in the response.

No game, seat, saved state, deployment, public start or played-save conversion
changes.
This commit is contained in:
Quintine committed 2026-10-07 17:51:08 +11:00
1 parent e05a205a47
commit 07c20ae806
10 files changed
+287 -11

No files matched your search

+7 -3
View File
@@ -1,6 +1,6 @@
import { env } from 'cloudflare:workers';
import { AdminError, requireAdmin } from '@/db/admin-access';
import { readAdminIntegrity, readAdminOperations } from '@/db/admin-operations';
import { ADMIN_STALL_MS, readAdminIntegrity, readAdminOperations, readAdminStalledDecisions } from '@/db/admin-operations';
import { adminFailure, adminResponse, adminToken } from '@/lib/admin-http';
import { buildRevision } from '@/lib/build-revision';
@@ -11,10 +11,14 @@ export async function GET(request: Request) {
if (expected && expected !== identity.id)
throw new AdminError('The signed-in administrator changed. Reload operations.', 401);
const query = new URL(request.url).searchParams;
if (query.size && (query.size !== 1 || query.get('integrity') !== '1'))
const reads = ['integrity', 'stalled'];
if (query.size && (query.size !== 1 || !reads.some(read => query.get(read) === '1')))
throw new AdminError('Invalid operations request.', 400);
if (query.has('integrity'))
if (query.get('integrity') === '1')
return adminResponse(await readAdminIntegrity(env.DB, identity));
if (query.get('stalled') === '1')
return adminResponse({ revision: buildRevision, observedAt: Date.now(),
stallMs: ADMIN_STALL_MS, stalled: await readAdminStalledDecisions(env.DB, identity) });
return adminResponse({ revision: buildRevision, ...await readAdminOperations(env.DB, identity) });
} catch (error) { return adminFailure(error); }
}