@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix electronics: <https://ref.openepcis.io/extensions/eu/electronics/> .
@prefix dpp: <https://ref.openepcis.io/extensions/common/core/> .
@prefix gs1: <https://ref.gs1.org/voc/> .
@prefix schema: <https://schema.org/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms: <http://purl.org/dc/terms/> .

# =============================================================================
# OpenEPCIS Electronics Vocabulary SHACL Shapes v0.9.5
# Validation shapes for Electronics Digital Product Passport data
# =============================================================================

<https://ref.openepcis.io/extensions/eu/electronics/shapes/>
    a sh:ShapesGraph ;
    dcterms:title "OpenEPCIS Electronics SHACL Shapes"@en ;
    dcterms:description "SHACL validation shapes for Electronics vocabulary."@en ;
    dcterms:created "2025-02-02"^^xsd:date ;
    dcterms:modified "2026-04-08"^^xsd:date .

# -----------------------------------------------------------------------------
# Electronic Device Shape
# -----------------------------------------------------------------------------
electronics:ElectronicDeviceShape a sh:NodeShape ;
    sh:targetClass electronics:ElectronicDevice ;
    rdfs:label "Electronic Device Shape" ;
    rdfs:comment "Validation shape for ElectronicDevice instances as defined by ESPR Electronics delegated acts." ;
    sh:property [
        sh:path schema:category ;
        sh:name "Device Category" ;
        sh:description "The product category of the electronic device." ;
        sh:maxCount 1 ;
        sh:class electronics:DeviceCategory
    ] ;
    sh:property [
        sh:path electronics:modelIdentifier ;
        sh:name "Model Identifier" ;
        sh:description "Manufacturer model identifier for the device." ;
        sh:datatype xsd:string ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path schema:name ;
        sh:name "Commercial Name" ;
        sh:description "Commercial or trade name of the device." ;
        sh:datatype xsd:string ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path electronics:repairabilityIndex ;
        sh:name "Repairability Index" ;
        sh:description "Repairability index assessment for the device." ;
        sh:class electronics:RepairabilityIndex
    ] ;
    sh:property [
        sh:path electronics:softwareSupport ;
        sh:name "Software Support" ;
        sh:description "Software and firmware support information." ;
        sh:class electronics:SoftwareSupport
    ] ;
    sh:property [
        sh:path electronics:energyEfficiency ;
        sh:name "Energy Efficiency" ;
        sh:description "Energy efficiency rating and consumption data." ;
        sh:class electronics:EnergyEfficiency
    ] ;
    sh:property [
        sh:path electronics:billOfMaterials ;
        sh:name "Bill of Materials" ;
        sh:description "Component bill of materials for the device." ;
        sh:class electronics:ComponentBOM
    ] ;
    sh:property [
        sh:path electronics:weeeCompliance ;
        sh:name "WEEE Compliance" ;
        sh:description "Waste Electrical and Electronic Equipment compliance data." ;
        sh:class electronics:WEEECompliance
    ] ;
    sh:property [
        sh:path electronics:rohsCompliance ;
        sh:name "RoHS Compliance" ;
        sh:description "Restriction of Hazardous Substances compliance data." ;
        sh:class electronics:RoHSCompliance
    ] ;
    sh:property [
        sh:path electronics:displaySpecification ;
        sh:name "Display Specification" ;
        sh:description "Display panel technical specifications." ;
        sh:class electronics:DisplaySpecification
    ] ;
    sh:property [
        sh:path electronics:materialDeclaration ;
        sh:name "Material Declaration" ;
        sh:description "Declared substances of concern present in the device." ;
        sh:class dpp:SubstanceOfConcern
    ] .

