tbox: v2.2 - polymorphisme declare sur 19 proprietes, 17 domaines poses, provenance portee par les classes concretes, GovernanceLayerObject rattachee, affectations de gouvernance completes (12 completees, 10 SDO, 1 PO, 16 stewards par objet metier), Panel Coverage gouverne. Validation SHACL sans violation bloquante
This commit is contained in:
+178
-101
@@ -12,7 +12,7 @@ pr: a owl:Ontology ;
|
||||
dcterms:title "Pernod Ricard Data Meta Model" ;
|
||||
rdfs:comment "OWL T-Box. Six layers (Ownership, Business, Logical, Delivery, Physical, Consumption) crossed with a provenance axis (Defined vs Captured). Defined objects are written by governance and reviewed; Captured objects are read from Snowflake, Tableau and Looker and are rebuilt, never edited. Bridge annotation properties are declared for future alignment with domain ontologies." ;
|
||||
owl:priorVersion pr:1.5 ;
|
||||
owl:versionIRI pr:2.0 ;
|
||||
owl:versionIRI pr:2.2 ;
|
||||
owl:versionInfo "1.6.0-draft-2026-07-30" .
|
||||
|
||||
pr:BusinessIntelligenceTool a pr:SystemType ;
|
||||
@@ -29,6 +29,7 @@ pr:KeyPerformanceIndicator a owl:Class ;
|
||||
rdfs:comment "An elevated Metric. Use this class rather than the deprecated isKPI flag." ;
|
||||
rdfs:subClassOf pr:Metric ;
|
||||
pr:acronym "KPI" ;
|
||||
pr:authoringMode "ASSERTED" ;
|
||||
pr:isAbstract false ;
|
||||
pr:shortLabel "KPI" .
|
||||
|
||||
@@ -51,7 +52,8 @@ pr:activationStatus a owl:DatatypeProperty,
|
||||
pr:arbitrationStatus a owl:DatatypeProperty ;
|
||||
rdfs:label "arbitration Status" ;
|
||||
rdfs:comment "TO_ARBITRATE blocks publication (OW-007). Use this on the object rather than tracking arbitration in a side spreadsheet." ;
|
||||
rdfs:range xsd:string .
|
||||
rdfs:range xsd:string ;
|
||||
pr:polymorphic true .
|
||||
|
||||
pr:authoringMode a owl:AnnotationProperty ;
|
||||
rdfs:label "authoring Mode" ;
|
||||
@@ -60,7 +62,8 @@ pr:authoringMode a owl:AnnotationProperty ;
|
||||
pr:belongsTo a owl:FunctionalProperty,
|
||||
owl:ObjectProperty ;
|
||||
rdfs:label "belongs To" ;
|
||||
rdfs:comment "Position in the categorization tree. One property for the whole tree: SubDomain belongs to DataDomain, BusinessObject belongs to SubDomain. Scope is enforced per class by SHACL rather than by two near-identical properties, and the same relation will serve if a domain family ever appears. Deliberately NOT transitive: entailment would produce two values and break the maxCount 1 shape. To walk the ancestry, use the property path belongsTo+ in the query." .
|
||||
rdfs:comment "Position in the categorization tree. One property for the whole tree: SubDomain belongs to DataDomain, BusinessObject belongs to SubDomain. Scope is enforced per class by SHACL rather than by two near-identical properties, and the same relation will serve if a domain family ever appears. Deliberately NOT transitive: entailment would produce two values and break the maxCount 1 shape. To walk the ancestry, use the property path belongsTo+ in the query." ;
|
||||
pr:polymorphic true .
|
||||
|
||||
pr:businessDefinition a owl:DatatypeProperty ;
|
||||
rdfs:label "business Definition" ;
|
||||
@@ -69,16 +72,19 @@ pr:businessDefinition a owl:DatatypeProperty ;
|
||||
MUST NOT be carried by a BusinessObject: an object gets its meaning through aboutConcept. Two definitions for one notion are two definitions free to diverge. Enforced by SHACL rather than by rdfs:domain, because Data Elements legitimately carry one too and a declared domain would make them entail BusinessConcept -- which the disjointness axioms would then reject.
|
||||
|
||||
MIGRATION: text currently on a Business Object moves to the Concept named by its aboutConcept.""" ;
|
||||
rdfs:domain pr:BusinessConcept ;
|
||||
rdfs:range xsd:string .
|
||||
|
||||
pr:businessRule a owl:DatatypeProperty ;
|
||||
rdfs:label "business Rule" ;
|
||||
rdfs:domain pr:BusinessConcept ;
|
||||
rdfs:range xsd:string .
|
||||
|
||||
pr:canonicalName a owl:DatatypeProperty,
|
||||
owl:FunctionalProperty ;
|
||||
rdfs:label "canonical Name" ;
|
||||
rdfs:range xsd:string .
|
||||
rdfs:range xsd:string ;
|
||||
pr:polymorphic true .
|
||||
|
||||
pr:computedBy a owl:ObjectProperty ;
|
||||
rdfs:label "computed By" ;
|
||||
@@ -107,11 +113,13 @@ pr:containsBIField a owl:ObjectProperty ;
|
||||
|
||||
pr:creationDate a owl:DatatypeProperty ;
|
||||
rdfs:label "creation Date" ;
|
||||
rdfs:range xsd:date .
|
||||
rdfs:range xsd:date ;
|
||||
pr:polymorphic true .
|
||||
|
||||
pr:definitionAddress a owl:DatatypeProperty ;
|
||||
rdfs:label "definition Address" ;
|
||||
rdfs:comment "Git URI of the code behind a Transformation. Connects the graph to the repository." ;
|
||||
rdfs:domain pr:Transformation ;
|
||||
rdfs:range xsd:anyURI .
|
||||
|
||||
pr:denotes a owl:AnnotationProperty ;
|
||||
@@ -158,7 +166,8 @@ pr:environment a owl:DatatypeProperty,
|
||||
|
||||
pr:exampleValue a owl:DatatypeProperty ;
|
||||
rdfs:label "example Value" ;
|
||||
rdfs:range xsd:string .
|
||||
rdfs:range xsd:string ;
|
||||
pr:polymorphic true .
|
||||
|
||||
pr:exposes a owl:ObjectProperty ;
|
||||
rdfs:label "exposes" ;
|
||||
@@ -177,23 +186,25 @@ So: TRANSITIONAL CONTROL. Asserted directly, and that is all. No rule is written
|
||||
|
||||
Retirement criterion, to be measured rather than debated: when the lineage chain reproduces the asserted link for more than 95% of certified BI fields across three consecutive reconciliation cycles, the direct link is derivable and can go.""" ;
|
||||
rdfs:domain pr:BusinessIntelligenceField ;
|
||||
rdfs:range pr:Metric ;
|
||||
pr:authoringMode "PROPOSED_CONFIRMED" .
|
||||
rdfs:range pr:Metric .
|
||||
|
||||
pr:expression a owl:DatatypeProperty ;
|
||||
rdfs:label "expression" ;
|
||||
rdfs:comment "The calculated-field formula, Tableau or LookML. Compared against the Metric formula to detect definition drift." ;
|
||||
rdfs:domain pr:BusinessIntelligenceField ;
|
||||
rdfs:range xsd:string .
|
||||
|
||||
pr:formula a owl:DatatypeProperty ;
|
||||
rdfs:label "formula" ;
|
||||
rdfs:domain pr:Metric ;
|
||||
rdfs:range xsd:string .
|
||||
|
||||
pr:fullyQualifiedName a owl:DatatypeProperty,
|
||||
owl:FunctionalProperty ;
|
||||
rdfs:label "fully Qualified Name" ;
|
||||
rdfs:comment "DATABASE.SCHEMA.RELATION[.COLUMN]. The actual join key against INFORMATION_SCHEMA: a bare physical name is ambiguous as soon as the same column name exists in two tables." ;
|
||||
rdfs:range xsd:string .
|
||||
rdfs:range xsd:string ;
|
||||
pr:polymorphic true .
|
||||
|
||||
pr:governedBy a owl:FunctionalProperty,
|
||||
owl:ObjectProperty ;
|
||||
@@ -204,7 +215,8 @@ pr:governedBy a owl:FunctionalProperty,
|
||||
pr:harvestDate a owl:DatatypeProperty ;
|
||||
rdfs:label "harvest Date" ;
|
||||
rdfs:comment "Staleness marker. A Captured Object not refreshed by the last run is a deletion candidate, not a fact." ;
|
||||
rdfs:range xsd:dateTime .
|
||||
rdfs:range xsd:dateTime ;
|
||||
pr:polymorphic true .
|
||||
|
||||
pr:harvestSource a owl:AnnotationProperty ;
|
||||
rdfs:label "harvest Source" ;
|
||||
@@ -279,7 +291,8 @@ pr:hostedOn a owl:FunctionalProperty,
|
||||
pr:identifier a owl:DatatypeProperty,
|
||||
owl:FunctionalProperty ;
|
||||
rdfs:label "identifier" ;
|
||||
rdfs:range xsd:string .
|
||||
rdfs:range xsd:string ;
|
||||
pr:polymorphic true .
|
||||
|
||||
pr:isAbout a owl:FunctionalProperty,
|
||||
owl:ObjectProperty ;
|
||||
@@ -308,24 +321,29 @@ pr:isInSchema a owl:FunctionalProperty,
|
||||
owl:ObjectProperty ;
|
||||
rdfs:label "is In Schema" ;
|
||||
rdfs:comment "Domain deliberately not declared, and the shapes must keep this OPTIONAL: Neo4j has no schema and BigQuery calls the level a dataset. A minCount 1 would break on the first harvest outside Snowflake. It is also the only property that would distinguish a tabular Dataset from a Graph, which is why that intermediate level is not declared yet -- one client does not pay for a level of hierarchy." ;
|
||||
rdfs:domain pr:DataStructure ;
|
||||
rdfs:range pr:Schema .
|
||||
|
||||
pr:isNullable a owl:DatatypeProperty ;
|
||||
rdfs:label "is Nullable" ;
|
||||
rdfs:domain pr:Field ;
|
||||
rdfs:range xsd:boolean .
|
||||
|
||||
pr:lastQueryDate a owl:DatatypeProperty ;
|
||||
rdfs:label "last Query Date" ;
|
||||
rdfs:comment "Lets the model say 'documented but unused for eight months'. A rationalisation argument that costs nothing and is denominated in warehouse spend." ;
|
||||
rdfs:domain pr:DataStructure ;
|
||||
rdfs:range xsd:dateTime ;
|
||||
pr:harvestSource "SNOWFLAKE.ACCOUNT_USAGE.ACCESS_HISTORY" .
|
||||
|
||||
pr:lastReviewDate a owl:DatatypeProperty ;
|
||||
rdfs:label "last Review Date" ;
|
||||
rdfs:range xsd:date .
|
||||
rdfs:range xsd:date ;
|
||||
pr:polymorphic true .
|
||||
|
||||
pr:logicalFormat a owl:DatatypeProperty ;
|
||||
rdfs:label "logical Format" ;
|
||||
rdfs:domain pr:DataElement ;
|
||||
rdfs:range xsd:string .
|
||||
|
||||
pr:measures a owl:ObjectProperty ;
|
||||
@@ -340,6 +358,7 @@ pr:monitoredBy a owl:ObjectProperty ;
|
||||
Says what the steward DOES, where the deprecated hasSteward only stated a membership.
|
||||
|
||||
DataProduct is the one exception to inheritance: it packages Data Objects belonging to several Business Objects, so it cannot inherit a single steward and declares its own.""" ;
|
||||
rdfs:domain pr:BusinessObject ;
|
||||
rdfs:range pr:DataSteward .
|
||||
|
||||
pr:operatedBy a owl:FunctionalProperty,
|
||||
@@ -351,11 +370,13 @@ pr:operatedBy a owl:FunctionalProperty,
|
||||
|
||||
pr:ordinalPosition a owl:DatatypeProperty ;
|
||||
rdfs:label "ordinal Position" ;
|
||||
rdfs:domain pr:Field ;
|
||||
rdfs:range xsd:integer .
|
||||
|
||||
pr:ownedBy a owl:ObjectProperty ;
|
||||
rdfs:label "owned By" ;
|
||||
rdfs:range pr:Actor .
|
||||
rdfs:range pr:Actor ;
|
||||
pr:polymorphic true .
|
||||
|
||||
pr:ownedByDomain a owl:FunctionalProperty,
|
||||
owl:ObjectProperty ;
|
||||
@@ -363,7 +384,8 @@ pr:ownedByDomain a owl:FunctionalProperty,
|
||||
rdfs:comment """The single Data Domain with authority to define the object's rule. Absent on Captured Objects: a Snowflake column is attributed through the Data Element mapped to it, never asserted directly.
|
||||
|
||||
Unlike the steward, this one is RE-DECLARABLE on a Data Element. It is inherited by default from the parent chain, but OW-002 attributes an element to the domain that defines its RULE, and a borrowed element -- Brand Code sitting in a Sell Out fact object -- has its rule elsewhere. A Data Element whose owningDomain differs from its parent's is a borrowed element: a signal to check against its represents, not an anomaly to fix.""" ;
|
||||
rdfs:range pr:DataDomain .
|
||||
rdfs:range pr:DataDomain ;
|
||||
pr:polymorphic true .
|
||||
|
||||
pr:packages a owl:ObjectProperty ;
|
||||
rdfs:label "packages" ;
|
||||
@@ -371,15 +393,27 @@ pr:packages a owl:ObjectProperty ;
|
||||
rdfs:domain pr:DataProduct ;
|
||||
rdfs:range pr:DataObject .
|
||||
|
||||
pr:personName a owl:DatatypeProperty ;
|
||||
rdfs:label "person Name" ;
|
||||
rdfs:comment "The name of the person currently holding the post. Declared on Actor rather than on each role, since every role shares it and Actor is their smallest common ancestor below the layer root. Held as a value rather than a node because what changes is the person, not the assignment: the post keeps its identifier, its domain and every edge that points at it, and a change of holder rewrites one literal. Used on actors and nowhere else." ;
|
||||
rdfs:domain pr:Actor ;
|
||||
rdfs:range xsd:string .
|
||||
|
||||
pr:physicalDataType a owl:DatatypeProperty ;
|
||||
rdfs:label "physical Data Type" ;
|
||||
rdfs:domain pr:Field ;
|
||||
rdfs:range xsd:string .
|
||||
|
||||
pr:physicalName a owl:DatatypeProperty,
|
||||
owl:FunctionalProperty ;
|
||||
rdfs:label "physical Name" ;
|
||||
rdfs:comment "Recorded verbatim, never altered (NR-009). Must NOT be carried by a Metric - that is a layer leak; under BR-013 the physical name belongs on the Data Element." ;
|
||||
rdfs:range xsd:string .
|
||||
rdfs:range xsd:string ;
|
||||
pr:polymorphic true .
|
||||
|
||||
pr:polymorphic a owl:AnnotationProperty ;
|
||||
rdfs:label "polymorphic" ;
|
||||
rdfs:comment "Declares that a property deliberately carries no rdfs:domain because it serves several classes with no useful common ancestor. Its scope is controlled class by class in SHACL instead. Without this axiom a deliberate omission and a forgotten one look identical, and no check can tell them apart." .
|
||||
|
||||
pr:primarilyStoredIn a owl:FunctionalProperty,
|
||||
owl:ObjectProperty ;
|
||||
@@ -391,8 +425,7 @@ A SUB-PROPERTY of storedIn on purpose, not a parallel relation. Entailment then
|
||||
Primary and replica rather than master and slave: the industry has moved on, and it reads better to the business.""" ;
|
||||
rdfs:domain pr:DataElement ;
|
||||
rdfs:range pr:Field ;
|
||||
rdfs:subPropertyOf pr:storedIn ;
|
||||
pr:authoringMode "PROPOSED_CONFIRMED" .
|
||||
rdfs:subPropertyOf pr:storedIn .
|
||||
|
||||
pr:produces a owl:ObjectProperty ;
|
||||
rdfs:label "produces" ;
|
||||
@@ -407,6 +440,7 @@ pr:qualifiedBy a owl:ObjectProperty ;
|
||||
|
||||
pr:queryCount a owl:DatatypeProperty ;
|
||||
rdfs:label "query Count" ;
|
||||
rdfs:domain pr:DataStructure ;
|
||||
rdfs:range xsd:integer .
|
||||
|
||||
pr:referencesSourceField a owl:ObjectProperty ;
|
||||
@@ -430,7 +464,8 @@ Range is deliberately left open and scoped by SHACL per class, because the two u
|
||||
|
||||
A Data Element uses this ONLY when it is dimensional. A measure element reaches meaning through Metric -> computedBy, which says more: it names WHICH metric the meaning travels through. Never both routes on one element.
|
||||
|
||||
Functional at DataObject level only -- not declared owl:FunctionalProperty here, since a single global cardinality would be wrong for one of the two uses.""" .
|
||||
Functional at DataObject level only -- not declared owl:FunctionalProperty here, since a single global cardinality would be wrong for one of the two uses.""" ;
|
||||
pr:polymorphic true .
|
||||
|
||||
pr:servedBy a owl:ObjectProperty ;
|
||||
rdfs:label "served By" ;
|
||||
@@ -438,6 +473,12 @@ pr:servedBy a owl:ObjectProperty ;
|
||||
rdfs:domain pr:DataInterface ;
|
||||
rdfs:range pr:DataStructure .
|
||||
|
||||
pr:serviceCommitment a owl:DatatypeProperty ;
|
||||
rdfs:label "service Commitment" ;
|
||||
rdfs:comment "What the contract guarantees about the product it covers: refresh schedule, freshness, quality thresholds, support channel, notice period on a breaking change. Held as prose for now, which no shape can verify; the structured form, aligned on ODCS, is the next step. Recorded here because the commitment had been written into businessRule for want of anywhere else, where it sat next to genuine business rules and could not be told apart." ;
|
||||
rdfs:domain pr:DataContract ;
|
||||
rdfs:range xsd:string .
|
||||
|
||||
pr:shortLabel a owl:AnnotationProperty,
|
||||
owl:FunctionalProperty ;
|
||||
rdfs:label "short Label" ;
|
||||
@@ -450,7 +491,8 @@ pr:sourceIdentifier a owl:DatatypeProperty,
|
||||
owl:FunctionalProperty ;
|
||||
rdfs:label "source Identifier" ;
|
||||
rdfs:comment "Native immutable id in the source system (Snowflake object id, Tableau LUID, Looker id). Makes reconciliation idempotent and survives renames, which names do not." ;
|
||||
rdfs:range xsd:string .
|
||||
rdfs:range xsd:string ;
|
||||
pr:polymorphic true .
|
||||
|
||||
pr:sourcedFrom a owl:ObjectProperty ;
|
||||
rdfs:label "sourced From" ;
|
||||
@@ -459,28 +501,34 @@ pr:sourcedFrom a owl:ObjectProperty ;
|
||||
Domain deliberately omitted -- it applies to Data Elements, Data Structures, Metrics and BI Data Sources alike, and the scope lives in the shapes.
|
||||
|
||||
It also settles a naming collision. As a string, "source" meant a system here and a BI surface in BIDataSource, two readings of one word. As a relation towards System, the two are different kinds of thing and the ambiguity disappears.""" ;
|
||||
rdfs:range pr:System .
|
||||
rdfs:range pr:System ;
|
||||
pr:polymorphic true .
|
||||
|
||||
pr:status a owl:DatatypeProperty ;
|
||||
rdfs:label "status" ;
|
||||
rdfs:range xsd:string .
|
||||
rdfs:range xsd:string ;
|
||||
pr:polymorphic true .
|
||||
|
||||
pr:synonym a owl:DatatypeProperty ;
|
||||
rdfs:label "synonym" ;
|
||||
rdfs:domain pr:BusinessConcept ;
|
||||
rdfs:range xsd:string .
|
||||
|
||||
pr:technicalDefinition a owl:DatatypeProperty ;
|
||||
rdfs:label "technical Definition" ;
|
||||
rdfs:domain pr:BusinessConcept ;
|
||||
rdfs:range xsd:string .
|
||||
|
||||
pr:timeAggregation a owl:DatatypeProperty ;
|
||||
rdfs:label "time Aggregation" ;
|
||||
rdfs:domain pr:Metric ;
|
||||
rdfs:range xsd:string .
|
||||
|
||||
pr:unit a owl:DatatypeProperty ;
|
||||
rdfs:label "unit" ;
|
||||
rdfs:comment "From the Units LoV. Note the LoV currently mixes physical units, currencies (ISO 4217) and value types (Index, Rate, Count) - three different concepts that should eventually be split." ;
|
||||
rdfs:range xsd:string .
|
||||
rdfs:range xsd:string ;
|
||||
pr:polymorphic true .
|
||||
|
||||
pr:usesBIDataSource a owl:ObjectProperty ;
|
||||
rdfs:label "uses BI Data Source" ;
|
||||
@@ -495,23 +543,19 @@ pr:usesConcept a owl:ObjectProperty ;
|
||||
|
||||
pr:version a owl:DatatypeProperty ;
|
||||
rdfs:label "version" ;
|
||||
rdfs:range xsd:string .
|
||||
rdfs:range xsd:string ;
|
||||
pr:polymorphic true .
|
||||
|
||||
pr:viewDefinition a owl:DatatypeProperty ;
|
||||
rdfs:label "view Definition" ;
|
||||
rdfs:domain pr:View ;
|
||||
rdfs:range xsd:string .
|
||||
|
||||
pr:BaseTable a owl:Class ;
|
||||
rdfs:label "Base Table" ;
|
||||
rdfs:comment "A structure that physically holds its rows, as opposed to one that derives them. The common case in a warehouse Gold layer, and where impact analysis usually bottoms out." ;
|
||||
rdfs:subClassOf pr:DataStructure ;
|
||||
pr:isAbstract false .
|
||||
|
||||
pr:DataContract a owl:Class ;
|
||||
rdfs:label "Data Contract" ;
|
||||
rdfs:comment "The service commitment attached to a Data Product: schema, freshness, quality thresholds, support, breaking-change notice period. Candidate alignment: ODCS (Bitol)." ;
|
||||
rdfs:subClassOf pr:DefinedObject,
|
||||
pr:DeliveryLayerObject ;
|
||||
pr:authoringMode "HARVESTED" ;
|
||||
pr:isAbstract false .
|
||||
|
||||
pr:DataDomainOwner a owl:Class ;
|
||||
@@ -519,6 +563,7 @@ pr:DataDomainOwner a owl:Class ;
|
||||
rdfs:comment "Accountable for a Data Domain. Exactly one per domain." ;
|
||||
rdfs:subClassOf pr:Actor ;
|
||||
pr:acronym "DDO" ;
|
||||
pr:authoringMode "ASSERTED" ;
|
||||
pr:isAbstract false ;
|
||||
pr:shortLabel "Domain Owner" .
|
||||
|
||||
@@ -527,6 +572,7 @@ pr:DataGovernanceLead a owl:Class ;
|
||||
rdfs:comment "Runs governance for a Data Domain. The acronym belongs in hasAcronym, not in the label (rule NR-005)." ;
|
||||
rdfs:subClassOf pr:Actor ;
|
||||
pr:acronym "DGL" ;
|
||||
pr:authoringMode "ASSERTED" ;
|
||||
pr:isAbstract false ;
|
||||
pr:shortLabel "Governance Lead" .
|
||||
|
||||
@@ -535,6 +581,7 @@ pr:DataProductOwner a owl:Class ;
|
||||
rdfs:comment "Runs a Data Product day to day: releases, changelog, support, consumer communication. Belongs to the Sub-Domain that operates the product." ;
|
||||
rdfs:subClassOf pr:Actor ;
|
||||
pr:acronym "PO" ;
|
||||
pr:authoringMode "ASSERTED" ;
|
||||
pr:isAbstract false ;
|
||||
pr:shortLabel "Product Owner" .
|
||||
|
||||
@@ -542,6 +589,8 @@ pr:DataSteward a owl:Class ;
|
||||
rdfs:label "Data Steward" ;
|
||||
rdfs:comment "Monitors a Business Object. Declared there and nowhere else: Data Objects and Data Elements inherit their steward, so that no column can ever have two answers to 'who watches this'." ;
|
||||
rdfs:subClassOf pr:Actor ;
|
||||
pr:acronym "DST" ;
|
||||
pr:authoringMode "ASSERTED" ;
|
||||
pr:isAbstract false ;
|
||||
pr:shortLabel "Steward" .
|
||||
|
||||
@@ -550,6 +599,7 @@ pr:DataSubDomainOwner a owl:Class ;
|
||||
rdfs:comment "Accountable for a Sub-Domain, exactly one per sub-domain. Named to match Data Domain Owner: the two roles are the same responsibility at two levels of the tree, and calling one 'Data Domain Owner' and the other 'Sub-Domain Owner' suggested a difference that does not exist." ;
|
||||
rdfs:subClassOf pr:Actor ;
|
||||
pr:acronym "SDO" ;
|
||||
pr:authoringMode "ASSERTED" ;
|
||||
pr:isAbstract false ;
|
||||
pr:shortLabel "Sub Domain Owner" .
|
||||
|
||||
@@ -557,12 +607,14 @@ pr:ExternalTable a owl:Class ;
|
||||
rdfs:label "External Table" ;
|
||||
rdfs:comment "Backed by files outside the warehouse. Marks the boundary where lineage leaves Snowflake." ;
|
||||
rdfs:subClassOf pr:DataStructure ;
|
||||
pr:authoringMode "HARVESTED" ;
|
||||
pr:isAbstract false .
|
||||
|
||||
pr:GovernanceLayerObject a owl:Class ;
|
||||
rdfs:label "Governance Layer Object" ;
|
||||
rdfs:comment "Root of the governance layer. Holds the actors and governance objects that are not data objects and therefore sit outside the data layers. Created by insertion above Actor rather than by renaming it, so that every range pointing at Actor keeps stating the nature of its target rather than its position in the model." ;
|
||||
rdfs:subClassOf pr:MetaModelObject ;
|
||||
rdfs:subClassOf pr:DefinedObject,
|
||||
pr:MetaModelObject ;
|
||||
pr:isAbstract true ;
|
||||
pr:shortLabel "Governance Layer" .
|
||||
|
||||
@@ -570,12 +622,7 @@ pr:PrimaryKey a owl:Class ;
|
||||
rdfs:label "Primary Key" ;
|
||||
rdfs:comment "The column or set of columns whose values make a row unique. Once harvested it makes a declared grain checkable: a hasGrainElement that does not match the real key is an automatic finding." ;
|
||||
rdfs:subClassOf pr:KeyConstraint ;
|
||||
pr:isAbstract false .
|
||||
|
||||
pr:View a owl:Class ;
|
||||
rdfs:label "View" ;
|
||||
rdfs:comment "Depends on other relations through dependsOn, so impact is transitive." ;
|
||||
rdfs:subClassOf pr:DataStructure ;
|
||||
pr:authoringMode "HARVESTED" ;
|
||||
pr:isAbstract false .
|
||||
|
||||
pr:isInBIDataSource a owl:FunctionalProperty,
|
||||
@@ -601,13 +648,14 @@ Range left open and scoped by SHACL per class, because the two uses have differe
|
||||
THE SEAM. This is the one relation crossing from what governance defines to what a harvester captures, and the one thing a steward confirms: the reconciliation job proposes the mapping on fully qualified name and type, a person accepts it. It is also what makes end-to-end impact analysis possible.
|
||||
|
||||
Not functional: the same object exists in DEV, UAT and PROD, and a Data Element may sit in several Fields -- see primaryLocation for the authoritative one. Renamed from physicalizedIn, which was jargon.""" ;
|
||||
pr:authoringMode "PROPOSED_CONFIRMED" .
|
||||
pr:polymorphic true .
|
||||
|
||||
pr:BusinessIntelligenceReport a owl:Class ;
|
||||
rdfs:label "Business Intelligence Report" ;
|
||||
rdfs:comment "What a Data Governance Lead actually cares about in an impact analysis: not that a column changed, but which reports break and who to warn." ;
|
||||
rdfs:subClassOf pr:CapturedObject,
|
||||
pr:ConsumptionLayerObject ;
|
||||
pr:authoringMode "HARVESTED" ;
|
||||
pr:harvestSource "Tableau Workbook/Sheet ; Looker Look/Dashboard" ;
|
||||
pr:isAbstract false ;
|
||||
pr:shortLabel "BI Report" .
|
||||
@@ -617,16 +665,26 @@ pr:BusinessIntelligenceWorkspace a owl:Class ;
|
||||
rdfs:comment "The container a BI tool organises its content in: a Tableau project or site, a Looker model. Useful mainly for attribution -- it is where you look to find who publishes what." ;
|
||||
rdfs:subClassOf pr:CapturedObject,
|
||||
pr:ConsumptionLayerObject ;
|
||||
pr:authoringMode "HARVESTED" ;
|
||||
pr:harvestSource "Tableau Metadata API (Project/Site) ; Looker API (Model)" ;
|
||||
pr:isAbstract false ;
|
||||
pr:shortLabel "BI Workspace" .
|
||||
|
||||
pr:DataContract a owl:Class ;
|
||||
rdfs:label "Data Contract" ;
|
||||
rdfs:comment "The service commitment attached to a Data Product: schema, freshness, quality thresholds, support, breaking-change notice period. Candidate alignment: ODCS (Bitol)." ;
|
||||
rdfs:subClassOf pr:DefinedObject,
|
||||
pr:DeliveryLayerObject ;
|
||||
pr:authoringMode "ASSERTED" ;
|
||||
pr:isAbstract false .
|
||||
|
||||
pr:DataSubDomain a owl:Class ;
|
||||
rdfs:label "Data Sub Domain" ;
|
||||
rdfs:comment "A coherent slice of a Data Domain, grouping the business objects that belong together: Sell Out inside Sales Performance, Fiscal Calendar inside Financial Performance. It exists so that governance can be delegated and reviewed at a size a person can hold in their head." ;
|
||||
rdfs:subClassOf pr:DefinedObject,
|
||||
pr:OwnershipLayerObject ;
|
||||
pr:acronym "SD" ;
|
||||
pr:authoringMode "ASSERTED" ;
|
||||
pr:isAbstract false ;
|
||||
pr:shortLabel "Sub Domain" .
|
||||
|
||||
@@ -635,6 +693,7 @@ pr:Database a owl:Class ;
|
||||
rdfs:comment "The top container of a storage engine: a Snowflake database, a Databricks catalog, a BigQuery project. Named differently by every vendor, which is why the class carries the generic name and the vendor word lives in the harvest annotation." ;
|
||||
rdfs:subClassOf pr:CapturedObject,
|
||||
pr:PhysicalLayerObject ;
|
||||
pr:authoringMode "HARVESTED" ;
|
||||
pr:harvestSource "SNOWFLAKE.INFORMATION_SCHEMA.DATABASES" ;
|
||||
pr:isAbstract false .
|
||||
|
||||
@@ -643,16 +702,15 @@ pr:Schema a owl:Class ;
|
||||
rdfs:comment "The namespace grouping structures inside a database. Optional on purpose: Neo4j has no schema and BigQuery calls the level a dataset, so nothing in the shapes may require it." ;
|
||||
rdfs:subClassOf pr:CapturedObject,
|
||||
pr:PhysicalLayerObject ;
|
||||
pr:authoringMode "HARVESTED" ;
|
||||
pr:harvestSource "SNOWFLAKE.INFORMATION_SCHEMA.SCHEMATA" ;
|
||||
pr:isAbstract false .
|
||||
|
||||
pr:Transformation a owl:Class ;
|
||||
rdfs:label "Transformation" ;
|
||||
rdfs:comment "The code that turns inputs into outputs: a dbt model, a Snowflake task, an ADF pipeline. Subclass of prov:Activity so that lineage is expressed in a standard vocabulary rather than a private one." ;
|
||||
rdfs:subClassOf prov:Activity,
|
||||
pr:CapturedObject,
|
||||
pr:PhysicalLayerObject ;
|
||||
pr:harvestSource "dbt manifest.json, Snowflake TASKS, Azure Data Factory pipelines" ;
|
||||
pr:View a owl:Class ;
|
||||
rdfs:label "View" ;
|
||||
rdfs:comment "Depends on other relations through dependsOn, so impact is transitive." ;
|
||||
rdfs:subClassOf pr:DataStructure ;
|
||||
pr:authoringMode "HARVESTED" ;
|
||||
pr:isAbstract false .
|
||||
|
||||
pr:BusinessLayerObject a owl:Class ;
|
||||
@@ -667,12 +725,14 @@ pr:DataInterface a owl:Class ;
|
||||
rdfs:comment "The channel through which a consumer actually gets the data: a Snowflake secure share or listing, a consumption schema with its grants, a file extract to a panel partner, an API or reverse-ETL feed. Not a Data Object (that is structure) and not a BI Data Source (that is one consumer among others). Verifiable: a grant, a share or an endpoint either exists or it does not. The output port in data-mesh terms." ;
|
||||
rdfs:subClassOf pr:DefinedObject,
|
||||
pr:DeliveryLayerObject ;
|
||||
pr:authoringMode "ASSERTED" ;
|
||||
pr:isAbstract false .
|
||||
|
||||
pr:ForeignKey a owl:Class ;
|
||||
rdfs:label "Foreign Key" ;
|
||||
rdfs:comment "A column, or set of columns, whose values must exist in another structure. Rule OW-006 keeps it out of the Data Elements -- it carries no business notion of its own, it is joining plumbing -- but it still needs somewhere to live, and here it makes the asserted qualifiedBy between Data Objects checkable against what the warehouse really enforces." ;
|
||||
rdfs:subClassOf pr:KeyConstraint ;
|
||||
pr:authoringMode "HARVESTED" ;
|
||||
pr:isAbstract false .
|
||||
|
||||
pr:KeyConstraint a owl:Class ;
|
||||
@@ -698,49 +758,36 @@ pr:System a owl:Class ;
|
||||
pr:authoringMode "ASSERTED" ;
|
||||
pr:isAbstract false .
|
||||
|
||||
pr:BusinessConcept a owl:Class ;
|
||||
rdfs:label "Business Concept" ;
|
||||
rdfs:comment "A shared business notion WITHOUT a formula. The presence of a formula is the sole discriminator against Metric (rule BR-003)." ;
|
||||
rdfs:subClassOf pr:BusinessLayerObject,
|
||||
pr:DefinedObject ;
|
||||
pr:isAbstract false ;
|
||||
pr:shortLabel "Concept" .
|
||||
pr:Transformation a owl:Class ;
|
||||
rdfs:label "Transformation" ;
|
||||
rdfs:comment "The code that turns inputs into outputs: a dbt model, a Snowflake task, an ADF pipeline. Subclass of prov:Activity so that lineage is expressed in a standard vocabulary rather than a private one." ;
|
||||
rdfs:subClassOf prov:Activity,
|
||||
pr:CapturedObject,
|
||||
pr:PhysicalLayerObject ;
|
||||
pr:authoringMode "HARVESTED" ;
|
||||
pr:harvestSource "dbt manifest.json, Snowflake TASKS, Azure Data Factory pipelines" ;
|
||||
pr:isAbstract false .
|
||||
|
||||
pr:BusinessIntelligenceDataSource a owl:Class ;
|
||||
rdfs:label "Business Intelligence Data Source" ;
|
||||
rdfs:comment "The semantic surface a report is built on. This is where BI meets the warehouse." ;
|
||||
rdfs:subClassOf pr:CapturedObject,
|
||||
pr:ConsumptionLayerObject ;
|
||||
pr:authoringMode "HARVESTED" ;
|
||||
pr:harvestSource "Tableau Published Datasource ; Looker Explore" ;
|
||||
pr:isAbstract false ;
|
||||
pr:shortLabel "BI Data Source" .
|
||||
|
||||
pr:BusinessObject a owl:Class ;
|
||||
rdfs:label "Business Object" ;
|
||||
rdfs:comment "The single anchor of accountability, which is why it stays in the Ownership layer: it is the one object where a steward is declared, and Data Objects and Data Elements inherit from it. It carries NO business definition of its own -- its meaning comes from its aboutConcept. What it does carry is a perimeter: the subject it is about, and the notions needed to read it." ;
|
||||
rdfs:subClassOf pr:DefinedObject,
|
||||
pr:OwnershipLayerObject ;
|
||||
pr:acronym "BO" ;
|
||||
pr:isAbstract false .
|
||||
|
||||
pr:DataDomain a owl:Class ;
|
||||
rdfs:label "Data Domain" ;
|
||||
rdfs:comment "A durable area of the business that owns the meaning of its data: Sales Performance, Product & Material, Financial Performance. It is the unit of accountability -- one owner, one governance lead -- and the top of the categorisation tree. Domains are stable; the projects and systems inside them are not." ;
|
||||
rdfs:subClassOf pr:DefinedObject,
|
||||
pr:OwnershipLayerObject ;
|
||||
pr:acronym "DD" ;
|
||||
pr:authoringMode "ASSERTED" ;
|
||||
pr:isAbstract false ;
|
||||
pr:shortLabel "Domain" .
|
||||
|
||||
pr:DataElement a owl:Class ;
|
||||
rdfs:label "Data Element" ;
|
||||
rdfs:comment "The finest defined unit. Its mapping to a physical Field is the ONLY place where the defined graph and the captured graph meet: proposed automatically by name and type matching, confirmed by a Data Steward." ;
|
||||
rdfs:subClassOf pr:DefinedObject,
|
||||
pr:LogicalLayerObject ;
|
||||
pr:authoringMode "PROPOSED_CONFIRMED" ;
|
||||
pr:isAbstract false ;
|
||||
pr:shortLabel "Element" .
|
||||
|
||||
pr:DeliveryLayerObject a owl:Class ;
|
||||
rdfs:label "Delivery Layer Object" ;
|
||||
rdfs:comment "What we promise, to whom, until when. A different question from how the data is structured, hence a layer of its own: version, owner, changelog, support channel, consumers to warn." ;
|
||||
@@ -755,11 +802,30 @@ pr:OwnershipLayerObject a owl:Class ;
|
||||
pr:isAbstract true ;
|
||||
pr:shortLabel "Ownership Layer" .
|
||||
|
||||
pr:BusinessObject a owl:Class ;
|
||||
rdfs:label "Business Object" ;
|
||||
rdfs:comment "The single anchor of accountability, which is why it stays in the Ownership layer: it is the one object where a steward is declared, and Data Objects and Data Elements inherit from it. It carries NO business definition of its own -- its meaning comes from its aboutConcept. What it does carry is a perimeter: the subject it is about, and the notions needed to read it." ;
|
||||
rdfs:subClassOf pr:DefinedObject,
|
||||
pr:OwnershipLayerObject ;
|
||||
pr:acronym "BO" ;
|
||||
pr:authoringMode "ASSERTED" ;
|
||||
pr:isAbstract false .
|
||||
|
||||
pr:DataElement a owl:Class ;
|
||||
rdfs:label "Data Element" ;
|
||||
rdfs:comment "The finest defined unit. Its mapping to a physical Field is the ONLY place where the defined graph and the captured graph meet: proposed automatically by name and type matching, confirmed by a Data Steward." ;
|
||||
rdfs:subClassOf pr:DefinedObject,
|
||||
pr:LogicalLayerObject ;
|
||||
pr:authoringMode "ASSERTED" ;
|
||||
pr:isAbstract false ;
|
||||
pr:shortLabel "Element" .
|
||||
|
||||
pr:BusinessIntelligenceField a owl:Class ;
|
||||
rdfs:label "Business Intelligence Field" ;
|
||||
rdfs:comment "A field as a business user sees it. exposesMetric is what turns a certified Metric from a definition on paper into something measurable against the real BI estate." ;
|
||||
rdfs:subClassOf pr:CapturedObject,
|
||||
pr:ConsumptionLayerObject ;
|
||||
pr:authoringMode "HARVESTED" ;
|
||||
pr:harvestSource "Tableau calculated fields ; LookML measures and dimensions" ;
|
||||
pr:isAbstract false ;
|
||||
pr:shortLabel "BI Field" .
|
||||
@@ -769,6 +835,7 @@ pr:DataObject a owl:Class ;
|
||||
rdfs:comment "The pivot of the whole model: it represents exactly one Business Object, groups the Data Elements that make it up, and is stored in one or more Data Structures. The single junction between what governance defines and what actually runs -- everything upstream is meaning, everything downstream is machinery." ;
|
||||
rdfs:subClassOf pr:DefinedObject,
|
||||
pr:LogicalLayerObject ;
|
||||
pr:authoringMode "ASSERTED" ;
|
||||
pr:isAbstract false .
|
||||
|
||||
pr:DataProduct a owl:Class ;
|
||||
@@ -776,13 +843,7 @@ pr:DataProduct a owl:Class ;
|
||||
rdfs:comment "The unit of delivery: what carries a version number, an owner, a changelog, a support channel and a list of consumers to warn. It has no single technical counterpart, and should not: physically it often lands on a Snowflake schema or a dbt project, but that is not what defines it. Operated by exactly one Sub-Domain -- it is a consumable, and there must be no ambiguity about who runs it. Candidate alignment: dcat:Dataset / DPROD." ;
|
||||
rdfs:subClassOf pr:DefinedObject,
|
||||
pr:DeliveryLayerObject ;
|
||||
pr:isAbstract false .
|
||||
|
||||
pr:Metric a owl:Class ;
|
||||
rdfs:label "Metric" ;
|
||||
rdfs:comment "A quantifiable measurement WITH a formula, a unit and a grain. Under BR-013 a Metric carries the harmonised CALCULATION RULE; variants that differ only by analysis context are Data Elements linked back via computedBy." ;
|
||||
rdfs:subClassOf pr:BusinessLayerObject,
|
||||
pr:DefinedObject ;
|
||||
pr:authoringMode "ASSERTED" ;
|
||||
pr:isAbstract false .
|
||||
|
||||
pr:SystemType a owl:Class ;
|
||||
@@ -790,12 +851,6 @@ pr:SystemType a owl:Class ;
|
||||
rdfs:comment "What kind of system this is -- source application, master data system, data platform, BI tool, external provider. Coarse on purpose: it exists to group systems in a view, not to model them." ;
|
||||
pr:isAbstract false .
|
||||
|
||||
pr:Actor a owl:Class ;
|
||||
rdfs:label "Actor" ;
|
||||
rdfs:comment "A person or a team. Deliberately NOT a MetaModelObject: people are not subject to ownership and lifecycle rules." ;
|
||||
rdfs:subClassOf pr:GovernanceLayerObject ;
|
||||
pr:isAbstract true .
|
||||
|
||||
pr:ConsumptionLayerObject a owl:Class ;
|
||||
rdfs:label "Consumption Layer Object" ;
|
||||
rdfs:comment "The BI estate. Separate from Physical because BI assets have their own lifecycle and their own owner: a dashboard belongs to its author, not to the Data Domain that owns the underlying data." ;
|
||||
@@ -803,6 +858,29 @@ pr:ConsumptionLayerObject a owl:Class ;
|
||||
pr:isAbstract true ;
|
||||
pr:shortLabel "Consumption Layer" .
|
||||
|
||||
pr:Actor a owl:Class ;
|
||||
rdfs:label "Actor" ;
|
||||
rdfs:comment "A person or a team. Deliberately NOT a MetaModelObject: people are not subject to ownership and lifecycle rules." ;
|
||||
rdfs:subClassOf pr:GovernanceLayerObject ;
|
||||
pr:isAbstract true .
|
||||
|
||||
pr:BusinessConcept a owl:Class ;
|
||||
rdfs:label "Business Concept" ;
|
||||
rdfs:comment "A shared business notion WITHOUT a formula. The presence of a formula is the sole discriminator against Metric (rule BR-003)." ;
|
||||
rdfs:subClassOf pr:BusinessLayerObject,
|
||||
pr:DefinedObject ;
|
||||
pr:authoringMode "ASSERTED" ;
|
||||
pr:isAbstract false ;
|
||||
pr:shortLabel "Concept" .
|
||||
|
||||
pr:Metric a owl:Class ;
|
||||
rdfs:label "Metric" ;
|
||||
rdfs:comment "A quantifiable measurement WITH a formula, a unit and a grain. Under BR-013 a Metric carries the harmonised CALCULATION RULE; variants that differ only by analysis context are Data Elements linked back via computedBy." ;
|
||||
rdfs:subClassOf pr:BusinessLayerObject,
|
||||
pr:DefinedObject ;
|
||||
pr:authoringMode "ASSERTED" ;
|
||||
pr:isAbstract false .
|
||||
|
||||
pr:PhysicalLayerObject a owl:Class ;
|
||||
rdfs:label "Physical Layer Object" ;
|
||||
rdfs:comment """What actually runs: the systems, containers, structures, columns, keys and code that hold the data.
|
||||
@@ -816,19 +894,26 @@ Until v1.4 this class was itself declared a kind of Captured Object, which made
|
||||
pr:isAbstract true ;
|
||||
pr:shortLabel "Physical Layer" .
|
||||
|
||||
pr:MetaModelObject a owl:Class ;
|
||||
rdfs:label "Meta Model Object" ;
|
||||
rdfs:comment "Anything the meta model describes. Actors are deliberately NOT Meta Model Objects." ;
|
||||
pr:isAbstract true .
|
||||
|
||||
pr:CapturedObject a owl:Class ;
|
||||
rdfs:label "Captured Object" ;
|
||||
rdfs:comment "Read from a running system and rebuilt on every run. Never hand-edited. Carries sourceIdentifier, fullyQualifiedName and harvestedOn instead of declared ownership: attribution is INFERRED through the Data Element it is mapped to, never asserted on the node." ;
|
||||
rdfs:subClassOf pr:MetaModelObject ;
|
||||
pr:isAbstract true .
|
||||
|
||||
pr:Field a owl:Class ;
|
||||
rdfs:label "Field" ;
|
||||
rdfs:comment "A physical column. The anchor of impact analysis: everything upstream reaches a Field, everything downstream starts from one." ;
|
||||
rdfs:subClassOf pr:CapturedObject,
|
||||
pr:PhysicalLayerObject ;
|
||||
pr:authoringMode "HARVESTED" ;
|
||||
pr:harvestSource "SNOWFLAKE.INFORMATION_SCHEMA.COLUMNS" ;
|
||||
pr:isAbstract false .
|
||||
|
||||
pr:MetaModelObject a owl:Class ;
|
||||
rdfs:label "Meta Model Object" ;
|
||||
rdfs:comment "Anything the meta model describes. Actors are deliberately NOT Meta Model Objects." ;
|
||||
pr:isAbstract true .
|
||||
|
||||
pr:DataStructure a owl:Class ;
|
||||
rdfs:label "Data Structure" ;
|
||||
rdfs:comment """Anything that carries Fields and reads as a set of rows. Never instantiated directly: a harvest types the concrete kind, and a viewer shows that kind rather than this parent.
|
||||
@@ -850,23 +935,21 @@ Existing BaseTable assertions stay DataStructure by entailment, every shape targ
|
||||
pr:harvestSource "SNOWFLAKE.INFORMATION_SCHEMA.TABLES" ;
|
||||
pr:isAbstract true .
|
||||
|
||||
pr:CapturedObject a owl:Class ;
|
||||
rdfs:label "Captured Object" ;
|
||||
rdfs:comment "Read from a running system and rebuilt on every run. Never hand-edited. Carries sourceIdentifier, fullyQualifiedName and harvestedOn instead of declared ownership: attribution is INFERRED through the Data Element it is mapped to, never asserted on the node." ;
|
||||
rdfs:subClassOf pr:MetaModelObject ;
|
||||
pr:authoringMode "HARVESTED" ;
|
||||
pr:isAbstract true .
|
||||
|
||||
pr:DefinedObject a owl:Class ;
|
||||
rdfs:label "Defined Object" ;
|
||||
rdfs:comment "Somebody decided it. Written by governance, edited through a pull request on the domain TTL file, and subject to the full identity and lifecycle shape: identifier, name, owner, owning Data Domain, status, version." ;
|
||||
rdfs:subClassOf pr:MetaModelObject ;
|
||||
pr:authoringMode "ASSERTED" ;
|
||||
pr:isAbstract true .
|
||||
|
||||
[] a owl:AllDisjointClasses ;
|
||||
owl:members ( pr:DefinedObject pr:CapturedObject ) .
|
||||
|
||||
[] a owl:AllDisjointClasses ;
|
||||
owl:members ( pr:BusinessIntelligenceWorkspace pr:BusinessIntelligenceDataSource pr:BusinessIntelligenceField pr:BusinessIntelligenceReport ) .
|
||||
|
||||
[] a owl:AllDisjointClasses ;
|
||||
owl:members ( pr:OwnershipLayerObject pr:BusinessLayerObject pr:LogicalLayerObject pr:DeliveryLayerObject pr:PhysicalLayerObject pr:ConsumptionLayerObject ) .
|
||||
|
||||
[] a owl:AllDisjointClasses ;
|
||||
owl:members ( pr:BusinessObject pr:DataObject pr:DataInterface pr:DataProduct ) .
|
||||
|
||||
@@ -879,9 +962,3 @@ pr:DefinedObject a owl:Class ;
|
||||
[] a owl:AllDisjointClasses ;
|
||||
owl:members ( pr:PrimaryKey pr:ForeignKey ) .
|
||||
|
||||
[] a owl:AllDisjointClasses ;
|
||||
owl:members ( pr:BusinessIntelligenceWorkspace pr:BusinessIntelligenceDataSource pr:BusinessIntelligenceField pr:BusinessIntelligenceReport ) .
|
||||
|
||||
[] a owl:AllDisjointClasses ;
|
||||
owl:members ( pr:OwnershipLayerObject pr:BusinessLayerObject pr:LogicalLayerObject pr:DeliveryLayerObject pr:PhysicalLayerObject pr:ConsumptionLayerObject ) .
|
||||
|
||||
|
||||
Reference in New Issue
Block a user