@prefix sh:     <http://www.w3.org/ns/shacl#> .
@prefix xsd:    <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs:   <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl:    <http://www.w3.org/2002/07/owl#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix dpp:    <https://www.dpp-interoperability.wiki/vocab/v1/dpp#> .
@prefix food:   <https://www.dpp-interoperability.wiki/vocab/v1/food#> .

# =============================================================================
# SHACL Shapes for Food Extension Vocabulary v0.1
# Companion to: https://www.dpp-interoperability.wiki/vocab/v1/food#
# =============================================================================

<https://www.dpp-interoperability.wiki/vocab/v1/food.shacl>
    a owl:Ontology ;
    rdfs:label "Food Extension SHACL Shapes" ;
    rdfs:comment "SHACL validation shapes for the DPP Food Extension vocabulary v0.1. Covers nutrition, allergens, ingredients, storage conditions, and food safety declarations." ;
    dcterms:created "2026-03-05"^^xsd:date ;
    rdfs:seeAlso <https://www.dpp-interoperability.wiki/vocab/v1/food#> .

# -----------------------------------------------------------------------------
# FoodExtension
# -----------------------------------------------------------------------------
food:FoodExtensionShape
    a sh:NodeShape ;
    sh:targetClass food:FoodExtension ;
    rdfs:label "Food Extension shape" ;
    sh:property [
        sh:path food:nutritionInformation ;
        sh:class food:NutritionInformation ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:name "nutritionInformation" ;
    ] ;
    sh:property [
        sh:path food:allergens ;
        sh:class food:Allergen ;
        sh:minCount 1 ;
        sh:name "allergens" ;
    ] ;
    sh:property [
        sh:path food:ingredients ;
        sh:class food:Ingredient ;
        sh:minCount 1 ;
        sh:name "ingredients" ;
    ] ;
    sh:property [
        sh:path food:storageConditions ;
        sh:class food:StorageConditions ;
        sh:maxCount 1 ;
        sh:name "storageConditions" ;
    ] ;
    sh:property [
        sh:path food:foodSafetyDeclarations ;
        sh:class food:FoodSafetyDeclaration ;
        sh:name "foodSafetyDeclarations" ;
    ] ;
    sh:property [
        sh:path food:countryOfOrigin ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "countryOfOrigin" ;
    ] ;
    sh:property [
        sh:path food:netQuantity ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "netQuantity" ;
    ] ;
    sh:property [
        sh:path food:drainedWeight ;
        sh:datatype xsd:double ;
        sh:minInclusive 0.0 ;
        sh:maxCount 1 ;
        sh:name "drainedWeight" ;
    ] ;
    sh:property [
        sh:path food:dietaryLabels ;
        sh:datatype xsd:string ;
        sh:name "dietaryLabels" ;
    ] ;
    sh:property [
        sh:path food:organicCertification ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "organicCertification" ;
    ] .

# -----------------------------------------------------------------------------
# NutritionInformation
# -----------------------------------------------------------------------------
food:NutritionInformationShape
    a sh:NodeShape ;
    sh:targetClass food:NutritionInformation ;
    rdfs:label "Nutrition Information shape" ;
    sh:property [
        sh:path food:servingSize ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "servingSize" ;
    ] ;
    sh:property [
        sh:path food:energyKj ;
        sh:datatype xsd:double ;
        sh:minInclusive 0.0 ;
        sh:maxCount 1 ;
        sh:name "energyKj" ;
    ] ;
    sh:property [
        sh:path food:energyKcal ;
        sh:datatype xsd:double ;
        sh:minInclusive 0.0 ;
        sh:maxCount 1 ;
        sh:name "energyKcal" ;
    ] ;
    sh:property [
        sh:path food:fat ;
        sh:datatype xsd:double ;
        sh:minInclusive 0.0 ;
        sh:maxCount 1 ;
        sh:name "fat" ;
    ] ;
    sh:property [
        sh:path food:saturatedFat ;
        sh:datatype xsd:double ;
        sh:minInclusive 0.0 ;
        sh:maxCount 1 ;
        sh:name "saturatedFat" ;
    ] ;
    sh:property [
        sh:path food:carbohydrate ;
        sh:datatype xsd:double ;
        sh:minInclusive 0.0 ;
        sh:maxCount 1 ;
        sh:name "carbohydrate" ;
    ] ;
    sh:property [
        sh:path food:sugars ;
        sh:datatype xsd:double ;
        sh:minInclusive 0.0 ;
        sh:maxCount 1 ;
        sh:name "sugars" ;
    ] ;
    sh:property [
        sh:path food:fibre ;
        sh:datatype xsd:double ;
        sh:minInclusive 0.0 ;
        sh:maxCount 1 ;
        sh:name "fibre" ;
    ] ;
    sh:property [
        sh:path food:protein ;
        sh:datatype xsd:double ;
        sh:minInclusive 0.0 ;
        sh:maxCount 1 ;
        sh:name "protein" ;
    ] ;
    sh:property [
        sh:path food:salt ;
        sh:datatype xsd:double ;
        sh:minInclusive 0.0 ;
        sh:maxCount 1 ;
        sh:name "salt" ;
    ] ;
    sh:property [
        sh:path food:sodium ;
        sh:datatype xsd:double ;
        sh:minInclusive 0.0 ;
        sh:maxCount 1 ;
        sh:name "sodium" ;
    ] .

