extends SceneTree const InventoryServiceScript = preload("res://scripts/inventory/inventory_service.gd") const LogisticsRequestScript = preload("res://scripts/inventory/logistics_request.gd") const LogisticsDispatcherScript = preload("res://scripts/inventory/logistics_dispatcher.gd") const InventoryReservationScript = preload("res://scripts/inventory/inventory_reservation.gd") var _checks := 0 var _failures := 0 func _initialize() -> void: call_deferred("_run") func _run() -> void: print("S2: Inventory and Logistics") _test_reservation_limits_and_idempotency() _test_transfer_never_duplicates_stock() _test_expiration_rules() _test_orphan_repair_report() _test_dispatch_priority_capacity_and_tie_break() _test_dispatch_missing_carrier_preserves_reserved_load() _test_atomic_transfer_batches_match_sequential_operations() _test_idempotency_conflicts_are_preflighted() _test_request_transitions() _test_snapshot_round_trip_and_atomic_restore() _test_strict_snapshot_migration_and_id_tombstones() if _failures == 0: print("PASS: %d checks" % _checks) else: push_error("FAIL: %d of %d checks failed" % [_failures, _checks]) quit(_failures) func _test_reservation_limits_and_idempotency() -> void: var service = InventoryServiceScript.new() var added: Dictionary = service.add_stack(&"warehouse", &"meal", 10, 90, -1, 0, 2) _expect(added[&"ok"], "stock can be added to an owner inventory") var first: Dictionary = service.reserve_item( &"warehouse", &"meal", 7, &"cafeteria", &"service", 10, 60, &"reserve-a" ) _expect(first[&"ok"] and service.available_quantity(&"warehouse", &"meal", 10) == 3, "reservation reduces available but not physical quantity") var replay: Dictionary = service.reserve_item( &"warehouse", &"meal", 7, &"cafeteria", &"service", 10, 60, &"reserve-a" ) _expect(replay[&"ok"] and replay[&"replay"] and service.get_reservations(true).size() == 1, "reservation operation id replays without creating stock claims") var rejected: Dictionary = service.reserve_item( &"warehouse", &"meal", 4, &"kitchen", &"service", 10, 60, &"reserve-b" ) _expect(not rejected[&"ok"] and rejected[&"code"] == &"INSUFFICIENT_AVAILABLE", "over-reservation is rejected atomically") var reservation_id: StringName = first[&"reservation_ids"][0] var consumed: Dictionary = service.consume_reservation(reservation_id, &"consume-a", 20) var quantity_after := service.total_quantity(&"warehouse", &"meal") var consumed_again: Dictionary = service.consume_reservation(reservation_id, &"consume-b", 21) _expect(consumed[&"ok"] and quantity_after == 3, "consumption removes exactly the reserved physical stock") _expect(consumed_again[&"ok"] and consumed_again[&"replay"] and service.total_quantity(&"warehouse", &"meal") == quantity_after, "a consumed reservation cannot consume twice") _expect(service.validate_invariants()[&"ok"], "reserve and consume preserve quantity minus reserved invariant") func _test_transfer_never_duplicates_stock() -> void: var service = InventoryServiceScript.new() service.add_stack(&"source", &"material", 12, 75, 500, 3, 3) var before := service.total_quantity(&"source", &"material") + service.total_quantity(&"destination", &"material") var moved: Dictionary = service.transfer_available( &"source", &"destination", &"material", 5, &"transfer-a", 20 ) var after := service.total_quantity(&"source", &"material") + service.total_quantity(&"destination", &"material") _expect(moved[&"ok"] and before == after and after == 12, "owner transfer conserves global item quantity") _expect(service.total_quantity(&"source", &"material") == 7 and service.total_quantity(&"destination", &"material") == 5, "transfer subtracts source before adding destination") var replay: Dictionary = service.transfer_available( &"source", &"destination", &"material", 5, &"transfer-a", 20 ) _expect(replay[&"replay"] and service.total_quantity(&"destination", &"material") == 5, "transfer replay cannot duplicate destination stock") var reserved: Dictionary = service.reserve_item( &"source", &"material", 4, &"delivery-1", &"logistics", 21, 100, &"pickup-reserve" ) var pickup: Dictionary = service.transfer_reserved( reserved[&"reservation_ids"], &"carrier-cargo", &"pickup-a", 22 ) _expect(pickup[&"ok"] and pickup[&"weight"] == 12, "reserved pickup transfers the exact reserved weight") _expect(service.total_quantity(&"source", &"material") == 3 and service.total_quantity(&"carrier-cargo", &"material") == 4, "reserved pickup consumes reservation and creates cargo once") _expect(service.validate_invariants()[&"ok"], "available and reserved remain valid after transfer") func _test_expiration_rules() -> void: var service = InventoryServiceScript.new() var added: Dictionary = service.add_stack(&"cold-store", &"food", 8, 80, 30, 0, 1) var reservation: Dictionary = service.reserve_item( &"cold-store", &"food", 3, &"service-a", &"meal", 10, 50, &"expiry-reserve" ) _expect(not service.is_stack_expired(added[&"stack_id"], 29), "stack remains valid before expires_at") _expect(service.is_stack_expired(added[&"stack_id"], 30), "stack expires exactly at expires_at") var report: Dictionary = service.process_expired(30) _expect(report[&"discarded_quantity"] == 5 and service.total_quantity(&"cold-store", &"food") == 3, "expiration discards only unreserved quantity") var consume: Dictionary = service.consume_reservation(reservation[&"reservation_ids"][0], &"expired-consume", 30) _expect(not consume[&"ok"] and consume[&"code"] == &"STACK_EXPIRED", "reserved stack is checked again before consumption") service.process_expired(50) _expect(service.total_quantity(&"cold-store", &"food") == 0, "reservation expiry releases and discards remaining expired stock") func _test_orphan_repair_report() -> void: var service = InventoryServiceScript.new() var added: Dictionary = service.add_stack(&"store", &"part", 5) var reservation: Dictionary = service.reserve_item( &"store", &"part", 2, &"repair-job", &"build", 0, -1, &"orphan-reserve" ) var stacks: Dictionary = service._inventories[&"store"] stacks.erase(added[&"stack_id"]) service._inventories[&"store"] = stacks var report: Dictionary = service.audit_and_repair_reservations(5) var repaired_reservation = service.get_reservation(reservation[&"reservation_ids"][0]) _expect(report[&"orphan_count"] == 1 and report[&"released_reservation_ids"].size() == 1, "orphan repair returns a structured repair report") _expect(repaired_reservation.state == InventoryReservationScript.State.RELEASED, "orphan repair closes the dangling reservation") func _test_dispatch_priority_capacity_and_tie_break() -> void: var high = _reserved_request(&"request-high", 90, 6, 300) var low = _reserved_request(&"request-low", 20, 6, 400) var dispatcher = LogisticsDispatcherScript.new() var carriers := { &"carrier-b": { &"position": Vector3i(1, 0, 1), &"capacity": 10, &"current_load": 0, &"role": &"logistics", &"path_minutes": {&"default": 5}, }, &"carrier-a": { &"position": Vector3i(0, 0, 1), &"capacity": 10, &"current_load": 0, &"role": &"logistics", &"path_minutes": {&"default": 5}, }, } var assignments: Array[Dictionary] = dispatcher.dispatch([low, high], carriers, 100) _expect(assignments.size() == 2 and assignments[0][&"request_id"] == &"request-high", "dispatcher evaluates requests in deterministic priority order") _expect(assignments[0][&"carrier_id"] == &"carrier-a", "equal scores use lexical carrier id as tie break") _expect(assignments[1][&"carrier_id"] == &"carrier-b", "reserved load prevents assigning beyond one carrier capacity") _expect(dispatcher.get_reserved_load(&"carrier-a") == 6 and dispatcher.get_reserved_load(&"carrier-b") == 6, "dispatcher records capacity reservations for later passes") var reordered_dispatcher = LogisticsDispatcherScript.new() var reordered_carriers := { &"carrier-a": carriers[&"carrier-a"], &"carrier-b": carriers[&"carrier-b"], } var reordered_assignments: Array[Dictionary] = reordered_dispatcher.dispatch([ _reserved_request(&"request-high", 90, 6, 300), _reserved_request(&"request-low", 20, 6, 400), ], reordered_carriers, 100) _expect( reordered_assignments == assignments, "one-pass carrier ordering remains deterministic across request and Dictionary insertion order" ) func _test_dispatch_missing_carrier_preserves_reserved_load() -> void: var dispatcher = LogisticsDispatcherScript.new() var carrier := { &"carrier-a": { &"position": Vector3i.ZERO, &"capacity": 10, &"current_load": 0, &"role": &"logistics", &"path_minutes": 1, }, } var first = _reserved_request(&"request-carrier-present", 90, 6, 300) _expect( dispatcher.dispatch([first], carrier, 100).size() == 1, "carrier accepts an assignment within capacity" ) var second = _reserved_request(&"request-carrier-absent", 80, 6, 310) _expect( dispatcher.dispatch([second], {}, 101).is_empty() and dispatcher.get_reserved_load(&"carrier-a") == 6, "temporarily absent carrier keeps its accepted reserved load" ) var absent_snapshot: Dictionary = dispatcher.create_snapshot() var restored = LogisticsDispatcherScript.new() _expect( restored.restore_snapshot(absent_snapshot) and restored.create_snapshot() == absent_snapshot, "missing-carrier reservation snapshot restores exactly" ) _expect( restored.dispatch([second], carrier, 102).is_empty() and restored.get_reserved_load(&"carrier-a") == 6, "reappearing carrier cannot accept another six units into capacity ten" ) _expect( restored.release_assignment(&"carrier-a", 6) == 0 and restored.create_snapshot()[&"carrier_loads"].is_empty(), "explicit assignment release removes the retained carrier load" ) func _test_atomic_transfer_batches_match_sequential_operations() -> void: var seed = InventoryServiceScript.new() seed.add_stack(&"warehouse", &"supply", 4, 87, 600, 3, 2, &"batch-source") var reservation_a: Dictionary = seed.reserve_item( &"warehouse", &"supply", 2, &"request-a", &"delivery", 10, 100, &"batch-reserve-a" ) var reservation_b: Dictionary = seed.reserve_item( &"warehouse", &"supply", 2, &"request-b", &"delivery", 10, 100, &"batch-reserve-b" ) var ids_a: Array[StringName] = [] var ids_b: Array[StringName] = [] ids_a.assign(reservation_a[&"reservation_ids"]) ids_b.assign(reservation_b[&"reservation_ids"]) var sequential = InventoryServiceScript.new() var batched = InventoryServiceScript.new() sequential.restore_snapshot(seed.create_snapshot()) batched.restore_snapshot(seed.create_snapshot()) sequential.transfer_reserved(ids_a, &"cargo-a", &"pickup-a", 20) sequential.transfer_reserved(ids_b, &"cargo-b", &"pickup-b", 20) var pickup_entries: Array[Dictionary] = [ {&"reservation_ids": ids_a, &"destination_inventory_id": &"cargo-a", &"operation_id": &"pickup-a"}, {&"reservation_ids": ids_b, &"destination_inventory_id": &"cargo-b", &"operation_id": &"pickup-b"}, ] var pickup_batch: Dictionary = batched.transfer_reserved_batch(pickup_entries, 20) _expect( pickup_batch[&"ok"] and pickup_batch[&"transfer_count"] == 2, "reserved-stock batch applies every ordered pickup atomically" ) _expect( batched.create_snapshot() == sequential.create_snapshot(), "reserved-stock batch is snapshot-equivalent to sequential public operations" ) var before_replay := batched.create_snapshot() var pickup_replay: Dictionary = batched.transfer_reserved_batch(pickup_entries, 20) _expect( pickup_replay[&"ok"] and pickup_replay[&"results"][0][&"replay"] and pickup_replay[&"results"][1][&"replay"] and batched.create_snapshot() == before_replay, "batch replay preserves per-operation idempotency without another transfer" ) var pickup_snapshot := batched.create_snapshot() sequential.transfer_available(&"cargo-a", &"destination", &"supply", 2, &"deliver-a", 21) sequential.transfer_available(&"cargo-b", &"destination", &"supply", 2, &"deliver-b", 21) var delivery_batch: Dictionary = batched.transfer_available_batch([ { &"source_inventory_id": &"cargo-a", &"destination_inventory_id": &"destination", &"item_id": &"supply", &"quantity": 2, &"operation_id": &"deliver-a", }, { &"source_inventory_id": &"cargo-b", &"destination_inventory_id": &"destination", &"item_id": &"supply", &"quantity": 2, &"operation_id": &"deliver-b", }, ], 21) _expect( delivery_batch[&"ok"] and batched.create_snapshot() == sequential.create_snapshot(), "available-stock batch preserves FEFO results, stack ids, and operation order" ) var rollback = InventoryServiceScript.new() rollback.restore_snapshot(pickup_snapshot) var before_failure := rollback.create_snapshot() var failed_batch: Dictionary = rollback.transfer_available_batch([ { &"source_inventory_id": &"cargo-a", &"destination_inventory_id": &"destination", &"item_id": &"supply", &"quantity": 2, &"operation_id": &"rollback-first", }, { &"source_inventory_id": &"missing-cargo", &"destination_inventory_id": &"destination", &"item_id": &"supply", &"quantity": 1, &"operation_id": &"rollback-second", }, ], 22) _expect( not failed_batch[&"ok"] and failed_batch[&"code"] == &"ATOMIC_BATCH_FAILED", "a failed line rejects the complete transfer batch" ) _expect( rollback.create_snapshot() == before_failure, "failed batch rolls back stock, generated ids, and idempotency records exactly" ) func _test_idempotency_conflicts_are_preflighted() -> void: var sequential = InventoryServiceScript.new() sequential.add_stack(&"source-a", &"supply", 4) sequential.add_stack(&"source-b", &"supply", 4) var first: Dictionary = sequential.transfer_available( &"source-a", &"destination", &"supply", 2, &"shared-operation", 10 ) var after_first := sequential.create_snapshot() var conflict: Dictionary = sequential.transfer_available( &"source-b", &"destination", &"supply", 2, &"shared-operation", 10 ) _expect(first[&"ok"], "first normalized input binds its operation id") _expect( not conflict[&"ok"] and conflict[&"code"] == &"IDEMPOTENCY_CONFLICT" and sequential.create_snapshot() == after_first, "sequential operation-id reuse with different input is rejected without side effects" ) var action_conflict: Dictionary = sequential.reserve_item( &"source-a", &"supply", 1, &"requester", &"delivery", 10, -1, &"shared-operation" ) _expect( not action_conflict[&"ok"] and action_conflict[&"code"] == &"IDEMPOTENCY_CONFLICT" and sequential.create_snapshot() == after_first, "operation id is bound to its action as well as normalized input" ) var duplicate_batch = InventoryServiceScript.new() duplicate_batch.add_stack(&"source-a", &"supply", 4) duplicate_batch.add_stack(&"source-b", &"supply", 4) var before_duplicate := duplicate_batch.create_snapshot() var duplicate_result: Dictionary = duplicate_batch.transfer_available_batch([ { &"source_inventory_id": &"source-a", &"destination_inventory_id": &"destination", &"item_id": &"supply", &"quantity": 2, &"operation_id": &"batch-shared", }, { &"source_inventory_id": &"source-b", &"destination_inventory_id": &"destination", &"item_id": &"supply", &"quantity": 2, &"operation_id": &"batch-shared", }, ], 10) _expect( not duplicate_result[&"ok"] and duplicate_result[&"code"] == &"IDEMPOTENCY_CONFLICT" and duplicate_batch.create_snapshot() == before_duplicate, "A-to-D then B-to-D duplicate operation id is rejected before the batch mutates" ) var existing_conflict = InventoryServiceScript.new() existing_conflict.add_stack(&"source-a", &"supply", 4) existing_conflict.add_stack(&"source-b", &"supply", 4) existing_conflict.transfer_available( &"source-a", &"destination", &"supply", 1, &"already-bound", 11 ) var before_existing_conflict := existing_conflict.create_snapshot() var existing_result: Dictionary = existing_conflict.transfer_available_batch([ { &"source_inventory_id": &"source-b", &"destination_inventory_id": &"destination", &"item_id": &"supply", &"quantity": 1, &"operation_id": &"would-be-first", }, { &"source_inventory_id": &"source-b", &"destination_inventory_id": &"destination", &"item_id": &"supply", &"quantity": 1, &"operation_id": &"already-bound", }, ], 11) _expect( not existing_result[&"ok"] and existing_result[&"code"] == &"IDEMPOTENCY_CONFLICT" and existing_conflict.create_snapshot() == before_existing_conflict, "existing operation-id conflict is found before an earlier batch row can apply" ) func _test_request_transitions() -> void: var request = _reserved_request(&"request-state", 50, 4, 200) _expect(request.assign(&"carrier", 20), "RESERVED request accepts a carrier assignment") _expect(request.transition_to(LogisticsRequestScript.State.PICKING_UP, "", 21), "ASSIGNED transitions to PICKING_UP") _expect(request.transition_to(LogisticsRequestScript.State.DELIVERING, "", 22), "PICKING_UP transitions to DELIVERING") _expect(request.transition_to(LogisticsRequestScript.State.COMPLETED, "", 23), "DELIVERING transitions to COMPLETED") _expect(not request.transition_to(LogisticsRequestScript.State.OPEN, "", 24), "terminal logistics request cannot reopen") func _test_snapshot_round_trip_and_atomic_restore() -> void: var original = InventoryServiceScript.new() original.add_stack(&"warehouse", &"supply", 10, 88, 700, 5, 2) original.reserve_item(&"warehouse", &"supply", 4, &"facility", &"restock", 10, 80, &"snapshot-reserve") var snapshot: Dictionary = original.create_snapshot() var restored = InventoryServiceScript.new() _expect(restored.restore_snapshot(snapshot), "valid inventory snapshot restores") _expect(restored.create_snapshot() == snapshot, "inventory snapshot round trip is exact") var before_invalid: Dictionary = restored.create_snapshot() var invalid: Dictionary = snapshot.duplicate(true) invalid[&"inventories"][0][&"stacks"][0][&"reserved_quantity"] = 99 _expect(not restored.restore_snapshot(invalid), "invalid inventory snapshot is rejected") _expect(restored.create_snapshot() == before_invalid, "failed restore leaves live inventory state untouched") var request = _reserved_request(&"request-save", 70, 3, 500) var request_snapshot: Dictionary = request.create_snapshot() var restored_request = LogisticsRequestScript.from_snapshot(request_snapshot) _expect(restored_request != null and restored_request.create_snapshot() == request_snapshot, "logistics request round trip preserves state") var dispatcher = LogisticsDispatcherScript.new() dispatcher.dispatch([request], { &"carrier": { &"capacity": 10, &"current_load": 0, &"role": &"porter", &"path_minutes": 2, &"position": Vector3i.ZERO, }, }, 40) var dispatcher_snapshot: Dictionary = dispatcher.create_snapshot() var restored_dispatcher = LogisticsDispatcherScript.new() _expect(restored_dispatcher.restore_snapshot(dispatcher_snapshot), "dispatcher snapshot restores") _expect(restored_dispatcher.create_snapshot() == dispatcher_snapshot, "dispatcher snapshot round trip is exact") func _test_strict_snapshot_migration_and_id_tombstones() -> void: var base = InventoryServiceScript.new() base.add_stack(&"warehouse", &"supply", 3, 90, 100, 5, 1) base.reserve_item( &"warehouse", &"supply", 1, &"requester", &"delivery", 6, 90, &"legacy-reserve" ) var snapshot: Dictionary = base.create_snapshot() var guard = InventoryServiceScript.new() _expect(guard.restore_snapshot(snapshot), "strict snapshot fixture restores before corruption checks") var guard_snapshot := guard.create_snapshot() var negative_minute := snapshot.duplicate(true) negative_minute[&"current_minute"] = -1 var negative_created := snapshot.duplicate(true) negative_created[&"inventories"][0][&"stacks"][0][&"created_at"] = -1 var negative_expiry := snapshot.duplicate(true) negative_expiry[&"inventories"][0][&"stacks"][0][&"expires_at"] = -2 var invalid_terminal := snapshot.duplicate(true) invalid_terminal[&"reservations"][0][&"terminal_at"] = 0 _expect( not guard.restore_snapshot(negative_minute) and not guard.restore_snapshot(negative_created) and not guard.restore_snapshot(negative_expiry) and not guard.restore_snapshot(invalid_terminal), "restore rejects negative or state-inconsistent canonical timestamps instead of clamping" ) _expect( guard.create_snapshot() == guard_snapshot, "strict timestamp rejection is atomic" ) var low_stack_sequence := snapshot.duplicate(true) low_stack_sequence[&"next_stack_sequence"] = 1 var low_reservation_sequence := snapshot.duplicate(true) low_reservation_sequence[&"next_reservation_sequence"] = 1 _expect( not guard.restore_snapshot(low_stack_sequence) and not guard.restore_snapshot(low_reservation_sequence) and guard.create_snapshot() == guard_snapshot, "next sequences at or below existing canonical ids are atomically rejected" ) var tombstone_source = InventoryServiceScript.new() var first_stack: Dictionary = tombstone_source.add_stack(&"source", &"part", 1) var reservation: Dictionary = tombstone_source.reserve_item( &"source", &"part", 1, &"consumer", &"use", 0, -1, &"tombstone-reserve" ) tombstone_source.consume_reservation( reservation[&"reservation_ids"][0], &"tombstone-consume", 1 ) var tombstone_snapshot := tombstone_source.create_snapshot() _expect( tombstone_source.total_quantity(&"source", &"part") == 0 and tombstone_snapshot[&"known_stack_ids"].has(String(first_stack[&"stack_id"])), "deleted generated stack id remains in persisted known-id history" ) var corrupt_tombstone_sequence := tombstone_snapshot.duplicate(true) corrupt_tombstone_sequence[&"next_stack_sequence"] = 1 var tombstone_restored = InventoryServiceScript.new() _expect( not tombstone_restored.restore_snapshot(corrupt_tombstone_sequence), "tombstone prevents a corrupted sequence from reusing a deleted auto id" ) _expect( tombstone_restored.restore_snapshot(tombstone_snapshot) and tombstone_restored.create_snapshot() == tombstone_snapshot and tombstone_restored.add_stack(&"source", &"part", 1)[&"stack_id"] == &"stack_00000002", "valid tombstone snapshot round-trips exactly and allocates the next unused id" ) var legacy_deleted = InventoryServiceScript.new() var migrated_deleted_ok := legacy_deleted.restore_snapshot( _as_legacy_inventory_snapshot(tombstone_snapshot) ) _expect( migrated_deleted_ok and legacy_deleted.create_snapshot()[&"known_stack_ids"].has("stack_00000001"), "version-1 counter migration reconstructs tombstones for deleted generated ids" ) var legacy_snapshot := _as_legacy_inventory_snapshot(snapshot) var migrated = InventoryServiceScript.new() var legacy_restored := migrated.restore_snapshot(legacy_snapshot) var legacy_replay: Dictionary = migrated.reserve_item( &"warehouse", &"supply", 1, &"requester", &"delivery", 6, 90, &"legacy-reserve" ) _expect( legacy_restored and legacy_replay[&"ok"] and legacy_replay[&"replay"], "version-1 snapshot migrates while preserving legacy replay behavior" ) var rebound_conflict: Dictionary = migrated.reserve_item( &"warehouse", &"supply", 2, &"requester", &"delivery", 6, 90, &"legacy-reserve" ) _expect( not rebound_conflict[&"ok"] and rebound_conflict[&"code"] == &"IDEMPOTENCY_CONFLICT", "first legacy replay upgrades the operation id to an input-bound record" ) var migrated_snapshot: Dictionary = migrated.create_snapshot() var migrated_roundtrip = InventoryServiceScript.new() _expect( migrated_snapshot[&"version"] == 2 and migrated_roundtrip.restore_snapshot(migrated_snapshot) and migrated_roundtrip.create_snapshot() == migrated_snapshot, "migrated version-2 snapshot is canonical and exact on subsequent restore" ) var ambiguous_legacy := _as_legacy_inventory_snapshot(snapshot) ambiguous_legacy[&"idempotency_results"].append({ &"operation_key": "transfer|legacy-reserve", &"result": {&"ok": true, &"code": &"OK", &"replay": false}, }) var ambiguous = InventoryServiceScript.new() var ambiguous_loaded := ambiguous.restore_snapshot(ambiguous_legacy) var ambiguous_use: Dictionary = ambiguous.transfer_available( &"warehouse", &"destination", &"supply", 1, &"legacy-reserve", 6 ) _expect( ambiguous_loaded and not ambiguous_use[&"ok"] and ambiguous_use[&"code"] == &"IDEMPOTENCY_CONFLICT", "legacy cross-action duplicate ids load compatibly and fail closed on replay" ) func _as_legacy_inventory_snapshot(snapshot: Dictionary) -> Dictionary: var legacy_snapshot := snapshot.duplicate(true) legacy_snapshot[&"version"] = 1 legacy_snapshot.erase(&"known_stack_ids") legacy_snapshot.erase(&"known_reservation_ids") var legacy_results: Array[Dictionary] = [] for record: Dictionary in legacy_snapshot[&"idempotency_results"]: legacy_results.append({ &"operation_key": "%s|%s" % [record[&"action"], record[&"operation_id"]], &"result": (record[&"result"] as Dictionary).duplicate(true), }) legacy_snapshot[&"idempotency_results"] = legacy_results return legacy_snapshot func _reserved_request( request_id: StringName, priority: int, weight: int, deadline: int ): var request = LogisticsRequestScript.new().configure( request_id, &"warehouse", &"facility", {&"supply": weight}, priority, 10, deadline, weight ) var reservations: Array[StringName] = [StringName("reservation-%s" % request_id)] var stacks: Array[StringName] = [StringName("stack-%s" % request_id)] request.mark_reserved(reservations, stacks, 11) return request func _expect(condition: bool, label: String) -> void: _checks += 1 if condition: print(" ✓ %s" % label) return _failures += 1 push_error(" ✗ %s" % label)