Cette page a été traduite par une machine et n'a pas encore été révisée par une personne. L'anglais est la référence ; les corrections sont les bienvenues sur GitHub. GitHub
Cookwala / SDK et scénarios / 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.
Lire d'abord: /docs/HUMANITARIAN-PROFILE/ /humanitarian/
Étapes
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
Résultat
You know that care rules follow the people served, not the food alone. Next: scenario 074 shows the care rules that apply to everyone.
Ligne de commande
cookwala humanitarian --pack profiles/humanitarian/school-meals-basic.rulepack.json examples/humanitarian/flows/school-meals/*.jsonSortie enregistrée
Statut: 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
Exécuter: 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")