# -----------------------------------------------------------------------------
# Repairability Index Shape
# -----------------------------------------------------------------------------
electronics:RepairabilityIndexShape a sh:NodeShape ;
    sh:targetClass electronics:RepairabilityIndex ;
    rdfs:label "Repairability Index Shape" ;
    rdfs:comment "Validation shape for repairability index assessments per EU methodology." ;
    sh:property [
        sh:path electronics:totalScore ;
        sh:name "Total Score" ;
        sh:description "Overall repairability score from 0 to 100." ;
        sh:datatype xsd:decimal ;
        sh:maxCount 1 ;
        sh:minInclusive 0 ;
        sh:maxInclusive 100 ;
        sh:message "Total score must be a decimal between 0 and 100."
    ] ;
    sh:property [
        sh:path electronics:displayScore ;
        sh:name "Display Score" ;
        sh:description "Simplified repairability score from 0 to 10 shown on the label." ;
        sh:datatype xsd:decimal ;
        sh:maxCount 1 ;
        sh:minInclusive 0 ;
        sh:maxInclusive 10 ;
        sh:message "Display score must be a decimal between 0 and 10."
    ] ;
    sh:property [
        sh:path electronics:repairabilityClass ;
        sh:name "Repairability Class" ;
        sh:description "EU repairability class designation." ;
        sh:maxCount 1 ;
        sh:class electronics:EURepairabilityClass
    ] ;
    sh:property [
        sh:path electronics:repairCriteria ;
        sh:name "Repair Criteria" ;
        sh:description "Individual repair criteria scores contributing to the index." ;
        sh:class electronics:RepairCriterion
    ] ;
    sh:property [
        sh:path electronics:assessmentDate ;
        sh:name "Assessment Date" ;
        sh:description "Date the repairability assessment was performed." ;
        sh:datatype xsd:date ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path electronics:assessmentBody ;
        sh:name "Assessment Body" ;
        sh:description "Organization that performed the repairability assessment." ;
        sh:maxCount 1 ;
        sh:class gs1:Organization
    ] ;
    sh:property [
        sh:path electronics:repairabilityLabelUrl ;
        sh:name "Repairability Label URL" ;
        sh:description "URL of the repairability label image." ;
        sh:datatype xsd:anyURI ;
        sh:maxCount 1
    ] .

# -----------------------------------------------------------------------------
# Repair Criterion Shape
# -----------------------------------------------------------------------------
electronics:RepairCriterionShape a sh:NodeShape ;
    sh:targetClass electronics:RepairCriterion ;
    rdfs:label "Repair Criterion Shape" ;
    rdfs:comment "Validation shape for individual repair criterion scores." ;
    sh:property [
        sh:path electronics:criterionType ;
        sh:name "Criterion Type" ;
        sh:description "The type of repair criterion being scored." ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:class electronics:RepairCriterionType
    ] ;
    sh:property [
        sh:path electronics:criterionScore ;
        sh:name "Criterion Score" ;
        sh:description "Score awarded for this criterion, from 0 to 20." ;
        sh:datatype xsd:decimal ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:minInclusive 0 ;
        sh:maxInclusive 20 ;
        sh:message "Criterion score must be a decimal between 0 and 20."
    ] ;
    sh:property [
        sh:path electronics:criterionMaxScore ;
        sh:name "Criterion Max Score" ;
        sh:description "Maximum possible score for this criterion." ;
        sh:datatype xsd:decimal ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path electronics:criterionDetails ;
        sh:name "Criterion Details" ;
        sh:description "Textual details or justification for the score." ;
        sh:datatype xsd:string ;
        sh:maxCount 1
    ] .

