58 lines
2.3 KiB
TypeScript
58 lines
2.3 KiB
TypeScript
import { getGameDb, persist } from '@/lib/db/client';
|
|
import { getLocalPlayer, updateLocalPlayerEconomy } from '@/lib/db/localPlayer';
|
|
import { getStateSnapshot } from '@/lib/game/state';
|
|
import { tickNow } from '@/lib/sim/engine';
|
|
|
|
// TEST-ONLY hook (v0.31.0, ISS-055) — grants cash so the e2e suite can afford a second
|
|
// plane (ATR €200k vs the €20k starting balance). Disabled unless FLIGHT_TEST_HOOKS=1
|
|
// (set in docker-compose.yml for the e2e instance only); every other deployment 404s here.
|
|
// Sibling of /api/test/create-package — same gate, same conventions.
|
|
//
|
|
// POST /api/test/add-cash
|
|
// body { amount?: number } — a positive finite number when provided; defaults to €1M.
|
|
// Adds to account.cash (rounded to cents) and returns the full state snapshot.
|
|
|
|
const DEFAULT_AMOUNT = 1_000_000;
|
|
|
|
export async function POST(req: Request) {
|
|
if (process.env.FLIGHT_TEST_HOOKS !== '1') {
|
|
return Response.json({ error: 'test hooks disabled' }, { status: 404 });
|
|
}
|
|
|
|
let body: unknown = {};
|
|
try {
|
|
const text = await req.text();
|
|
body = text ? JSON.parse(text) : {};
|
|
} catch {
|
|
return Response.json({ error: 'invalid JSON body' }, { status: 400 });
|
|
}
|
|
if (typeof body !== 'object' || body === null || Array.isArray(body)) {
|
|
return Response.json({ error: 'body must be a JSON object' }, { status: 400 });
|
|
}
|
|
const input = body as Record<string, unknown>;
|
|
for (const key of Object.keys(input)) {
|
|
if (key !== 'amount') {
|
|
return Response.json({ error: `unknown field "${key}"` }, { status: 400 });
|
|
}
|
|
}
|
|
let amount = DEFAULT_AMOUNT;
|
|
if (input.amount !== undefined) {
|
|
if (typeof input.amount !== 'number' || !Number.isFinite(input.amount) || input.amount <= 0) {
|
|
return Response.json({ error: 'amount must be a positive finite number' }, { status: 400 });
|
|
}
|
|
amount = input.amount;
|
|
}
|
|
|
|
try {
|
|
const inst = await getGameDb();
|
|
await tickNow(); // clock is current before the snapshot we return (same as siblings)
|
|
const player = await getLocalPlayer(inst);
|
|
await updateLocalPlayerEconomy(inst, { cash: Math.round((player.cash + amount) * 100) / 100 });
|
|
await persist(inst);
|
|
return Response.json(await getStateSnapshot());
|
|
} catch (err) {
|
|
console.error('test hook failed', err);
|
|
return Response.json({ error: 'test hook failed' }, { status: 500 });
|
|
}
|
|
}
|