{
  "schema_version": "1.0",
  "nodes": [
    {
      "id": "order",
      "type": "input/json_value",
      "label": "Order",
      "parameters": { "value": {"order_id": "FDB-2026-10417", "currency": "EUR", "customer": {"name": "Lena Hoffmann", "locale": "de-DE"}, "delivery": {"date": "2026-10-03", "zone": "semicentro", "recipient": "Giulia Ferri", "address": "Via Solferino 12, 20121 Milano"}, "lines": [{"item": "Peonie rosa, mazzo da 12", "qty": 1, "unit_price": 42}, {"item": "Rami di eucalipto", "qty": 2, "unit_price": 4.5}, {"item": "Vaso in vetro soffiato color ambra", "qty": 1, "unit_price": 18.9}], "gift": {"occasion": "birthday", "message": "Cara Giulia, buon compleanno! Che quest'anno fiorisca come queste peonie. Un abbraccio da Monaco, Lena"}},
        "required": true
      }
    },
    {
      "id": "lines",
      "type": "enumerate/json",
      "label": "Each line",
      "parameters": {
        "jsonConfig": {
          "arrayPath": "lines",
          "properties": [
            {
              "sourcePath": "item",
              "outputPort": "item",
              "outputType": "text",
              "selected": true
            },
            {
              "sourcePath": "qty",
              "outputPort": "qty",
              "outputType": "number",
              "selected": true
            },
            {
              "sourcePath": "unit_price",
              "outputPort": "unit_price",
              "outputType": "number",
              "selected": true
            }
          ]
        },
        "emptyBehavior": "fail",
        "absentBehavior": "fail"
      }
    },
    {
      "id": "line_total",
      "type": "utility/calculate",
      "label": "Line total",
      "parameters": {
        "expression": "qty * unit_price",
        "decimals": 2
      }
    },
    {
      "id": "priced_lines",
      "type": "aggregate/json",
      "label": "Priced lines",
      "parameters": {
        "emptyBehavior": "fail",
        "jsonAggregateConfig": {
          "prettyPrint": true,
          "outputName": "priced_lines",
          "columns": [
            {
              "name": "item",
              "inputPort": "item",
              "type": "text"
            },
            {
              "name": "qty",
              "inputPort": "qty",
              "type": "number"
            },
            {
              "name": "unit_price",
              "inputPort": "unit_price",
              "type": "number"
            },
            {
              "name": "line_total",
              "inputPort": "line_total",
              "type": "number"
            }
          ]
        }
      }
    },
    {
      "id": "subtotal",
      "type": "utility/calculate",
      "label": "Subtotal",
      "parameters": {
        "expression": "sum(priced_lines[*].line_total)",
        "decimals": 2
      }
    },
    {
      "id": "zone",
      "type": "utility/extract",
      "label": "Delivery zone",
      "parameters": {
        "path": "delivery.zone",
        "expected_type": "text",
        "on_missing": "fail"
      }
    },
    {
      "id": "fee_centro",
      "type": "utility/constant",
      "label": "City centre fee",
      "parameters": {
        "type": "number",
        "value": "6"
      }
    },
    {
      "id": "fee_semicentro",
      "type": "utility/constant",
      "label": "Inner districts fee",
      "parameters": {
        "type": "number",
        "value": "9"
      }
    },
    {
      "id": "fee_provincia",
      "type": "utility/constant",
      "label": "Province fee",
      "parameters": {
        "type": "number",
        "value": "15"
      }
    },
    {
      "id": "fee_far",
      "type": "utility/constant",
      "label": "Any other zone",
      "parameters": {
        "type": "number",
        "value": "22"
      }
    },
    {
      "id": "zone_fee",
      "type": "utility/select_by_key",
      "label": "Fee for the zone",
      "parameters": {
        "selectionConfig": {
          "valueType": "number",
          "onNoMatch": "use_default",
          "caseSensitive": false,
          "cases": [
            {
              "key": "centro",
              "inputPort": "centro",
              "label": "City centre"
            },
            {
              "key": "semicentro",
              "inputPort": "semicentro",
              "label": "Inner districts"
            },
            {
              "key": "provincia",
              "inputPort": "provincia",
              "label": "Province"
            }
          ]
        }
      }
    },
    {
      "id": "delivery",
      "type": "utility/calculate",
      "label": "Delivery",
      "parameters": {
        "expression": "if(subtotal >= 80, 0, zone_fee)",
        "decimals": 2
      }
    },
    {
      "id": "coupon",
      "type": "utility/extract",
      "label": "Coupon percent",
      "parameters": {
        "path": "coupon_percent",
        "expected_type": "number",
        "on_missing": "default",
        "default_value": 0
      }
    },
    {
      "id": "discount",
      "type": "utility/calculate",
      "label": "Discount",
      "parameters": {
        "expression": "round(subtotal * coupon / 100, 2)",
        "decimals": 2
      }
    },
    {
      "id": "total",
      "type": "utility/calculate",
      "label": "Total",
      "parameters": {
        "expression": "subtotal - discount + delivery",
        "decimals": 2
      }
    },
    {
      "id": "name",
      "type": "utility/extract",
      "label": "Customer name",
      "parameters": {
        "path": "customer.name",
        "expected_type": "text",
        "on_missing": "fail"
      }
    },
    {
      "id": "locale",
      "type": "utility/extract",
      "label": "Customer language",
      "parameters": {
        "path": "customer.locale",
        "expected_type": "text",
        "on_missing": "fail"
      }
    },
    {
      "id": "currency",
      "type": "utility/extract",
      "label": "Currency",
      "parameters": {
        "path": "currency",
        "expected_type": "text",
        "on_missing": "fail"
      }
    },
    {
      "id": "date",
      "type": "utility/extract",
      "label": "Delivery date",
      "parameters": {
        "path": "delivery.date",
        "expected_type": "text",
        "on_missing": "fail"
      }
    },
    {
      "id": "fmt_subtotal",
      "type": "text/format",
      "label": "Subtotal as text",
      "parameters": {
        "format": "currency",
        "locale": "en-GB",
        "currency": "EUR",
        "currency_display": "symbol"
      }
    },
    {
      "id": "fmt_delivery",
      "type": "text/format",
      "label": "Delivery as text",
      "parameters": {
        "format": "currency",
        "locale": "en-GB",
        "currency": "EUR",
        "currency_display": "symbol"
      }
    },
    {
      "id": "fmt_discount",
      "type": "text/format",
      "label": "Discount as text",
      "parameters": {
        "format": "currency",
        "locale": "en-GB",
        "currency": "EUR",
        "currency_display": "symbol"
      }
    },
    {
      "id": "fmt_total",
      "type": "text/format",
      "label": "Total as text",
      "parameters": {
        "format": "currency",
        "locale": "en-GB",
        "currency": "EUR",
        "currency_display": "symbol"
      }
    },
    {
      "id": "fmt_date",
      "type": "text/format",
      "label": "Date as text",
      "parameters": {
        "format": "date",
        "locale": "en-GB",
        "date_style": "full"
      }
    },
    {
      "id": "fmt_lines",
      "type": "text/format",
      "label": "Lines as text",
      "parameters": {
        "format": "json",
        "json_style": "compact"
      }
    },
    {
      "id": "card_message",
      "type": "utility/extract",
      "label": "Card message",
      "parameters": {
        "path": "gift.message",
        "expected_type": "text",
        "on_missing": "absent"
      }
    },
    {
      "id": "fmt_gift",
      "type": "text/format",
      "label": "Gift as text",
      "parameters": {
        "format": "auto",
        "true_text": "yes: a hand-painted card with the customer's own message travels with the flowers",
        "false_text": "no"
      }
    },
    {
      "id": "confirm_facts",
      "type": "text/template",
      "label": "Confirmation facts",
      "parameters": {
        "template": "Customer: [name]\nWrite in the language of this locale: [locale]\nItems ordered (JSON): [lines]\nSubtotal: [subtotal]\nDelivery: [delivery]\nCoupon discount: [discount]\nTotal paid: [total]\nDelivery day: [date]\nGift: [gift]",
        "placeholders": [
          {
            "name": "name",
            "inputPort": "name"
          },
          {
            "name": "locale",
            "inputPort": "locale"
          },
          {
            "name": "lines",
            "inputPort": "lines"
          },
          {
            "name": "subtotal",
            "inputPort": "subtotal"
          },
          {
            "name": "delivery",
            "inputPort": "delivery"
          },
          {
            "name": "discount",
            "inputPort": "discount"
          },
          {
            "name": "total",
            "inputPort": "total"
          },
          {
            "name": "date",
            "inputPort": "date"
          },
          {
            "name": "gift",
            "inputPort": "gift"
          }
        ]
      }
    },
    {
      "id": "confirmation",
      "type": "ai/text_generation",
      "label": "Confirmation message",
      "parameters": {
        "system_prompt": "You write the order confirmation of Fiori di Brera, a flower shop in Milan, to the customer, in the language of the locale you are given. Warm and brief, like a florist who knows their customers: a greeting with the first name, what is on its way and when, then the amounts. Name the flowers and items in the customer's language, with their quantities; do not give prices per item. Copy every amount and the delivery day exactly as written in the facts, character for character: never recompute, round or reformat them. If the delivery amount is zero, say that delivery is free. Leave the discount out when it is zero. Mention the card only if Gift says yes, without quoting its message. Sign as \"Fiori di Brera\". Plain text, at most 110 words, no subject line.",
        "temperature": 0.4,
        "max_tokens": 2000
      },
      "model": {
        "model": "gpt-5.6-luna",
        "params": {
          "reasoning_effort": "low",
          "max_tokens": 2000
        }
      }
    },
    {
      "id": "occasion",
      "type": "utility/extract",
      "label": "Occasion",
      "parameters": {
        "path": "gift.occasion",
        "expected_type": "text",
        "on_missing": "default",
        "default_value": "a thoughtful gift"
      }
    },
    {
      "id": "only_gift",
      "type": "utility/filter",
      "label": "Only for a gift",
      "parameters": {
        "invert": false
      }
    },
    {
      "id": "card_brief",
      "type": "text/template",
      "label": "Card brief",
      "parameters": {
        "template": "Occasion: [occasion]\nWhat was ordered (JSON): [lines]",
        "placeholders": [
          {
            "name": "occasion",
            "inputPort": "occasion"
          },
          {
            "name": "lines",
            "inputPort": "lines"
          }
        ]
      }
    },
    {
      "id": "card_idea",
      "type": "ai/text_generation",
      "label": "Card illustration prompt",
      "parameters": {
        "system_prompt": "You write one prompt for an image model, in English, for the front of a greeting card from a florist. The picture: a loose, luminous watercolour of exactly the flowers and the vase that were ordered, in their true colours, painted by hand on textured cream cotton paper, with soft blooms of pigment, a few paint splashes and visible brush strokes. The paper fills the whole frame edge to edge: no table, no background, no border around it. The bouquet and its vase stand entirely in the upper half, the vase base well above the middle; the lower half is plain, empty cream paper for a handwritten message. Let the occasion set the mood through light and colour only. No text, no letters, no numbers, no signature, no border, no hands, no table. One paragraph, at most 90 words, nothing but the prompt.",
        "temperature": 0.7,
        "max_tokens": 2000
      },
      "model": {
        "model": "gpt-5.6-luna",
        "params": {
          "reasoning_effort": "low",
          "max_tokens": 2000
        }
      }
    },
    {
      "id": "card_art",
      "type": "ai/text_to_image",
      "label": "Watercolour card",
      "parameters": {
        "aspect_ratio": "3_4"
      }
    },
    {
      "id": "card",
      "type": "image/text_overlay",
      "label": "Handwritten message",
      "parameters": {
        "typography": {
          "schema": "madoo.image-typography/v1",
          "preset": "minimal",
          "font": {
            "schema": "madoo.font-reference/v1",
            "familyGuid": "003a4245-80cc-0e52-ae8c-a804414a63d8",
            "versionGuid": "efee828d-e9d9-3859-e226-13e804256fa2",
            "family": "Caveat",
            "variant": "regular",
            "weight": 400,
            "style": "normal",
            "fingerprint": "a16659fcbbece3ebc342f911e5046ff58cb980578149fdea900a92aafe49cc9f"
          },
          "size": {
            "mode": "relative",
            "value": 4.2,
            "min": 26,
            "max": 88
          },
          "text": {
            "color": "#2E3A4F",
            "opacity": 0.94,
            "transform": "none",
            "letterSpacing": 0,
            "lineSpacing": 1.12
          },
          "layout": {
            "anchor": "bottom-center",
            "alignment": "center",
            "maxWidthPercent": 78,
            "maxHeightPercent": 30,
            "maxLines": 6,
            "offsetXPercent": 0,
            "offsetYPercent": 0,
            "overflow": "fit",
            "safeArea": {
              "preset": "title-safe",
              "topPercent": 6,
              "rightPercent": 8,
              "bottomPercent": 7,
              "leftPercent": 8
            }
          },
          "outline": {
            "enabled": false,
            "color": "#000000",
            "width": 0
          },
          "shadow": {
            "enabled": false,
            "color": "#000000",
            "opacity": 0,
            "offsetX": 0,
            "offsetY": 0,
            "blur": 0
          },
          "background": {
            "enabled": false,
            "color": "#FFFFFF",
            "opacity": 0,
            "paddingX": 0,
            "paddingY": 0
          }
        }
      }
    },
    {
      "id": "out_confirmation",
      "type": "output/text",
      "label": "Confirmation",
      "parameters": {
        "output_name": "confirmation"
      }
    },
    {
      "id": "out_total",
      "type": "output/json",
      "label": "Total",
      "parameters": {
        "output_name": "total"
      }
    },
    {
      "id": "out_lines",
      "type": "output/json",
      "label": "Priced lines",
      "parameters": {
        "output_name": "priced_lines"
      }
    },
    {
      "id": "out_card",
      "type": "output/image",
      "label": "Card",
      "parameters": {
        "output_name": "card"
      }
    }
  ],
  "connections": [
    {
      "from_node": "order",
      "from_output": "json",
      "to_node": "lines",
      "to_input": "json"
    },
    {
      "from_node": "lines",
      "from_output": "qty",
      "to_node": "line_total",
      "to_input": "qty"
    },
    {
      "from_node": "lines",
      "from_output": "unit_price",
      "to_node": "line_total",
      "to_input": "unit_price"
    },
    {
      "from_node": "lines",
      "from_output": "item",
      "to_node": "priced_lines",
      "to_input": "item"
    },
    {
      "from_node": "lines",
      "from_output": "qty",
      "to_node": "priced_lines",
      "to_input": "qty"
    },
    {
      "from_node": "lines",
      "from_output": "unit_price",
      "to_node": "priced_lines",
      "to_input": "unit_price"
    },
    {
      "from_node": "line_total",
      "from_output": "result",
      "to_node": "priced_lines",
      "to_input": "line_total"
    },
    {
      "from_node": "priced_lines",
      "from_output": "result",
      "to_node": "subtotal",
      "to_input": "priced_lines"
    },
    {
      "from_node": "order",
      "from_output": "json",
      "to_node": "zone",
      "to_input": "json"
    },
    {
      "from_node": "zone",
      "from_output": "value",
      "to_node": "zone_fee",
      "to_input": "selector"
    },
    {
      "from_node": "fee_far",
      "from_output": "value",
      "to_node": "zone_fee",
      "to_input": "default_value"
    },
    {
      "from_node": "fee_centro",
      "from_output": "value",
      "to_node": "zone_fee",
      "to_input": "centro"
    },
    {
      "from_node": "fee_semicentro",
      "from_output": "value",
      "to_node": "zone_fee",
      "to_input": "semicentro"
    },
    {
      "from_node": "fee_provincia",
      "from_output": "value",
      "to_node": "zone_fee",
      "to_input": "provincia"
    },
    {
      "from_node": "subtotal",
      "from_output": "result",
      "to_node": "delivery",
      "to_input": "subtotal"
    },
    {
      "from_node": "zone_fee",
      "from_output": "selected_value",
      "to_node": "delivery",
      "to_input": "zone_fee"
    },
    {
      "from_node": "order",
      "from_output": "json",
      "to_node": "coupon",
      "to_input": "json"
    },
    {
      "from_node": "subtotal",
      "from_output": "result",
      "to_node": "discount",
      "to_input": "subtotal"
    },
    {
      "from_node": "coupon",
      "from_output": "value",
      "to_node": "discount",
      "to_input": "coupon"
    },
    {
      "from_node": "subtotal",
      "from_output": "result",
      "to_node": "total",
      "to_input": "subtotal"
    },
    {
      "from_node": "discount",
      "from_output": "result",
      "to_node": "total",
      "to_input": "discount"
    },
    {
      "from_node": "delivery",
      "from_output": "result",
      "to_node": "total",
      "to_input": "delivery"
    },
    {
      "from_node": "order",
      "from_output": "json",
      "to_node": "name",
      "to_input": "json"
    },
    {
      "from_node": "order",
      "from_output": "json",
      "to_node": "locale",
      "to_input": "json"
    },
    {
      "from_node": "order",
      "from_output": "json",
      "to_node": "currency",
      "to_input": "json"
    },
    {
      "from_node": "order",
      "from_output": "json",
      "to_node": "date",
      "to_input": "json"
    },
    {
      "from_node": "subtotal",
      "from_output": "result",
      "to_node": "fmt_subtotal",
      "to_input": "value"
    },
    {
      "from_node": "locale",
      "from_output": "value",
      "to_node": "fmt_subtotal",
      "to_input": "locale"
    },
    {
      "from_node": "currency",
      "from_output": "value",
      "to_node": "fmt_subtotal",
      "to_input": "currency"
    },
    {
      "from_node": "delivery",
      "from_output": "result",
      "to_node": "fmt_delivery",
      "to_input": "value"
    },
    {
      "from_node": "locale",
      "from_output": "value",
      "to_node": "fmt_delivery",
      "to_input": "locale"
    },
    {
      "from_node": "currency",
      "from_output": "value",
      "to_node": "fmt_delivery",
      "to_input": "currency"
    },
    {
      "from_node": "discount",
      "from_output": "result",
      "to_node": "fmt_discount",
      "to_input": "value"
    },
    {
      "from_node": "locale",
      "from_output": "value",
      "to_node": "fmt_discount",
      "to_input": "locale"
    },
    {
      "from_node": "currency",
      "from_output": "value",
      "to_node": "fmt_discount",
      "to_input": "currency"
    },
    {
      "from_node": "total",
      "from_output": "result",
      "to_node": "fmt_total",
      "to_input": "value"
    },
    {
      "from_node": "locale",
      "from_output": "value",
      "to_node": "fmt_total",
      "to_input": "locale"
    },
    {
      "from_node": "currency",
      "from_output": "value",
      "to_node": "fmt_total",
      "to_input": "currency"
    },
    {
      "from_node": "date",
      "from_output": "value",
      "to_node": "fmt_date",
      "to_input": "value"
    },
    {
      "from_node": "locale",
      "from_output": "value",
      "to_node": "fmt_date",
      "to_input": "locale"
    },
    {
      "from_node": "priced_lines",
      "from_output": "result",
      "to_node": "fmt_lines",
      "to_input": "value"
    },
    {
      "from_node": "order",
      "from_output": "json",
      "to_node": "card_message",
      "to_input": "json"
    },
    {
      "from_node": "card_message",
      "from_output": "found",
      "to_node": "fmt_gift",
      "to_input": "value"
    },
    {
      "from_node": "name",
      "from_output": "value",
      "to_node": "confirm_facts",
      "to_input": "name"
    },
    {
      "from_node": "locale",
      "from_output": "value",
      "to_node": "confirm_facts",
      "to_input": "locale"
    },
    {
      "from_node": "fmt_lines",
      "from_output": "text",
      "to_node": "confirm_facts",
      "to_input": "lines"
    },
    {
      "from_node": "fmt_subtotal",
      "from_output": "text",
      "to_node": "confirm_facts",
      "to_input": "subtotal"
    },
    {
      "from_node": "fmt_delivery",
      "from_output": "text",
      "to_node": "confirm_facts",
      "to_input": "delivery"
    },
    {
      "from_node": "fmt_discount",
      "from_output": "text",
      "to_node": "confirm_facts",
      "to_input": "discount"
    },
    {
      "from_node": "fmt_total",
      "from_output": "text",
      "to_node": "confirm_facts",
      "to_input": "total"
    },
    {
      "from_node": "fmt_date",
      "from_output": "text",
      "to_node": "confirm_facts",
      "to_input": "date"
    },
    {
      "from_node": "fmt_gift",
      "from_output": "text",
      "to_node": "confirm_facts",
      "to_input": "gift"
    },
    {
      "from_node": "confirm_facts",
      "from_output": "result",
      "to_node": "confirmation",
      "to_input": "prompt"
    },
    {
      "from_node": "order",
      "from_output": "json",
      "to_node": "occasion",
      "to_input": "json"
    },
    {
      "from_node": "card_message",
      "from_output": "found",
      "to_node": "only_gift",
      "to_input": "condition"
    },
    {
      "from_node": "fmt_lines",
      "from_output": "text",
      "to_node": "only_gift",
      "to_input": "value"
    },
    {
      "from_node": "occasion",
      "from_output": "value",
      "to_node": "card_brief",
      "to_input": "occasion"
    },
    {
      "from_node": "only_gift",
      "from_output": "value",
      "to_node": "card_brief",
      "to_input": "lines"
    },
    {
      "from_node": "card_brief",
      "from_output": "result",
      "to_node": "card_idea",
      "to_input": "prompt"
    },
    {
      "from_node": "card_idea",
      "from_output": "result",
      "to_node": "card_art",
      "to_input": "prompt"
    },
    {
      "from_node": "card_art",
      "from_output": "result",
      "to_node": "card",
      "to_input": "image"
    },
    {
      "from_node": "card_message",
      "from_output": "value",
      "to_node": "card",
      "to_input": "text"
    },
    {
      "from_node": "confirmation",
      "from_output": "result",
      "to_node": "out_confirmation",
      "to_input": "text"
    },
    {
      "from_node": "total",
      "from_output": "result",
      "to_node": "out_total",
      "to_input": "json"
    },
    {
      "from_node": "priced_lines",
      "from_output": "result",
      "to_node": "out_lines",
      "to_input": "json"
    },
    {
      "from_node": "card",
      "from_output": "result",
      "to_node": "out_card",
      "to_input": "image"
    }
  ]
}
