@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix : <https://www.gov.br/governodigital/pt-br/infraestrutura-nacional-de-dados/catalogo-nacional-de-dados/releases/DCAT-BR-1.0.0/shacl/shapes.ttl#> .
@prefix adms: <http://www.w3.org/ns/adms#> .
@prefix cc: <http://creativecommons.org/ns#> .
@prefix dcat: <http://www.w3.org/ns/dcat#> .
@prefix dcatbr: <http://purl.org/dcat-br/> .
@prefix dct: <http://purl.org/dc/terms/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix locn: <http://www.w3.org/ns/locn#> .
@prefix odrl: <http://www.w3.org/ns/odrl/2/> .
@prefix org: <http://www.w3.org/ns/org#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix prov: <http://www.w3.org/ns/prov#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix schema: <http://schema.org/> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix spdx: <http://spdx.org/rdf/terms#> .
@prefix time: <http://www.w3.org/2006/time#> .
@prefix vann: <http://purl.org/vocab/vann/> .
@prefix vcard: <http://www.w3.org/2006/vcard/ns#> .
@prefix voaf: <http://purl.org/vocommons/voaf#> .
@prefix wdrs: <http://www.w3.org/2007/05/powder-s#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

<https://www.gov.br/governodigital/pt-br/infraestrutura-nacional-de-dados/catalogo-nacional-de-dados/releases/DCAT-BR-1.0.0/shacl/shapes.ttl>
    a owl:Ontology ;
    dct:conformsTo <https://www.w3.org/TR/shacl> ;
    dct:title "DCAT-BR 1.0.0 - SHACL shapes (core)"@en ;
    dct:title "DCAT-BR 1.0.0 - SHACL shapes (núcleo)"@pt-BR ;
    dct:description "Este arquivo especifica as restrições principais sobre propriedades e classes expressas pelo DCAT-BR em SHACL. Aqui ficam cardinalidades, existência, tipo literal e nodeKind. Restrições de range por classe ficam em range.ttl."@pt-BR ;
    dct:description "This file specifies the core constraints on properties and classes expressed by DCAT-BR in SHACL. Cardinalities, existence, literal datatype and nodeKind are here. Class-range constraints belong in range.ttl."@en ;
    owl:versionInfo "1.0.0" .

# -------------------------------------------------------------------------
# Helper shapes
# -------------------------------------------------------------------------

:NonEmptyText_Shape
    a sh:NodeShape ;
    rdfs:label "Texto não vazio"@pt-BR ;
    rdfs:label "Non-empty text"@en ;
    sh:property [
        sh:path rdf:value ;
        sh:nodeKind sh:Literal
    ] .

:DateOrDateTimeDataType_Shape
    a sh:NodeShape ;
    rdfs:label "Disjunção de data/hora"@pt-BR ;
    rdfs:label "Date/time disjunction"@en ;
    rdfs:comment "Verifica que um valor literal é tipado como xsd:date, xsd:dateTime, xsd:gYear ou xsd:gYearMonth."@pt-BR ;
    rdfs:comment "Checks that a literal value is typed as xsd:date, xsd:dateTime, xsd:gYear or xsd:gYearMonth."@en ;
    sh:message "Os valores devem ser tipados como xsd:date, xsd:dateTime, xsd:gYear ou xsd:gYearMonth."@pt-BR ;
    sh:message "Values must be typed as xsd:date, xsd:dateTime, xsd:gYear or xsd:gYearMonth."@en ;
    sh:or (
        [ sh:datatype xsd:date ]
        [ sh:datatype xsd:dateTime ]
        [ sh:datatype xsd:gYear ]
        [ sh:datatype xsd:gYearMonth ]
    ) .

# -------------------------------------------------------------------------
# Agent (foaf:Agent)
# -------------------------------------------------------------------------

