{
 "$schema": "https://json-schema.org/draft/2020-12/schema",
 "$id": "https://shop.example.de/feeds/agent_feed.schema.json",
 "title": "Agent Product Feed 1.0",
 "description": "Maschinenlesbarer Produktkatalog fuer KI-Einkaufsassistenten. Eigenes Format dieses Shops; Preise brutto als Dezimalstring, Verfuegbarkeit zum Erzeugungszeitpunkt, Live-Stand ueber availability_endpoint. Der Kauf wird immer im Shop-Checkout abgeschlossen (checkout.url).",
 "type": "object",
 "additionalProperties": false,
 "required": [
  "schema_version",
  "generated_at",
  "shop",
  "products"
 ],
 "properties": {
  "schema_version": {
   "const": "1.0",
   "description": "Version dieses Schemas"
  },
  "generated_at": {
   "type": "string",
   "format": "date-time",
   "description": "Erzeugungszeitpunkt (UTC, ISO 8601)"
  },
  "shop": {
   "type": "object",
   "additionalProperties": false,
   "required": [
    "name",
    "url",
    "currency",
    "checkout_policy"
   ],
   "properties": {
    "name": {
     "type": "string",
     "minLength": 1
    },
    "url": {
     "type": "string",
     "pattern": "^https://"
    },
    "currency": {
     "type": "string",
     "pattern": "^[A-Z]{3}$",
     "description": "Standardwaehrung, ISO 4217"
    },
    "checkout_policy": {
     "type": "string",
     "description": "Wie ein Agent den Kauf ausloest (Text)"
    }
   }
  },
  "products": {
   "type": "array",
   "minItems": 1,
   "items": {
    "$ref": "#/$defs/product"
   }
  }
 },
 "$defs": {
  "money": {
   "type": "object",
   "additionalProperties": false,
   "required": [
    "amount",
    "currency"
   ],
   "properties": {
    "amount": {
     "type": "string",
     "pattern": "^(0|[1-9][0-9]*)\\.[0-9]{2}$",
     "description": "Bruttobetrag mit genau zwei Nachkommastellen als String - keine Gleitkommazahl, damit kein Agent Rundungsfehler einbaut"
    },
    "currency": {
     "type": "string",
     "pattern": "^[A-Z]{3}$",
     "description": "ISO 4217"
    }
   }
  },
  "product": {
   "type": "object",
   "additionalProperties": false,
   "required": [
    "id",
    "title",
    "description",
    "brand",
    "url",
    "images",
    "variants"
   ],
   "properties": {
    "id": {
     "type": "string",
     "pattern": "^[a-z0-9-]+$",
     "description": "Produktgruppe"
    },
    "title": {
     "type": "string",
     "minLength": 1,
     "maxLength": 150
    },
    "description": {
     "type": "string",
     "maxLength": 5000
    },
    "brand": {
     "type": "string",
     "minLength": 1
    },
    "url": {
     "type": "string",
     "pattern": "^https://",
     "description": "Produktseite"
    },
    "images": {
     "type": "array",
     "minItems": 1,
     "items": {
      "type": "string",
      "pattern": "^https://"
     }
    },
    "variants": {
     "type": "array",
     "minItems": 1,
     "items": {
      "$ref": "#/$defs/variant"
     }
    }
   }
  },
  "variant": {
   "type": "object",
   "additionalProperties": false,
   "required": [
    "sku",
    "gtin",
    "title",
    "attributes",
    "price",
    "regular_price",
    "sale",
    "availability",
    "stock_quantity",
    "shipping",
    "url",
    "checkout",
    "availability_endpoint"
   ],
   "properties": {
    "sku": {
     "type": "string",
     "minLength": 1,
     "description": "Eindeutige Artikelnummer der Variante"
    },
    "gtin": {
     "type": [
      "string",
      "null"
     ],
     "pattern": "^[0-9]{8,14}$",
     "description": "GTIN/EAN; null wenn das Produkt keine hat (Handwerk, Eigenmarke)"
    },
    "title": {
     "type": "string",
     "minLength": 1
    },
    "attributes": {
     "type": "object",
     "additionalProperties": false,
     "properties": {
      "color": {
       "type": "string"
      },
      "size": {
       "type": "string"
      }
     }
    },
    "price": {
     "$ref": "#/$defs/money",
     "description": "Jetzt geltender Preis (bei aktivem Sale der Sale-Preis)"
    },
    "regular_price": {
     "$ref": "#/$defs/money",
     "description": "Normalpreis ohne Aktion"
    },
    "sale": {
     "oneOf": [
      {
       "type": "null"
      },
      {
       "type": "object",
       "additionalProperties": false,
       "required": [
        "price",
        "valid_from",
        "valid_until"
       ],
       "properties": {
        "price": {
         "$ref": "#/$defs/money"
        },
        "valid_from": {
         "type": "string",
         "format": "date"
        },
        "valid_until": {
         "type": "string",
         "format": "date"
        }
       }
      }
     ],
     "description": "Aktive Aktion oder null"
    },
    "availability": {
     "enum": [
      "in_stock",
      "out_of_stock"
     ]
    },
    "stock_quantity": {
     "type": "integer",
     "minimum": 0
    },
    "shipping": {
     "type": "object",
     "additionalProperties": false,
     "required": [
      "country",
      "price"
     ],
     "properties": {
      "country": {
       "type": "string",
       "pattern": "^[A-Z]{2}$"
      },
      "price": {
       "$ref": "#/$defs/money"
      }
     }
    },
    "url": {
     "type": "string",
     "pattern": "^https://"
    },
    "checkout": {
     "type": "object",
     "additionalProperties": false,
     "required": [
      "method",
      "url"
     ],
     "properties": {
      "method": {
       "const": "redirect_to_shop_checkout"
      },
      "url": {
       "type": "string",
       "pattern": "^https://"
      }
     },
     "description": "Der Agent leitet den Kunden hierhin; Bezahlung im Shop"
    },
    "availability_endpoint": {
     "type": "string",
     "pattern": "^https://",
     "description": "Liefert den Live-Bestand (GET, JSON)"
    }
   },
   "if": {
    "properties": {
     "stock_quantity": {
      "const": 0
     }
    },
    "required": [
     "stock_quantity"
    ]
   },
   "then": {
    "properties": {
     "availability": {
      "const": "out_of_stock"
     }
    }
   },
   "else": {
    "properties": {
     "availability": {
      "const": "in_stock"
     }
    }
   }
  }
 }
}