commit 2d95fe9d9a4c4a932d66611d6b331e28217591b7
parent 1a0260fa46be246dc33138f5d1d3254ea397ce5b
Author: triesap <tyson@radroots.org>
Date: Mon, 21 Sep 2026 12:59:57 +0000
core: add proposed supply change types
Diffstat:
2 files changed, 81 insertions(+), 0 deletions(-)
diff --git a/src/hyf_core/domain/supply_change.mojo b/src/hyf_core/domain/supply_change.mojo
@@ -0,0 +1,57 @@
+from std.collections import Optional
+
+
+@fieldwise_init
+struct ProposedSupplyChange(Copyable, Movable):
+ var target_kind: String
+ var target_id: Optional[String]
+ var operation: String
+ var expected_revision: Optional[String]
+ var unresolved: Bool
+
+
+def proposed_change(
+ target_kind: String,
+ target_id: Optional[String],
+ operation: String,
+ expected_revision: Optional[String],
+) raises -> ProposedSupplyChange:
+ var kinds = ["listing", "product", "farm"]
+ var kind_known = False
+ for candidate in kinds:
+ if candidate == target_kind:
+ kind_known = True
+ if not kind_known:
+ raise Error("target kind must be listing, product or farm")
+ var operations = [
+ "addition",
+ "remaining",
+ "replacement",
+ "withdrawal",
+ "correction",
+ "unresolved",
+ ]
+ var operation_known = False
+ for candidate in operations:
+ if candidate == operation:
+ operation_known = True
+ if not operation_known:
+ raise Error("unknown supply change operation: " + operation)
+
+ var resolved_operation = String(operation)
+ var unresolved = False
+ if (operation == "withdrawal" or operation == "correction") and not target_id:
+ resolved_operation = "unresolved"
+ unresolved = True
+
+ return ProposedSupplyChange(
+ target_kind=String(target_kind),
+ target_id=target_id.copy(),
+ operation=resolved_operation,
+ expected_revision=expected_revision.copy(),
+ unresolved=unresolved,
+ )
+
+
+def change_expands_to_farm(change: ProposedSupplyChange) -> Bool:
+ return False
diff --git a/tests/test_domain.mojo b/tests/test_domain.mojo
@@ -365,3 +365,27 @@ def test_supply_claims_are_per_product_and_not_inventory() raises:
assert_true(not claim_is_forecast(tomato_claim))
with assert_raises():
_ = supply_claim("c4", tomatoes, "probably", "known", 1, 0, "kg", "exact")
+
+
+from hyf_core.domain.supply_change import (
+ change_expands_to_farm,
+ proposed_change,
+)
+
+
+def test_supply_change_operations_and_scoped_withdrawal() raises:
+ var addition = proposed_change("listing", Optional[String]("b1"), "addition", None)
+ assert_equal(addition.operation, "addition")
+ var remaining = proposed_change("listing", Optional[String]("b1"), "remaining", None)
+ assert_equal(remaining.operation, "remaining")
+ var replacement = proposed_change("listing", Optional[String]("b1"), "replacement", None)
+ assert_equal(replacement.operation, "replacement")
+ # Ambiguous withdrawal target must not expand to whole-farm stock.
+ var ambiguous = proposed_change("listing", None, "withdrawal", None)
+ assert_equal(ambiguous.operation, "unresolved")
+ assert_true(ambiguous.unresolved)
+ assert_true(not change_expands_to_farm(ambiguous))
+ var correction = proposed_change("product", None, "correction", None)
+ assert_equal(correction.operation, "unresolved")
+ with assert_raises():
+ _ = proposed_change("galaxy", Optional[String]("x"), "addition", None)