:Agent_Shape
    a sh:NodeShape ;
    rdfs:label "Agente"@pt-BR ;
    rdfs:label "Agent"@en ;
    sh:targetClass foaf:Agent ;
    sh:property [
        sh:path foaf:name ;
        sh:minCount 1 ;
        sh:nodeKind sh:Literal ;
        sh:minLength 2 ;
        sh:and (
            [ sh:not [ sh:pattern "^\\s+$" ] ]
            [ sh:not [ sh:pattern "^(.)\\1{3,}$" ] ]
        ) ;
        sh:severity sh:Violation ;
        sh:message "foaf:name é obrigatório e deve ser um literal com pelo menos 2 caracteres (não pode ser apenas espaços ou caracteres repetidos)."@pt-BR
    ] .

# -------------------------------------------------------------------------
# vCard contact point (vcard:Organization)
# -------------------------------------------------------------------------

:VCard_Shape
    a sh:NodeShape ;
    rdfs:label "vCard"@pt-BR ;
    rdfs:label "vCard"@en ;
    sh:targetClass vcard:Organization ;
    sh:property [
        sh:path vcard:fn ;
        sh:minCount 1 ;
        sh:nodeKind sh:Literal ;
        sh:minLength 2 ;
        sh:and (
            [ sh:not [ sh:pattern "^\\s+$" ] ]
            [ sh:not [ sh:pattern "^(.)\\1{3,}$" ] ]
        ) ;
        sh:severity sh:Violation ;
        sh:message "vcard:fn é obrigatório e deve ser um literal com pelo menos 2 caracteres (não pode ser apenas espaços ou caracteres repetidos)."@pt-BR
    ], [
        sh:path vcard:hasEmail ;
        sh:minCount 1 ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "vcard:hasEmail é obrigatório e deve ser um recurso (IRI ou nó anônimo), tipicamente um mailto:."@pt-BR
    ] .

# -------------------------------------------------------------------------
# spdx:Checksum
# -------------------------------------------------------------------------

:Checksum_Shape
    a sh:NodeShape ;
    rdfs:label "Verificação de Integridade"@pt-BR ;
    rdfs:label "Checksum"@en ;
    sh:targetClass spdx:Checksum ;
    sh:property [
        sh:path spdx:algorithm ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "spdx:algorithm é obrigatório e deve ter exatamente um valor (recurso) representando o algoritmo usado."@pt-BR
    ], [
        sh:path spdx:checksumValue ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:datatype xsd:hexBinary ;
        sh:severity sh:Violation ;
        sh:message "spdx:checksumValue é obrigatório e deve ter exatamente um valor do tipo xsd:hexBinary."@pt-BR
    ] .

# -------------------------------------------------------------------------
# dct:Location
# -------------------------------------------------------------------------

:Location_Shape
    a sh:NodeShape ;
    rdfs:label "Local"@pt-BR ;
    rdfs:label "Location"@en ;
    sh:targetClass dct:Location ;
    sh:property [
        sh:path dcat:bbox ;
        sh:maxCount 1 ;
        sh:nodeKind sh:Literal ;
        sh:severity sh:Violation ;
        sh:message "dcat:bbox deve ser um literal (use no máximo 1 valor)."@pt-BR
    ], [
        sh:path dcat:centroid ;
        sh:maxCount 1 ;
        sh:nodeKind sh:Literal ;
        sh:severity sh:Violation ;
        sh:message "dcat:centroid deve ser um literal (use no máximo 1 valor)."@pt-BR
    ], [
        sh:path locn:geometry ;
        sh:maxCount 1 ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "locn:geometry deve ser um recurso (IRI ou nó anônimo) representando a geometria (use no máximo 1 valor)."@pt-BR
    ] .

# -------------------------------------------------------------------------
# dct:PeriodOfTime
# -------------------------------------------------------------------------

