Package weight, payload capacity and per-kg payout (ISS-045)
CI / build + unit + e2e (pull_request) Successful in 8m2s
CI / build + unit + e2e (pull_request) Successful in 8m2s
Packages carry a real weightKg (unit weight x count with +/-30% jitter), plane capacity becomes maxPayloadKg instead of 6 slots, load validation sums cargo weight against the payload, and the payout gains a per-kg part. Loadout display shows tonnage; OpenAPI swaps CatalogEntry.capacity for maxPayloadKg and adds PackageState.weightKg.
This commit is contained in:
@@ -14,11 +14,13 @@ import { tickNow } from '@/lib/sim/engine';
|
||||
// same gate, same conventions.
|
||||
//
|
||||
// POST /api/test/create-package
|
||||
// body { originIcao?: string, destIcao?: string, deadlineOffsetMs?: number }
|
||||
// body { originIcao?: string, destIcao?: string, deadlineOffsetMs?: number, weightKg?: number }
|
||||
// - ICACOs must exist in the airport dataset and differ (400 otherwise);
|
||||
// omitted endpoints are picked at random by generatePackage.
|
||||
// - deadlineOffsetMs defaults to a normal 6–72h game-time window (NOT the short
|
||||
// hook deadline of expire-package) — pass an explicit value to override.
|
||||
// - weightKg (v0.27.0) forces the package weight instead of the RNG draw, so e2e
|
||||
// flows that load several packages can stay under the plane's payload deterministically.
|
||||
// Returns 201 + the created package row.
|
||||
|
||||
export async function POST(req: Request) {
|
||||
@@ -38,7 +40,7 @@ export async function POST(req: Request) {
|
||||
}
|
||||
const input = body as Record<string, unknown>;
|
||||
for (const key of Object.keys(input)) {
|
||||
if (key !== 'originIcao' && key !== 'destIcao' && key !== 'deadlineOffsetMs') {
|
||||
if (key !== 'originIcao' && key !== 'destIcao' && key !== 'deadlineOffsetMs' && key !== 'weightKg') {
|
||||
return Response.json({ error: `unknown field "${key}"` }, { status: 400 });
|
||||
}
|
||||
}
|
||||
@@ -50,6 +52,9 @@ export async function POST(req: Request) {
|
||||
if (input.deadlineOffsetMs !== undefined && (typeof input.deadlineOffsetMs !== 'number' || !Number.isFinite(input.deadlineOffsetMs))) {
|
||||
return Response.json({ error: 'deadlineOffsetMs must be a finite number' }, { status: 400 });
|
||||
}
|
||||
if (input.weightKg !== undefined && (typeof input.weightKg !== 'number' || !Number.isFinite(input.weightKg) || input.weightKg <= 0)) {
|
||||
return Response.json({ error: 'weightKg must be a positive finite number' }, { status: 400 });
|
||||
}
|
||||
|
||||
try {
|
||||
const inst = await getGameDb();
|
||||
@@ -79,6 +84,7 @@ export async function POST(req: Request) {
|
||||
deadlineOffsetMs: input.deadlineOffsetMs as number | undefined,
|
||||
originIcao: input.originIcao as string | undefined,
|
||||
destIcao: input.destIcao as string | undefined,
|
||||
weightKg: input.weightKg as number | undefined,
|
||||
});
|
||||
await inst.db.insert(schema.packages).values(created);
|
||||
await persist(inst);
|
||||
|
||||
Reference in New Issue
Block a user