# -----------------------------------------------------------------------------
# Allergen
# -----------------------------------------------------------------------------
food:AllergenShape
    a sh:NodeShape ;
    sh:targetClass food:Allergen ;
    rdfs:label "Allergen shape" ;
    sh:property [
        sh:path food:allergenName ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "allergenName" ;
    ] ;
    sh:property [
        sh:path food:allergenPresence ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "allergenPresence" ;
    ] .

# -----------------------------------------------------------------------------
# Ingredient
# -----------------------------------------------------------------------------
food:IngredientShape
    a sh:NodeShape ;
    sh:targetClass food:Ingredient ;
    rdfs:label "Ingredient shape" ;
    sh:property [
        sh:path food:ingredientName ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "ingredientName" ;
    ] ;
    sh:property [
        sh:path food:ingredientPercentage ;
        sh:datatype xsd:double ;
        sh:minInclusive 0.0 ;
        sh:maxInclusive 100.0 ;
        sh:maxCount 1 ;
        sh:name "ingredientPercentage" ;
    ] ;
    sh:property [
        sh:path food:ingredientOrigin ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "ingredientOrigin" ;
    ] ;
    sh:property [
        sh:path food:organic ;
        sh:datatype xsd:boolean ;
        sh:maxCount 1 ;
        sh:name "organic" ;
    ] .

# -----------------------------------------------------------------------------
# StorageConditions
# -----------------------------------------------------------------------------
food:StorageConditionsShape
    a sh:NodeShape ;
    sh:targetClass food:StorageConditions ;
    rdfs:label "Storage Conditions shape" ;
    sh:property [
        sh:path food:temperatureMin ;
        sh:datatype xsd:double ;
        sh:maxCount 1 ;
        sh:name "temperatureMin" ;
    ] ;
    sh:property [
        sh:path food:temperatureMax ;
        sh:datatype xsd:double ;
        sh:maxCount 1 ;
        sh:name "temperatureMax" ;
    ] ;
    sh:property [
        sh:path food:humidity ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "humidity" ;
    ] ;
    sh:property [
        sh:path food:storageInstructions ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "storageInstructions" ;
    ] ;
    sh:property [
        sh:path food:expiryType ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "expiryType" ;
    ] ;
    sh:property [
        sh:path food:shelfLifeDays ;
        sh:datatype xsd:integer ;
        sh:minInclusive 0 ;
        sh:maxCount 1 ;
        sh:name "shelfLifeDays" ;
    ] .

# -----------------------------------------------------------------------------
# FoodSafetyDeclaration
# -----------------------------------------------------------------------------
food:FoodSafetyDeclarationShape
    a sh:NodeShape ;
    sh:targetClass food:FoodSafetyDeclaration ;
    rdfs:label "Food Safety Declaration shape" ;
    sh:property [
        sh:path food:certificationStandard ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "certificationStandard" ;
    ] ;
    sh:property [
        sh:path food:certificationBody ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "certificationBody" ;
    ] ;
    sh:property [
        sh:path food:certificationValidFrom ;
        sh:datatype xsd:date ;
        sh:maxCount 1 ;
        sh:name "certificationValidFrom" ;
    ] ;
    sh:property [
        sh:path food:certificationValidUntil ;
        sh:datatype xsd:date ;
        sh:maxCount 1 ;
        sh:name "certificationValidUntil" ;
    ] .
