@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 soc:    <https://www.dpp-interoperability.wiki/vocab/v1/soc#> .

# =============================================================================
# SHACL Shapes for Substances of Concern Extension Vocabulary v0.1
# Companion to: https://www.dpp-interoperability.wiki/vocab/v1/soc#
# =============================================================================

<https://www.dpp-interoperability.wiki/vocab/v1/soc.shacl>
    a owl:Ontology ;
    rdfs:label "SoC Extension SHACL Shapes" ;
    rdfs:comment "SHACL validation shapes for the DPP Substances of Concern Extension vocabulary v0.1. Covers substance identification, concentration, regulatory thresholds, SVHC checks, hazards, restricted substance lists, and due diligence." ;
    dcterms:created "2026-03-05"^^xsd:date ;
    rdfs:seeAlso <https://www.dpp-interoperability.wiki/vocab/v1/soc#> .

# -----------------------------------------------------------------------------
# SocExtension
# -----------------------------------------------------------------------------
soc:SocExtensionShape
    a sh:NodeShape ;
    sh:targetClass soc:SocExtension ;
    rdfs:label "SoC Extension shape" ;
    sh:property [
        sh:path soc:hasSubstanceOfConcern ;
        sh:class soc:Substance ;
        sh:minCount 1 ;
        sh:name "hasSubstanceOfConcern" ;
    ] ;
    sh:property [
        sh:path soc:svhcCandidateListCheck ;
        sh:class soc:SvhcCandidateListCheck ;
        sh:maxCount 1 ;
        sh:name "svhcCandidateListCheck" ;
    ] ;
    sh:property [
        sh:path soc:hazards ;
        sh:class soc:Hazard ;
        sh:name "hazards" ;
    ] ;
    sh:property [
        sh:path soc:dueDiligenceStatement ;
        sh:class soc:DueDiligenceStatement ;
        sh:maxCount 1 ;
        sh:name "dueDiligenceStatement" ;
    ] .

# -----------------------------------------------------------------------------
# Substance
# -----------------------------------------------------------------------------
soc:SubstanceShape
    a sh:NodeShape ;
    sh:targetClass soc:Substance ;
    rdfs:label "Substance shape" ;
    sh:property [
        sh:path soc:substanceName ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "substanceName" ;
    ] ;
    sh:property [
        sh:path soc:casNumber ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "casNumber" ;
    ] ;
    sh:property [
        sh:path soc:ecNumber ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "ecNumber" ;
    ] ;
    sh:property [
        sh:path soc:iupacName ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "iupacName" ;
    ] ;
    sh:property [
        sh:path soc:substanceLocation ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "substanceLocation" ;
    ] ;
    sh:property [
        sh:path soc:relevantLifecycleStage ;
        sh:datatype xsd:string ;
        sh:name "relevantLifecycleStage" ;
    ] ;
    sh:property [
        sh:path soc:substanceFunction ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "substanceFunction" ;
    ] ;
    sh:property [
        sh:path soc:hazardClassification ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "hazardClassification" ;
    ] ;
    sh:property [
        sh:path soc:role ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "role" ;
    ] ;
    sh:property [
        sh:path soc:additionalNotes ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "additionalNotes" ;
    ] ;
    sh:property [
        sh:path soc:safetyDataSheetLink ;
        sh:datatype xsd:anyURI ;
        sh:maxCount 1 ;
        sh:name "safetyDataSheetLink" ;
    ] ;
    sh:property [
        sh:path soc:concentration ;
        sh:class soc:Concentration ;
        sh:maxCount 1 ;
        sh:name "concentration" ;
    ] ;
    sh:property [
        sh:path soc:regulatoryThreshold ;
        sh:class soc:RegulatoryThreshold ;
        sh:maxCount 1 ;
        sh:name "regulatoryThreshold" ;
    ] ;
    sh:property [
        sh:path soc:alternatives ;
        sh:class soc:Substance ;
        sh:name "alternatives" ;
    ] .

# -----------------------------------------------------------------------------
# Concentration
# -----------------------------------------------------------------------------
soc:ConcentrationShape
    a sh:NodeShape ;
    sh:targetClass soc:Concentration ;
    rdfs:label "Concentration shape" ;
    sh:property [
        sh:path soc:concentrationValue ;
        sh:datatype xsd:double ;
        sh:minInclusive 0.0 ;
        sh:maxCount 1 ;
        sh:name "concentrationValue" ;
    ] ;
    sh:property [
        sh:path soc:concentrationUnit ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "concentrationUnit" ;
    ] ;
    sh:property [
        sh:path soc:concentrationUncertainty ;
        sh:datatype xsd:double ;
        sh:minInclusive 0.0 ;
        sh:maxCount 1 ;
        sh:name "concentrationUncertainty" ;
    ] ;
    sh:property [
        sh:path soc:measurementMethod ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "measurementMethod" ;
    ] .

