Esta página foi traduzida por máquina e ainda não foi revisada por uma pessoa. O inglês é a referência; correções são bem-vindas no GitHub. GitHub
Cookwala / SDK e cenários / 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.
Leia primeiro: /docs/HUMANITARIAN-PROFILE/ /humanitarian/
Passos
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
Resultado
You know that care rules follow the people served, not the food alone. Next: scenario 074 shows the care rules that apply to everyone.
Linha de comando
cookwala humanitarian --pack profiles/humanitarian/school-meals-basic.rulepack.json examples/humanitarian/flows/school-meals/*.jsonSaída gravada
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"}Código
Executar: 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")