# -----------------------------------------------------------------------------
# Software Support Shape
# -----------------------------------------------------------------------------
electronics:SoftwareSupportShape a sh:NodeShape ;
    sh:targetClass electronics:SoftwareSupport ;
    rdfs:label "Software Support Shape" ;
    rdfs:comment "Validation shape for software and firmware support commitments." ;
    sh:property [
        sh:path schema:operatingSystem ;
        sh:name "Operating System" ;
        sh:description "Name of the operating system." ;
        sh:datatype xsd:string ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path electronics:osVersion ;
        sh:name "OS Version" ;
        sh:description "Version of the operating system at time of manufacture." ;
        sh:datatype xsd:string ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path electronics:firmwareVersion ;
        sh:name "Firmware Version" ;
        sh:description "Current firmware version identifier." ;
        sh:datatype xsd:string ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path electronics:securityUpdateEndDate ;
        sh:name "Security Update End Date" ;
        sh:description "Date until which security updates are guaranteed." ;
        sh:datatype xsd:date ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path electronics:featureUpdateEndDate ;
        sh:name "Feature Update End Date" ;
        sh:description "Date until which feature updates are guaranteed." ;
        sh:datatype xsd:date ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path electronics:securitySupportYears ;
        sh:name "Security Support Years" ;
        sh:description "Duration in years of security update support." ;
        sh:class dpp:DurationYears ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path electronics:featureSupportYears ;
        sh:name "Feature Support Years" ;
        sh:description "Duration in years of feature update support." ;
        sh:class dpp:DurationYears ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path electronics:updateChannel ;
        sh:name "Update Channel" ;
        sh:description "URL of the update distribution channel." ;
        sh:datatype xsd:anyURI ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path electronics:latestUpdateDate ;
        sh:name "Latest Update Date" ;
        sh:description "Date of the most recent software or firmware update." ;
        sh:datatype xsd:date ;
        sh:maxCount 1
    ] .

# -----------------------------------------------------------------------------
# Energy Efficiency Shape
# -----------------------------------------------------------------------------
electronics:EnergyEfficiencyShape a sh:NodeShape ;
    sh:targetClass electronics:EnergyEfficiency ;
    rdfs:label "Energy Efficiency Shape" ;
    rdfs:comment "Validation shape for energy efficiency labelling and consumption data." ;
    sh:property [
        sh:path electronics:energyEfficiencyClass ;
        sh:name "Energy Efficiency Class" ;
        sh:description "EU energy efficiency class (A to G)." ;
        sh:maxCount 1 ;
        sh:class electronics:EnergyEfficiencyClass
    ] ;
    sh:property [
        sh:path electronics:annualEnergyConsumption ;
        sh:name "Annual Energy Consumption" ;
        sh:description "Estimated annual energy consumption in kilowatt-hours." ;
        sh:class dpp:EnergyKilowattHours ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path electronics:powerConsumptionOn ;
        sh:name "Power Consumption On" ;
        sh:description "Power consumption in on-mode in watts." ;
        sh:class dpp:PowerWatts ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path electronics:powerConsumptionStandby ;
        sh:name "Power Consumption Standby" ;
        sh:description "Power consumption in standby mode in watts." ;
        sh:class dpp:PowerWatts ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path electronics:powerConsumptionOff ;
        sh:name "Power Consumption Off" ;
        sh:description "Power consumption in off mode in watts." ;
        sh:class dpp:PowerWatts ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path electronics:eprelRegistrationNumber ;
        sh:name "EPREL Registration Number" ;
        sh:description "Registration number in the EU EPREL product database." ;
        sh:datatype xsd:string ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path electronics:energyLabelUrl ;
        sh:name "Energy Label URL" ;
        sh:description "URL of the EU energy label image." ;
        sh:datatype xsd:anyURI ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path electronics:eprelProductUrl ;
        sh:name "EPREL Product URL" ;
        sh:description "URL of the product entry in the EPREL database." ;
        sh:datatype xsd:anyURI ;
        sh:maxCount 1
    ] .

# -----------------------------------------------------------------------------
# Component BOM Shape
# -----------------------------------------------------------------------------
electronics:ComponentBOMShape a sh:NodeShape ;
    sh:targetClass electronics:ComponentBOM ;
    rdfs:label "Component BOM Shape" ;
    rdfs:comment "Validation shape for the component bill of materials." ;
    sh:property [
        sh:path electronics:components ;
        sh:name "Components" ;
        sh:description "List of electronic components that make up the device." ;
        sh:class electronics:ElectronicComponent ;
        sh:minCount 1
    ] .