:PeriodOfTime_Shape
    a sh:NodeShape ;
    rdfs:label "Período de Tempo"@pt-BR ;
    rdfs:label "PeriodOfTime"@en ;
    sh:targetClass dct:PeriodOfTime ;
    sh:property [
        sh:path dcat:startDate ;
        sh:maxCount 1 ;
        sh:node :DateOrDateTimeDataType_Shape ;
        sh:severity sh:Violation ;
        sh:message "dcat:startDate deve ter no máximo 1 valor e ser uma data (xsd:date, xsd:dateTime, xsd:gYear ou xsd:gYearMonth)."@pt-BR
    ], [
        sh:path dcat:endDate ;
        sh:maxCount 1 ;
        sh:node :DateOrDateTimeDataType_Shape ;
        sh:severity sh:Violation ;
        sh:message "dcat:endDate deve ter no máximo 1 valor e ser uma data (xsd:date, xsd:dateTime, xsd:gYear ou xsd:gYearMonth)."@pt-BR
    ], [
        sh:path time:hasBeginning ;
        sh:maxCount 1 ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "time:hasBeginning deve ser um recurso (use no máximo 1 valor)."@pt-BR
    ], [
        sh:path time:hasEnd ;
        sh:maxCount 1 ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "time:hasEnd deve ser um recurso (use no máximo 1 valor)."@pt-BR
    ] .

# -------------------------------------------------------------------------
# dcat:Distribution
# -------------------------------------------------------------------------

:Distribution_Shape
    a sh:NodeShape ;
    rdfs:label "Distribuição"@pt-BR ;
    rdfs:label "Distribution"@en ;
    sh:targetClass dcat:Distribution ;
    sh:property [
        sh:path dcat:accessURL ;
        sh:minCount 1 ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dcat:accessURL é obrigatório e deve ter pelo menos 1 valor (recurso/IRI ou nó anônimo)."@pt-BR
    ], [
        sh:path dct:title ;
        sh:minCount 1 ;
        sh:nodeKind sh:Literal ;
        sh:minLength 3 ;
        sh:and (
            [ sh:not [ sh:pattern "^\\s+$" ] ]
            [ sh:not [ sh:pattern "^(.)\\1{3,}$" ] ]
        ) ;
        sh:severity sh:Violation ;
        sh:message "dct:title é obrigatório e deve ser um literal com pelo menos 3 caracteres (não pode ser vazio/repetitivo)."@pt-BR
    ], [
        sh:path dct:description ;
        sh:minCount 1 ;
        sh:nodeKind sh:Literal ;
        sh:minLength 10 ;
        sh:and (
            [ sh:not [ sh:pattern "^\\s+$" ] ]
            [ sh:not [ sh:pattern "^(.)\\1{3,}$" ] ]
        ) ;
        sh:severity sh:Violation ;
        sh:message "dct:description é obrigatório e deve ser um literal com pelo menos 10 caracteres (não pode ser vazio/repetitivo)."@pt-BR
    ], [
        sh:path dcat:downloadURL ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dcat:downloadURL deve ser um recurso (URI/IRI ou nó anônimo)."@pt-BR
    ], [
        sh:path dct:format ;
        sh:maxCount 1 ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dct:format deve ter no máximo 1 valor e ser um recurso (URI/IRI ou nó anônimo)."@pt-BR
    ], [
        sh:path dcat:mediaType ;
        sh:maxCount 1 ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dcat:mediaType deve ter no máximo 1 valor e ser um recurso (URI/IRI ou nó anônimo)."@pt-BR
    ], [
        sh:path dcat:compressFormat ;
        sh:maxCount 1 ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dcat:compressFormat deve ter no máximo 1 valor e ser um recurso (URI/IRI ou nó anônimo)."@pt-BR
    ], [
        sh:path dct:language ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dct:language deve ser um recurso (URI/IRI ou nó anônimo)."@pt-BR
    ], [
        sh:path dct:license ;
        sh:maxCount 1 ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dct:license deve ter no máximo 1 valor e ser um recurso (URI/IRI ou nó anônimo)."@pt-BR
    ], [
        sh:path dct:rights ;
        sh:maxCount 1 ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dct:rights deve ter no máximo 1 valor e ser um recurso (URI/IRI ou nó anônimo)."@pt-BR
    ],  [
        sh:path spdx:checksum ;
        sh:maxCount 1 ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "spdx:checksum deve ter no máximo 1 valor e ser um recurso spdx:Checksum."@pt-BR
    ], [
        sh:path dct:issued ;
        sh:maxCount 1 ;
        sh:node :DateOrDateTimeDataType_Shape ;
        sh:severity sh:Violation ;
        sh:message "dct:issued deve ter no máximo 1 valor e ser uma data válida."@pt-BR
    ], [
        sh:path dct:modified ;
        sh:maxCount 1 ;
        sh:node :DateOrDateTimeDataType_Shape ;
        sh:severity sh:Violation ;
        sh:message "dct:modified deve ter no máximo 1 valor e ser uma data válida."@pt-BR
    ], [
        sh:path dct:type ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dct:type deve ser um recurso (URI/IRI ou nó anônimo)."@pt-BR
    ], [
        sh:path foaf:page ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "foaf:page deve ser um recurso (URI/IRI ou nó anônimo)."@pt-BR
    ] .

