Esta página fue traducida por una máquina y aún no ha sido revisada por una persona. El inglés es la referencia; las correcciones son bienvenidas en GitHub. GitHub
Cookwala / SDK y escenarios / 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.
Leer primero: /docs/HUMANITARIAN-PROFILE/ /humanitarian/
Pasos
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.
Línea de comandos
cookwala humanitarian --pack profiles/humanitarian/school-meals-basic.rulepack.json examples/humanitarian/flows/school-meals/*.jsonSalida grabada
Estado: 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
Ejecutar: 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")