# -----------------------------------------------------------------------------
# Electronic Component Shape
# -----------------------------------------------------------------------------
electronics:ElectronicComponentShape a sh:NodeShape ;
    sh:targetClass electronics:ElectronicComponent ;
    rdfs:label "Electronic Component Shape" ;
    rdfs:comment "Validation shape for individual electronic component entries." ;
    sh:property [
        sh:path electronics:componentType ;
        sh:name "Component Type" ;
        sh:description "Category of the component (e.g., battery, display, PCB)." ;
        sh:maxCount 1 ;
        sh:class electronics:ComponentType
    ] ;
    sh:property [
        sh:path schema:name ;
        sh:name "Component Name" ;
        sh:description "Human-readable name of the component." ;
        sh:datatype xsd:string ;
        sh:minCount 1 ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path gs1:manufacturer ;
        sh:name "Component Manufacturer" ;
        sh:description "Organization that manufactured the component." ;
        sh:maxCount 1 ;
        sh:class gs1:Organization
    ] ;
    sh:property [
        sh:path electronics:componentPartNumber ;
        sh:name "Component Part Number" ;
        sh:description "Manufacturer part number for the component." ;
        sh:datatype xsd:string ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path electronics:isReplaceable ;
        sh:name "Is Replaceable" ;
        sh:description "Whether the component can be replaced by the user or a professional." ;
        sh:datatype xsd:boolean ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path electronics:replacementDifficulty ;
        sh:name "Replacement Difficulty" ;
        sh:description "Difficulty level for replacing the component." ;
        sh:maxCount 1 ;
        sh:class electronics:ReplacementDifficulty
    ] ;
    sh:property [
        sh:path electronics:componentPassport ;
        sh:name "Component Passport" ;
        sh:description "URL of the digital product passport for this component." ;
        sh:datatype xsd:anyURI ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path electronics:sparePartAvailabilityYears ;
        sh:name "Spare Part Availability Years" ;
        sh:description "Duration in years that spare parts will remain available." ;
        sh:class dpp:DurationYears ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path electronics:sparePartPrice ;
        sh:name "Spare Part Price" ;
        sh:description "Price of the spare part for replacement." ;
        sh:maxCount 1 ;
        sh:class gs1:PriceSpecification
    ] .

# -----------------------------------------------------------------------------
# WEEE Compliance Shape
# -----------------------------------------------------------------------------
electronics:WEEEComplianceShape a sh:NodeShape ;
    sh:targetClass electronics:WEEECompliance ;
    rdfs:label "WEEE Compliance Shape" ;
    rdfs:comment "Validation shape for Waste Electrical and Electronic Equipment compliance." ;
    sh:property [
        sh:path schema:category ;
        sh:name "WEEE Category" ;
        sh:description "WEEE Directive annex category for the device." ;
        sh:maxCount 1 ;
        sh:class electronics:WEEECategory
    ] ;
    sh:property [
        sh:path electronics:weeeRegistrationNumber ;
        sh:name "WEEE Registration Number" ;
        sh:description "Producer registration number under the WEEE Directive." ;
        sh:datatype xsd:string ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path electronics:weeeRegistrationCountry ;
        sh:name "WEEE Registration Country" ;
        sh:description "ISO 3166-1 alpha-2 country code of WEEE registration." ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:pattern "^[A-Z]{2}$" ;
        sh:message "WEEE registration country must be a two-letter ISO 3166-1 alpha-2 code."
    ] ;
    sh:property [
        sh:path electronics:collectionSchemeUrl ;
        sh:name "Collection Scheme URL" ;
        sh:description "URL describing the take-back or collection scheme." ;
        sh:datatype xsd:anyURI ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path electronics:recyclabilityRate ;
        sh:name "Recyclability Rate" ;
        sh:description "Fraction of device mass that is recyclable (0 to 1)." ;
        sh:datatype xsd:decimal ;
        sh:maxCount 1 ;
        sh:minInclusive 0 ;
        sh:maxInclusive 1 ;
        sh:message "Recyclability rate must be a decimal between 0 and 1."
    ] ;
    sh:property [
        sh:path electronics:recoverabilityRate ;
        sh:name "Recoverability Rate" ;
        sh:description "Fraction of device mass that is recoverable (0 to 1)." ;
        sh:datatype xsd:decimal ;
        sh:maxCount 1 ;
        sh:minInclusive 0 ;
        sh:maxInclusive 1 ;
        sh:message "Recoverability rate must be a decimal between 0 and 1."
    ] .