# -------------------------------------------------------------------------
# dcat:DataService
# -------------------------------------------------------------------------

:DataService_Shape
    a sh:NodeShape ;
    rdfs:label "Serviço de Dados"@pt-BR ;
    rdfs:label "Data Service"@en ;
    sh:targetClass dcat:DataService ;
    sh:property [
        sh:path dct:title ;
        sh:minCount 1 ;
        sh:nodeKind sh:Literal ;
        sh:minLength 3 ;
        sh:and (
            [ sh:not [ sh:pattern "^\\s+$" ] ]
            [ sh:not [ sh:pattern "^(.)\\1{3,}$" ] ]
        ) ;
        sh:severity sh:Violation ;
        sh:message "dct:title é obrigatório e deve ser um literal com pelo menos 3 caracteres (não pode ser vazio/repetitivo)."@pt-BR
    ], [
        sh:path dct:description ;
        sh:minCount 1 ;
        sh:nodeKind sh:Literal ;
        sh:minLength 10 ;
        sh:and (
            [ sh:not [ sh:pattern "^\\s+$" ] ]
            [ sh:not [ sh:pattern "^(.)\\1{3,}$" ] ]
        ) ;
        sh:severity sh:Violation ;
        sh:message "dct:description é obrigatório e deve ser um literal com pelo menos 10 caracteres (não pode ser vazio/repetitivo)."@pt-BR
    ], [
        sh:path dcat:endpointURL ;
        sh:minCount 1 ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dcat:endpointURL é obrigatório e deve ter pelo menos 1 valor (recurso/IRI ou nó anônimo)."@pt-BR
    ], [
        sh:path dcat:endpointDescription ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dcat:endpointDescription deve ser um recurso (URI/IRI ou nó anônimo) apontando para documentação técnica."@pt-BR
    ], [
        sh:path dcat:contactPoint ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dcat:contactPoint deve ser um recurso vcard:Organization (com vcard:fn e vcard:hasEmail)."@pt-BR
    ], [
        sh:path dct:publisher ;
        sh:maxCount 1 ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dct:publisher deve ter no máximo 1 valor e ser um recurso (URI/IRI ou nó anônimo) representando o publicador."@pt-BR
    ], [
        sh:path dct:license ;
        sh:maxCount 1 ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dct:license deve ter no máximo 1 valor e ser um recurso (URI/IRI ou nó anônimo)."@pt-BR
    ], [
        sh:path dcat:landingPage ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dcat:landingPage deve ser um recurso (URI/IRI ou nó anônimo)."@pt-BR
    ], [
        sh:path dcat:keyword ;
        sh:nodeKind sh:Literal ;
        sh:severity sh:Violation ;
        sh:message "dcat:keyword deve ser um literal (texto) representando palavra-chave."@pt-BR
    ], [
        sh:path dcat:theme ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dcat:theme deve ser um recurso (URI/IRI ou nó anônimo) representando um conceito de tema."@pt-BR
    ], [
        sh:path dcat:servesDataset ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dcat:servesDataset deve ser um recurso (URI/IRI ou nó anônimo) apontando para o dataset servido."@pt-BR
    ] .

