Diese Seite wurde maschinell übersetzt und wurde noch nicht von einer Person überprüft. Englisch ist die Referenz; Korrekturen auf GitHub sind willkommen. GitHub
Cookwala / SDK und Szenarien / 069
A school offer that includes whole nuts: the audience decides
The school-meals flow records bread and whole mixed nuts. The nut rules in the school and care packs are tied to the audience group children under five, which the handover and distribution name, not the offer, so checking the offer alone finds nothing.
Zuerst lesen: /docs/HUMANITARIAN-PROFILE/ /humanitarian/
Schritte
The school pack on the offer: no finding, because an offer names no audience.
humanitarianCheckThe care pack on the offer: the same.
humanitarianCheckThe recorded handover names the groups children and children_under_5 and declares the two nut findings; it validates.
validateThe handover's content hash, the value a program would pin in its records.
hash
Ergebnis
You know that care rules follow the people served, not the food alone. Next: scenario 074 shows the care rules that apply to everyone.
Kommandozeile
cookwala humanitarian --pack profiles/humanitarian/school-meals-basic.rulepack.json examples/humanitarian/flows/school-meals/*.jsonAufgezeichnete Ausgabe
Status: ok
[1] humanitarianCheck: {"results": [{"id": "of-2026-11-16-sch-001", "kind": "Offer", "findings": []}]}
[2] humanitarianCheck: {"results": [{"id": "of-2026-11-16-sch-001", "kind": "Offer", "findings": []}]}
[3] validate: {"ok": true, "errors": []}
[4] hash: {"hash": "sha256:c65ab78eecd80f2b712f5e1ff94fb18f58fe237956c1265a5c36c13193c70054"}Code
Ausführen: python scenarios/out/069-school-offer-with-whole-nuts/python.py
# Scenario 069: A school offer that includes whole nuts: the audience decides
# The school-meals flow records bread and whole mixed nuts. The nut rules in the school and care packs are tied to the audience group children under five, which the handover and distribution name, not the offer, so checking the offer alone finds nothing.
# Run a hub first: python hub/cookwala_hub.py --recipes examples
import json, os
from cookwala.client import CookwalaClient, CookwalaProblem
def load(path):
with open(path, encoding="utf-8") as f:
return json.load(f)
def pick(obj, path):
for part in path.replace("]", "").replace("[", ".").split("."):
obj = obj[int(part)] if part.isdigit() else (len(obj) if part == "length" else obj.get(part))
return obj
c = CookwalaClient(os.environ.get("COOKWALA_HUB", "http://localhost:7878"))
# Step 1: The school pack on the offer: no finding, because an offer names no audience.
school = c.humanitarian_check([{"profile": "0.2.0", "kind": "Offer", "id": "of-2026-11-16-sch-001", "donor": "did:web:bakery.example", "createdAt": "2026-11-16T06:30:00+02:00", "items": [{"lineId": "1", "name": "Whole-wheat bread", "kg": 40, "storage": "ambient", "origin": "food_service", "dateMark": {"kind": "best_before", "date": "2026-11-17"}, "allergens": ["cereals_gluten"]}, {"lineId": "2", "name": "Mixed nuts (whole)", "kg": 5, "storage": "ambient", "origin": "retail", "dateMark": {"kind": "best_before", "date": "2027-02-01"}, "allergens": ["tree_nuts"], "foodClasses": ["whole_nuts"]}], "window": {"from": "2026-11-16T07:00:00+02:00", "to": "2026-11-16T10:00:00+02:00"}, "site": {"country": "EG", "admin1": "Giza", "siteName": "Bakery back door"}, "state": "distributed", "version": 4}], ["school-meals-basic"])
assert pick(school, "results[0].id") == "of-2026-11-16-sch-001", pick(school, "results[0].id")
print("ok", "results[0].id", "=", "of-2026-11-16-sch-001")
assert pick(school, "results[0].findings.length") == 0, pick(school, "results[0].findings.length")
print("ok", "results[0].findings.length", "=", 0)
# Step 2: The care pack on the offer: the same.
care = c.humanitarian_check([{"profile": "0.2.0", "kind": "Offer", "id": "of-2026-11-16-sch-001", "donor": "did:web:bakery.example", "createdAt": "2026-11-16T06:30:00+02:00", "items": [{"lineId": "1", "name": "Whole-wheat bread", "kg": 40, "storage": "ambient", "origin": "food_service", "dateMark": {"kind": "best_before", "date": "2026-11-17"}, "allergens": ["cereals_gluten"]}, {"lineId": "2", "name": "Mixed nuts (whole)", "kg": 5, "storage": "ambient", "origin": "retail", "dateMark": {"kind": "best_before", "date": "2027-02-01"}, "allergens": ["tree_nuts"], "foodClasses": ["whole_nuts"]}], "window": {"from": "2026-11-16T07:00:00+02:00", "to": "2026-11-16T10:00:00+02:00"}, "site": {"country": "EG", "admin1": "Giza", "siteName": "Bakery back door"}, "state": "distributed", "version": 4}], ["care-vulnerable-groups"])
assert pick(care, "results[0].findings.length") == 0, pick(care, "results[0].findings.length")
print("ok", "results[0].findings.length", "=", 0)
# Step 3: The recorded handover names the groups children and children_under_5 and declares the two nut findings; it validates.
handover = c.validate("humanitarian", load("examples/humanitarian/flows/school-meals/handover-1.json"))
assert pick(handover, "ok") == True, pick(handover, "ok")
print("ok", "ok", "=", True)
# Step 4: The handover's content hash, the value a program would pin in its records.
h = c.hash(load("examples/humanitarian/flows/school-meals/handover-1.json"))
assert pick(h, "hash") == "sha256:c65ab78eecd80f2b712f5e1ff94fb18f58fe237956c1265a5c36c13193c70054", pick(h, "hash")
print("ok", "hash", "=", "sha256:c65ab78eecd80f2b712f5e1ff94fb18f58fe237956c1265a5c36c13193c70054")
print("scenario complete")