# -----------------------------------------------------------------------------
# RoHS Compliance Shape
# -----------------------------------------------------------------------------
electronics:RoHSComplianceShape a sh:NodeShape ;
    sh:targetClass electronics:RoHSCompliance ;
    rdfs:label "RoHS Compliance Shape" ;
    rdfs:comment "Validation shape for Restriction of Hazardous Substances compliance." ;
    sh:property [
        sh:path electronics:rohsCompliant ;
        sh:name "RoHS Compliant" ;
        sh:description "Whether the device is fully RoHS compliant." ;
        sh:datatype xsd:boolean ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path electronics:rohsExemptions ;
        sh:name "RoHS Exemptions" ;
        sh:description "Annex exemption codes applicable to the device." ;
        sh:datatype xsd:string
    ] ;
    sh:property [
        sh:path electronics:rohsDeclarationUrl ;
        sh:name "RoHS Declaration URL" ;
        sh:description "URL of the RoHS declaration of conformity." ;
        sh:datatype xsd:anyURI ;
        sh:maxCount 1
    ] .

# -----------------------------------------------------------------------------
# Display Specification Shape
# -----------------------------------------------------------------------------
electronics:DisplaySpecificationShape a sh:NodeShape ;
    sh:targetClass electronics:DisplaySpecification ;
    rdfs:label "Display Specification Shape" ;
    rdfs:comment "Validation shape for display panel technical specifications." ;
    sh:property [
        sh:path electronics:screenDiagonal ;
        sh:name "Screen Diagonal" ;
        sh:description "Viewable screen diagonal measurement." ;
        sh:class gs1:QuantitativeValue ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path electronics:screenResolutionWidth ;
        sh:name "Screen Resolution Width" ;
        sh:description "Horizontal resolution in pixels." ;
        sh:datatype xsd:integer ;
        sh:maxCount 1 ;
        sh:minInclusive 1 ;
        sh:message "Screen resolution width must be a positive integer."
    ] ;
    sh:property [
        sh:path electronics:screenResolutionHeight ;
        sh:name "Screen Resolution Height" ;
        sh:description "Vertical resolution in pixels." ;
        sh:datatype xsd:integer ;
        sh:maxCount 1 ;
        sh:minInclusive 1 ;
        sh:message "Screen resolution height must be a positive integer."
    ] ;
    sh:property [
        sh:path electronics:displayTechnology ;
        sh:name "Display Technology" ;
        sh:description "Display panel technology type (e.g., OLED, IPS LCD)." ;
        sh:datatype xsd:string ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path electronics:refreshRate ;
        sh:name "Refresh Rate" ;
        sh:description "Display refresh rate." ;
        sh:class electronics:FrequencyHertz ;
        sh:maxCount 1
    ] ;
    sh:property [
        sh:path electronics:peakBrightness ;
        sh:name "Peak Brightness" ;
        sh:description "Peak display luminance." ;
        sh:class electronics:LuminanceCandela ;
        sh:maxCount 1
    ] .

# =============================================================================
# QuantitativeValue unitCode Shapes (GS1-idiomatic)
# =============================================================================

electronics:RefreshRateShape a sh:NodeShape ;
    sh:targetSubjectsOf electronics:refreshRate ;
    sh:property [
        sh:path ( electronics:refreshRate gs1:unitCode ) ;
        sh:hasValue "HTZ" ;
        sh:message "electronics:refreshRate must use unitCode 'HTZ' (hertz)"@en
    ] .

electronics:PeakBrightnessShape a sh:NodeShape ;
    sh:targetSubjectsOf electronics:peakBrightness ;
    sh:property [
        sh:path ( electronics:peakBrightness gs1:unitCode ) ;
        sh:hasValue "CDM2" ;
        sh:message "electronics:peakBrightness must use unitCode 'CDM2' (cd/m²)"@en
    ] .