# -------------------------------------------------------------------------
# dcat:Dataset
# -------------------------------------------------------------------------

:Dataset_Shape
    a sh:NodeShape ;
    rdfs:label "Conjunto de Dados"@pt-BR ;
    rdfs:label "Dataset"@en ;
    sh:targetClass dcat:Dataset ;
    sh:property [
        sh:path dct:title ;
        sh:minCount 1 ;
        sh:nodeKind sh:Literal ;
        sh:minLength 3 ;
        sh:and (
            [ sh:not [ sh:pattern "^\\s+$" ] ]
            [ sh:not [ sh:pattern "^(.)\\1{3,}$" ] ]
        ) ;
        sh:severity sh:Violation ;
        sh:message "dct:title é obrigatório e deve ser um literal com pelo menos 3 caracteres (não pode ser vazio/repetitivo)."@pt-BR
    ], [
        sh:path dct:description ;
        sh:minCount 1 ;
        sh:nodeKind sh:Literal ;
        sh:minLength 10 ;
        sh:and (
            [ sh:not [ sh:pattern "^\\s+$" ] ]
            [ sh:not [ sh:pattern "^(.)\\1{3,}$" ] ]
        ) ;
        sh:severity sh:Violation ;
        sh:message "dct:description é obrigatório e deve ser um literal com pelo menos 10 caracteres (não pode ser vazio/repetitivo)."@pt-BR
    ], [
        sh:path dct:identifier ;
        sh:nodeKind sh:Literal ;
        sh:severity sh:Violation ;
        sh:message "dct:identifier deve ser um literal (texto) que identifica unicamente o conjunto de dados."@pt-BR
    ], [
        sh:path dct:accessRights ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dct:accessRights é obrigatório, deve ter exatamente 1 valor e deve ser um recurso (URI/IRI ou nó anônimo)."@pt-BR
    ], [
        sh:path dct:accrualPeriodicity ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dct:accrualPeriodicity é obrigatório, deve ter exatamente 1 valor e deve ser um recurso (URI/IRI ou nó anônimo)."@pt-BR
    ], [
        sh:path dcat:contactPoint ;
        sh:minCount 1 ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dcat:contactPoint é obrigatório e deve ser um recurso vcard:Organization (com vcard:fn e vcard:hasEmail)."@pt-BR
    ], [
        sh:path dct:publisher ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dct:publisher é obrigatório, deve ter exatamente 1 valor e deve ser um recurso (URI/IRI ou nó anônimo) representando o publicador."@pt-BR
    ], [
        sh:path dct:creator ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dct:creator deve ser um recurso (URI/IRI ou nó anônimo) representando o criador do conjunto de dados."@pt-BR
    ], [
        sh:path dct:issued ;
        sh:maxCount 1 ;
        sh:node :DateOrDateTimeDataType_Shape ;
        sh:severity sh:Violation ;
        sh:message "dct:issued deve ter no máximo 1 valor e ser uma data válida."@pt-BR
    ], [
        sh:path dct:modified ;
        sh:maxCount 1 ;
        sh:node :DateOrDateTimeDataType_Shape ;
        sh:severity sh:Violation ;
        sh:message "dct:modified deve ter no máximo 1 valor e ser uma data válida."@pt-BR
    ], [
        sh:path dct:spatial ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dct:spatial deve ser um recurso (URI/IRI ou nó anônimo) representando a cobertura geográfica."@pt-BR
    ], [
        sh:path dct:temporal ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dct:temporal deve ser um recurso (URI/IRI ou nó anônimo) representando a cobertura temporal."@pt-BR
    ], [
        sh:path dcat:distribution ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dcat:distribution deve ser um recurso (URI/IRI ou nó anônimo) apontando para uma distribuição."@pt-BR
    ], [
        sh:path dcat:keyword ;
        sh:nodeKind sh:Literal ;
        sh:severity sh:Violation ;
        sh:message "dcat:keyword deve ser um literal (texto) representando palavra-chave."@pt-BR
    ], [
        sh:path dcat:landingPage ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dcat:landingPage deve ser um recurso (URI/IRI ou nó anônimo)."@pt-BR
    ], [
        sh:path dcat:theme ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dcat:theme deve ser um recurso (URI/IRI ou nó anônimo) representando um conceito de tema."@pt-BR
    ], [
        sh:path dct:type ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dct:type deve ser um recurso (URI/IRI ou nó anônimo) representando o tipo do conjunto de dados."@pt-BR
    ], [
        sh:path dcat:version ;
        sh:maxCount 1 ;
        sh:nodeKind sh:Literal ;
        sh:severity sh:Violation ;
        sh:message "dcat:version deve ter no máximo 1 valor e ser um literal (texto)."@pt-BR
    ], [
        sh:path prov:wasGeneratedBy ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "prov:wasGeneratedBy deve ser um recurso (URI/IRI ou nó anônimo) representando a atividade que gerou o conjunto de dados."@pt-BR
    ], [
        sh:path dcat:inSeries ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dcat:inSeries deve ser um recurso (URI/IRI ou nó anônimo) representando a série (normalmente um dcat:Dataset)."@pt-BR
    ], [
        sh:path foaf:page ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "foaf:page deve ser um recurso (URI/IRI ou nó anônimo) apontando para uma página web relacionada."@pt-BR
    ] .