# -----------------------------------------------------------------------------
# RegulatoryThreshold
# -----------------------------------------------------------------------------
soc:RegulatoryThresholdShape
    a sh:NodeShape ;
    sh:targetClass soc:RegulatoryThreshold ;
    rdfs:label "Regulatory Threshold shape" ;
    sh:property [
        sh:path soc:thresholdValue ;
        sh:datatype xsd:double ;
        sh:minInclusive 0.0 ;
        sh:maxCount 1 ;
        sh:name "thresholdValue" ;
    ] ;
    sh:property [
        sh:path soc:thresholdUnit ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "thresholdUnit" ;
    ] ;
    sh:property [
        sh:path soc:regulationReference ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "regulationReference" ;
    ] ;
    sh:property [
        sh:path soc:thresholdExceeded ;
        sh:datatype xsd:boolean ;
        sh:maxCount 1 ;
        sh:name "thresholdExceeded" ;
    ] .

# -----------------------------------------------------------------------------
# SvhcCandidateListCheck
# -----------------------------------------------------------------------------
soc:SvhcCandidateListCheckShape
    a sh:NodeShape ;
    sh:targetClass soc:SvhcCandidateListCheck ;
    rdfs:label "SVHC Candidate List Check shape" ;
    sh:property [
        sh:path soc:svhcCheckDate ;
        sh:datatype xsd:date ;
        sh:maxCount 1 ;
        sh:name "svhcCheckDate" ;
    ] ;
    sh:property [
        sh:path soc:svhcListVersion ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "svhcListVersion" ;
    ] ;
    sh:property [
        sh:path soc:svhcPresent ;
        sh:datatype xsd:boolean ;
        sh:maxCount 1 ;
        sh:name "svhcPresent" ;
    ] .

# -----------------------------------------------------------------------------
# Hazard
# -----------------------------------------------------------------------------
soc:HazardShape
    a sh:NodeShape ;
    sh:targetClass soc:Hazard ;
    rdfs:label "Hazard shape" ;
    sh:property [
        sh:path soc:hazardCode ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "hazardCode" ;
    ] ;
    sh:property [
        sh:path soc:hazardClass ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "hazardClass" ;
    ] ;
    sh:property [
        sh:path soc:signalWord ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "signalWord" ;
    ] ;
    sh:property [
        sh:path soc:hazardStatement ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "hazardStatement" ;
    ] .

# -----------------------------------------------------------------------------
# OtherListCompliance
# -----------------------------------------------------------------------------
soc:OtherListComplianceShape
    a sh:NodeShape ;
    sh:targetClass soc:OtherListCompliance ;
    rdfs:label "Other List Compliance shape" ;
    sh:property [
        sh:path soc:listName ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "listName" ;
    ] ;
    sh:property [
        sh:path soc:listComplianceStatus ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "listComplianceStatus" ;
    ] ;
    sh:property [
        sh:path soc:listVersion ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "listVersion" ;
    ] .

# -----------------------------------------------------------------------------
# DueDiligenceStatement
# -----------------------------------------------------------------------------
soc:DueDiligenceStatementShape
    a sh:NodeShape ;
    sh:targetClass soc:DueDiligenceStatement ;
    rdfs:label "Due Diligence Statement shape" ;
    sh:property [
        sh:path soc:dueDiligenceScope ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "dueDiligenceScope" ;
    ] ;
    sh:property [
        sh:path soc:dueDiligenceDate ;
        sh:datatype xsd:date ;
        sh:maxCount 1 ;
        sh:name "dueDiligenceDate" ;
    ] ;
    sh:property [
        sh:path soc:dueDiligenceOutcome ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "dueDiligenceOutcome" ;
    ] ;
    sh:property [
        sh:path soc:dueDiligenceDocumentLink ;
        sh:datatype xsd:anyURI ;
        sh:maxCount 1 ;
        sh:name "dueDiligenceDocumentLink" ;
    ] ;
    sh:property [
        sh:path soc:performedBy ;
        sh:class soc:DueDiligencePerformer ;
        sh:maxCount 1 ;
        sh:name "performedBy" ;
    ] .

# -----------------------------------------------------------------------------
# DueDiligencePerformer
# -----------------------------------------------------------------------------
soc:DueDiligencePerformerShape
    a sh:NodeShape ;
    sh:targetClass soc:DueDiligencePerformer ;
    rdfs:label "Due Diligence Performer shape" ;
    sh:property [
        sh:path soc:performerName ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "performerName" ;
    ] ;
    sh:property [
        sh:path soc:performerId ;
        sh:datatype xsd:string ;
        sh:maxCount 1 ;
        sh:name "performerId" ;
    ] .
