Add persistent AFK reserves and recovery (Refs #151)
CI / checks (push) Successful in 7m7s

This commit is contained in:
2026-10-17 16:57:26 -04:00
parent 7f2205e9c4
commit d723f23d67
22 changed files with 2646 additions and 16 deletions
+40
View File
@@ -0,0 +1,40 @@
import { json, isHttpError } from '@sveltejs/kit';
import { authenticateBank } from '$lib/server/auth/bank.js';
import { afkRequest, type AfkAction } from '$lib/server/fleet/afk.js';
import { jsonBody } from '$lib/server/request-body.js';
export async function POST({ request, params }: { request: Request; params: { action: string } }) {
const headers = { 'Cache-Control': 'no-store' };
const authentication = authenticateBank(request);
if (!authentication.ok)
return json(
{ ok: false, code: authentication.code },
{ status: authentication.status, headers }
);
if (!['balance', 'event', 'purchase', 'reserve', 'start', 'settle'].includes(params.action))
return json({ ok: false, code: 'invalid_action' }, { status: 404, headers });
if (
request.headers.get('content-type')?.split(';')[0].trim().toLowerCase() !==
'application/json'
)
return json({ ok: false, code: 'invalid_content_type' }, { status: 415, headers });
let value: unknown;
try {
value = await jsonBody(request, 4096);
} catch (cause) {
if (isHttpError(cause, 413)) throw cause;
return json({ ok: false, code: 'invalid_request' }, { status: 400, headers });
}
try {
const { body, status } = afkRequest(
params.action as AfkAction,
value,
authentication.server,
authentication.instanceId
);
return json(body, { status, headers });
} catch {
console.error('AFK transaction failed; request may be retried with the same identity.');
return json({ ok: false, code: 'unavailable' }, { status: 503, headers });
}
}
+10
View File
@@ -0,0 +1,10 @@
import { error, json } from '@sveltejs/kit';
import { jsonBody } from '$lib/server/request-body.js';
import { afkCorrectSession } from '$lib/server/fleet/afk.js';
/** Human reconciliation is restricted to sessions already confirmed stopped. */
export async function POST({ request, locals }: { request: Request; locals: App.Locals }) {
if (!locals.user || locals.user.role !== 'admin') error(403, 'Administrator access required.');
const result = afkCorrectSession(await jsonBody(request, 4096), locals.user.id);
return json(result.body, { status: result.status, headers: { 'Cache-Control': 'no-store' } });
}