# -------------------------------------------------------------------------
# Extras DCAT-BR (campos adicionais)
# -------------------------------------------------------------------------

:DCATBR_Extras_Shape
    a sh:NodeShape ;
    rdfs:label "Extensões DCAT-BR"@pt-BR ;
    rdfs:label "DCAT-BR extensions"@en ;
    sh:targetClass dcat:Resource ;
    sh:property [
        sh:path dcatbr:relacionadoODS ;
        sh:maxCount 1 ;
        sh:datatype xsd:boolean ;
        sh:severity sh:Violation ;
        sh:message "dcatbr:relacionadoODS deve ter no máximo 1 valor do tipo xsd:boolean."@pt-BR
    ], [
        sh:path dcatbr:dadosRacaEtnia ;
        sh:maxCount 1 ;
        sh:datatype xsd:boolean ;
        sh:severity sh:Violation ;
        sh:message "dcatbr:dadosRacaEtnia deve ter no máximo 1 valor do tipo xsd:boolean."@pt-BR
    ], [
        sh:path dcatbr:dadosGenero ;
        sh:maxCount 1 ;
        sh:datatype xsd:boolean ;
        sh:severity sh:Violation ;
        sh:message "dcatbr:dadosGenero deve ter no máximo 1 valor do tipo xsd:boolean."@pt-BR
    ], [
        sh:path dcatbr:ods ;
        sh:nodeKind sh:BlankNodeOrIRI ;
        sh:severity sh:Violation ;
        sh:message "dcatbr:ods deve ser um recurso (URI/IRI ou nó anônimo), recomendado como skos:Concept."@pt-BR
    ], [
        sh:path dcat:spatialResolutionInMeters ;
        sh:maxCount 1 ;
        sh:datatype xsd:decimal ;
        sh:severity sh:Violation ;
        sh:message "dcat:spatialResolutionInMeters deve ter no máximo 1 valor do tipo xsd:decimal."@pt-BR
    ] .
