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
-14
@@ -127,27 +127,27 @@ describe('loadPackage', () => {
|
||||
await expectActionError(loadPackage(inst, 'p-open', 'plane-starter'), 409, /at LEMD/);
|
||||
});
|
||||
|
||||
it('rejects loading when the plane has no free slot (capacity from catalog)', async () => {
|
||||
it('rejects loading when the plane has no payload room (maxPayloadKg from catalog)', async () => {
|
||||
const inst = await freshDb('load-full.db');
|
||||
await insertOpenPackage(inst, 'p-new');
|
||||
// Fill all atr72 slots with loaded cargo…
|
||||
for (let i = 0; i < PLANE_TYPES.atr72.capacity; i++) {
|
||||
await insertOpenPackage(inst, `p-fill-${i}`, { status: 'loaded', planeId: 'plane-starter' });
|
||||
await insertOpenPackage(inst, 'p-new', { weightKg: 1_000 });
|
||||
// Fill past maxPayloadKg with loaded cargo…
|
||||
const chunk = Math.floor(PLANE_TYPES.atr72.maxPayloadKg / 3) + 1; // 3 chunks > max
|
||||
for (let i = 0; i < 3; i++) {
|
||||
await insertOpenPackage(inst, `p-fill-${i}`, { status: 'loaded', planeId: 'plane-starter', weightKg: chunk });
|
||||
}
|
||||
|
||||
await expectActionError(loadPackage(inst, 'p-new', 'plane-starter'), 409, /no free slots/i);
|
||||
await expectActionError(loadPackage(inst, 'p-new', 'plane-starter'), 409, /no payload room/i);
|
||||
});
|
||||
|
||||
it('counts expired packages as occupying their slot too', async () => {
|
||||
it('counts expired packages as occupying their payload too', async () => {
|
||||
const inst = await freshDb('load-expiredslot.db');
|
||||
await insertOpenPackage(inst, 'p-new');
|
||||
// capacity − 1 loaded + 1 expired = full.
|
||||
for (let i = 0; i < PLANE_TYPES.atr72.capacity - 1; i++) {
|
||||
await insertOpenPackage(inst, `p-fill-${i}`, { status: 'loaded', planeId: 'plane-starter' });
|
||||
}
|
||||
await insertOpenPackage(inst, 'p-expired-slot', { status: 'expired', planeId: 'plane-starter' });
|
||||
await insertOpenPackage(inst, 'p-new', { weightKg: 1_000 });
|
||||
// Half + half (expired) leaves no room — each alone would fit.
|
||||
const half = Math.floor(PLANE_TYPES.atr72.maxPayloadKg / 2) + 1;
|
||||
await insertOpenPackage(inst, 'p-loaded-half', { status: 'loaded', planeId: 'plane-starter', weightKg: half });
|
||||
await insertOpenPackage(inst, 'p-expired-slot', { status: 'expired', planeId: 'plane-starter', weightKg: half });
|
||||
|
||||
await expectActionError(loadPackage(inst, 'p-new', 'plane-starter'), 409, /no free slots/i);
|
||||
await expectActionError(loadPackage(inst, 'p-new', 'plane-starter'), 409, /no payload room/i);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user