Magnowlia

Acme Shop Sample Ontology

A complete example ontology for the Acme Shop e-commerce platform, demonstrating all features of the Magnowlia ontology framework.

Download Turtle (.ttl) Mapping Vocabulary Business Vocabulary
Prefixes
owl:<http://www.w3.org/2002/07/owl#>
rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>
rdfs:<http://www.w3.org/2000/01/rdf-schema#>
xsd:<http://www.w3.org/2001/XMLSchema#>
skos:<http://www.w3.org/2004/02/skos/core#>
dct:<http://purl.org/dc/terms/>
b:<https://acmeshop.example.com/ontology/business#>
bv:<https://magnowlia.com/ontology/business-vocabulary#>
m:<https://magnowlia.com/ontology/mapping#>
t:<https://acmeshop.example.com/ontology/tech#>
ONTOLOGY HEADER · TECHNICAL LAYER - TABLES · TECHNICAL LAYER - COLUMNS · BUSINESS LAYER - CLASSES · BUSINESS LAYER - RELATIONSHIPS · BUSINESS LAYER - PROPERTIES (Dimensions) · BUSINESS LAYER - CONSTANTS · ACCESS CONTROL · BUSINESS LAYER - METRICS (with structured properties) · CORRELATIONS — How metrics relate to each other

ONTOLOGY HEADER (0)

TECHNICAL LAYER - TABLES (8)

t:order_summary_view m:Table
Order Summary View
Denormalized view joining orders, customers, and products. Primary fact table for order analytics.
t:customers m:Table
Customers
Customer master data including segmentation and demographics.
t:products m:Table
Products
Product catalog with categories and pricing.
t:service_items m:Table
Service Items
Service offerings such as warranties, installations, and subscriptions.
t:customer_loyalty m:Table
Customer Loyalty
Loyalty-program data for customers — tier and points balance. One row per enrolled customer.
t:shipments m:Table
Shipments
One row per shipment, linking an order to the carrier that delivered it.
t:carriers m:Table
Carriers
Shipping carrier master data.
t:customer_product_favorites m:Table
Customer Product Favorites
Junction table linking customers to the products they have favorited (many-to-many).

TECHNICAL LAYER - COLUMNS (38)

t:order_summary_view.order_id m:Column
Order ID
Unique order identifier (PK).
t:order_summary_view.order_date m:Column
Order Date
Date the order was placed. Used as the primary time dimension for order metrics.
t:order_summary_view.order_total m:Column
Order Total
Total order amount. Currency is indicated by the currency column; may be EUR or GBP.
t:order_summary_view.order_status m:Column
Order Status
Current order fulfillment status: pending, confirmed, shipped, delivered, returned, cancelled.
t:order_summary_view.customer_country m:Column
Customer Country
ISO country code of the ordering customer. Denormalized from customer master.
t:order_summary_view.product_category m:Column
Product Category
Category of the ordered product. Denormalized from product catalog.
t:order_summary_view.payment_method m:Column
Payment Method
Payment method used for the order: credit_card, paypal, bank_transfer, apple_pay.
t:order_summary_view.currency m:Column
Currency
ISO currency code for the order amount (EUR, GBP).
t:order_summary_view.customer_type m:Column
Customer Type
Customer classification: regular, internal (staff), wholesale.
t:order_summary_view.is_test_order m:Column
Is Test Order
Boolean flag indicating whether this is a test order that should be excluded from reporting.
t:order_summary_view.customer_id m:Column
Customer ID
FK to customers table. Denormalized into the view for join-free access.
t:order_summary_view.quantity m:Column
Quantity
Number of items in the order line.
t:order_summary_view.product_id m:Column
Product ID
FK to products table. Identifies the product in the order.
t:customers.customer_id m:Column
Customer ID
Customer unique identifier (PK).
t:customers.customer_segment m:Column
Customer Segment
Customer segment classification: Premium, Standard, New, Churned.
t:customers.customer_name m:Column
Customer Name
Full name of the customer.
t:customers.customer_email m:Column
Customer Email
Primary email address of the customer.
t:customers.customer_country m:Column
Customer Country
ISO country code of the customer. Master data source for the denormalized order_summary_view.customer_country.
t:customers.customer_type m:Column
Customer Type
Customer classification: regular, internal (staff), wholesale. Master data source for the denormalized order_summary_view.customer_type.
t:customers.created_at m:Column
Created At
Timestamp when the customer record was created (registration date).
t:customer_loyalty.customer_id m:Column
Loyalty Customer ID
Reference to the customer this loyalty record belongs to.
t:customer_loyalty.tier m:Column
Loyalty Tier
Loyalty program tier: bronze, silver, gold, platinum.
t:customer_loyalty.points_balance m:Column
Loyalty Points Balance
Current loyalty point balance for the customer.
t:products.product_id m:Column
Product ID
Product unique identifier (PK).
t:products.product_name m:Column
Product Name
Display name of the product.
t:products.product_category m:Column
Product Category
Category the product belongs to: Electronics, Clothing, Home & Garden, Sports, Books.
t:products.product_price m:Column
Product Price
Current list price of the product in EUR.
t:service_items.service_id m:Column
Service ID
Unique service item identifier (PK).
t:service_items.service_name m:Column
Service Name
Display name of the service item.
t:service_items.service_category m:Column
Service Category
Category the service belongs to: Warranty, Installation, Subscription, Support.
t:service_items.service_price m:Column
Service Price
Current price of the service item in EUR.
t:order_summary_view.service_id m:Column
Service ID
FK to service_items table. Identifies the service in the order. Null when the order line is for a product.
t:shipments.order_id m:Column
Order ID
Order this shipment fulfills (FK to order_summary_view.order_id).
t:shipments.carrier_code m:Column
Carrier Code
Carrier that handled this shipment (FK to carriers.carrier_code).
t:carriers.carrier_code m:Column
Carrier Code
Unique carrier identifier (PK).
t:carriers.carrier_name m:Column
Carrier Name
Human-readable carrier name.
t:customer_product_favorites.customer_id m:Column
Customer ID
Favoriting customer (FK to customers.customer_id).
t:customer_product_favorites.product_id m:Column
Product ID
Favorited product (FK to products.product_id).

BUSINESS LAYER - CLASSES (15)

b:Order owl:Class
Order
A customer order placed on the Acme Shop platform. Backed by the order_summary_view which is a denormalized view joining orders, customers, and products.
b:Customer owl:Class
Customer
A registered customer of Acme Shop.
b:LoyaltyMember owl:Class m:BusinessView
Loyalty Member
An enrolled loyalty-program customer, with tier and points alongside the customer's name and contact details.
b:loyaltyMemberTier owl:DatatypeProperty
Loyalty Tier
Loyalty program tier — bronze, silver, gold, platinum.
b:loyaltyMemberPoints owl:DatatypeProperty
Loyalty Points Balance
Current point balance for the member.
b:loyaltyMemberName owl:DatatypeProperty
Loyalty Member Name
Full name of the loyalty member.
b:Purchasable owl:Class
Purchasable
Abstract superclass for anything that can appear as a line item in an order. Subclassed by Product (physical goods) and ServiceItem (services, warranties, subscriptions). This class has no direct table mapping — use the concrete subclasses Product (t:products) or ServiceItem (t:service_items) for queries.
b:Product owl:Class
Product
A physical product available in the Acme Shop catalog.
b:ServiceItem owl:Class
Service Item
A service offering such as a warranty, installation, or subscription that can be purchased alongside or independently of a product.
b:WholesaleCustomer owl:Class m:BusinessView
Wholesale Customer
Customer purchasing in bulk at wholesale prices. Identified by customer_type = 'wholesale' in the order view.
b:InternalCustomer owl:Class m:BusinessView
Internal Customer
Internal staff purchases. Typically excluded from revenue reporting. Identified by customer_type = 'internal'.
b:PremiumWholesaleCustomer owl:Class m:BusinessView
Premium Wholesale Customer
High-value wholesale customers with premium pricing agreements. Identified by customer_type = 'wholesale' AND customer_segment = 'Premium'.
b:ReturnedOrder owl:Class m:BusinessView
Returned Order
Orders that were returned or refunded by the customer.
b:CancelledOrder owl:Class m:BusinessView
Cancelled Order
Orders that were cancelled before fulfillment. NOTE: Mutually exclusive with ReturnedOrder - an order is either cancelled or returned, not both.
b:Carrier owl:Class
Carrier
A shipping carrier that delivers orders.

BUSINESS LAYER - RELATIONSHIPS (11)

b:customerHasOrder owl:ObjectProperty
customer has order
Links a customer to all orders they have placed. Joined via customer_id.
b:orderForCustomer owl:ObjectProperty
order for customer
Links an order back to the customer who placed it. Inverse of customerHasOrder.
b:orderHasProduct owl:ObjectProperty
order has product
Links an order to the physical product purchased. Joined via product_id.
b:productInOrder owl:ObjectProperty
product in order
Links a product to all orders in which it appears. Inverse of orderHasProduct.
b:orderHasPurchasable owl:ObjectProperty
order has purchasable
Links an order to any purchasable item (product or service). This is the polymorphic relationship — use orderHasProduct or orderHasServiceItem for type-specific access. Realized via product_id or service_id depending on the subtype.
b:orderHasServiceItem owl:ObjectProperty
order has service item
Links an order to the service item purchased. Joined via service_id.
b:serviceItemInOrder owl:ObjectProperty
service item in order
Links a service item to all orders in which it appears. Inverse of orderHasServiceItem.
b:orderShippedByCarrier owl:ObjectProperty
shipped by carrier
Links an order to the carrier that shipped it, via the shipments bridge table.
b:carrierShippedOrder owl:ObjectProperty
shipped order
Links a carrier to the orders it shipped, via the shipments bridge table.
b:customerFavoritedProduct owl:ObjectProperty
favorited product
A product the customer has favorited, via the favorites junction.
b:productFavoritedByCustomer owl:ObjectProperty
favorited by customer
A customer who has favorited the product, via the favorites junction.

BUSINESS LAYER - PROPERTIES (Dimensions) (27)

b:orderId owl:DatatypeProperty
Order ID
Unique order identifier.
b:orderDate owl:DatatypeProperty
Order Date
Date when the order was placed. Primary time dimension for all order-related metrics.
b:orderTotal owl:DatatypeProperty
Order Total
Total monetary value of the order. Currency varies (see orderCurrency).
b:orderStatus owl:DatatypeProperty
Order Status
Current fulfillment status of the order.
b:customerCountry owl:DatatypeProperty
Customer Country
ISO country code of the ordering customer. Only available for customers who have placed orders. See b:customerCountryMaster for the master data version.
b:productCategory owl:DatatypeProperty
Product Category
Category of the ordered product. Only available for products that appear in orders. See b:productCategoryMaster for the master data version.
b:paymentMethod owl:DatatypeProperty
Payment Method
Method of payment used for the order.
b:orderCurrency owl:DatatypeProperty
Order Currency
ISO currency code for the order amount.
b:customerType owl:DatatypeProperty
Customer Type
Classification of the customer. Determines eligibility for reporting (internal/test orders are typically excluded). See b:customerTypeMaster for the master data version.
b:customerId owl:DatatypeProperty
Customer ID
Customer identifier. FK to customers table, available directly in order_summary_view.
b:orderQuantity owl:DatatypeProperty
Order Quantity
Number of items in the order.
b:isTestOrder owl:DatatypeProperty
Is Test Order
Boolean flag indicating whether this is a test order. Test orders are excluded from revenue and performance metrics.
b:productId owl:DatatypeProperty
Product ID
Product identifier. FK to products table, available directly in order_summary_view.
b:productName owl:DatatypeProperty
Product Name
Display name of the product.
b:productCategoryMaster owl:DatatypeProperty
Product Category (Master)
Category from the product catalog master table. See also b:productCategory on b:Order for the denormalized version available in order analytics.
b:productPrice owl:DatatypeProperty
Product Price
Current list price of the product in EUR.
b:serviceId owl:DatatypeProperty
Service ID
Unique service item identifier.
b:serviceName owl:DatatypeProperty
Service Name
Display name of the service item.
b:serviceCategory owl:DatatypeProperty
Service Category
Category of the service item.
b:servicePrice owl:DatatypeProperty
Service Price
Current price of the service item in EUR.
b:customerSegment owl:DatatypeProperty
Customer Segment
Customer segment classification from the customer master table.
b:customerName owl:DatatypeProperty
Customer Name
Full name of the customer.
b:customerEmail owl:DatatypeProperty
Customer Email
Primary email address of the customer. Contains PII — access is restricted.
b:customerCountryMaster owl:DatatypeProperty
Customer Country (Master)
ISO country code from the customer master table. See also b:customerCountry on b:Order for the denormalized version available in order analytics.
b:customerTypeMaster owl:DatatypeProperty
Customer Type (Master)
Customer classification from the master table. See also b:customerType on b:Order for the denormalized version available in order analytics.
b:customerCreatedAt owl:DatatypeProperty
Customer Registration Date
Timestamp when the customer registered.
b:carrierName owl:DatatypeProperty
Carrier Name
The carrier's display name.

BUSINESS LAYER - CONSTANTS (1)

b:gbpToEurExchangeRate bv:BusinessConstant
GBP to EUR Exchange Rate
Fixed exchange rate for converting GBP to EUR. Rate: 1 GBP = 0.85 EUR. To convert GBP amounts to EUR, divide by 0.85. This value is inlined in metric expressions.

ACCESS CONTROL (2)

b:revenueAccessPolicy bv:AccessPolicy
Revenue access policy
Only admins and the finance group may query revenue-bearing metrics.
b:customerCountryRowFilter bv:RowFilter
Customer country row filter
Per-user region restriction on Order rows. Non-admin callers only see orders whose customer_country is in their {{user.region}} attribute.

BUSINESS LAYER - METRICS (with structured properties) (8)

b:totalRevenueMetric bv:Metric
Total Revenue
Total order revenue with automatic GBP to EUR conversion. Includes ALL order types and statuses. For order count see b:orderCountMetric; for average value see b:averageOrderValueMetric.
b:orderCountMetric bv:Metric
Order Count
Total number of orders placed. Counts all orders regardless of status. For revenue see b:totalRevenueMetric.
b:averageOrderValueMetric bv:Metric
Average Order Value
Average revenue per order. Equivalent to total_revenue / order_count.
b:returnRateMetric bv:Metric
Return Rate
Percentage of orders that were returned or refunded, excluding test orders and internal staff purchases. Formula: returned_orders / total_orders * 100. A value of 5% means one in twenty orders was returned.
b:uniqueCustomersMetric bv:Metric
Unique Customers
Number of distinct customers who placed orders in the period. NOTE: This is an ACTIVITY-BASED count - only customers with at least one order are counted. This is NOT a master data count of all registered customers.
b:totalItemsSoldMetric bv:Metric
Total Items Sold
Total number of items sold across all orders.
b:revenuePerCustomerSegmentMetric bv:Metric
Revenue Per Customer Segment
Average revenue per customer, broken down by customer segment. Requires joining orders with customer master data. For total revenue without segmentation, see b:totalRevenueMetric.
b:newCustomerRegistrationsMetric bv:Metric
New Customer Registrations
Number of new customer registrations per period. Excludes internal (staff) customers. For activity-based customer counts (customers who placed orders), see b:uniqueCustomersMetric.

CORRELATIONS — How metrics relate to each other (2)

b:newRegistrations_correlates_returnRate bv:MetricCorrelation
New Registrations ↔ Return Rate
New customers return items at higher rates than repeat buyers — unfamiliar with sizing and product quality. The effect flattens at high registration volumes.
b:returnRate_drives_averageOrderValue bv:MetricCorrelation
Return Rate → AOV
Higher return rates tend to reduce effective AOV as returned items deflate averages.
Full Turtle Source
1@prefix owl: <http://www.w3.org/2002/07/owl#> .
2@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
3@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
4@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
5@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
6@prefix dct: <http://purl.org/dc/terms/> .
7@prefix b: <https://acmeshop.example.com/ontology/business#> .
8@prefix bv: <https://magnowlia.com/ontology/business-vocabulary#> .
9@prefix m: <https://magnowlia.com/ontology/mapping#> .
10@prefix t: <https://acmeshop.example.com/ontology/tech#> .
11
12# ===========================================================================
13# ONTOLOGY HEADER
14# ===========================================================================
15
16"ttl-uri"><https://acmeshop.example.com/ontology> a owl:Ontology ;
17 dct:title "Acme Shop Optimized Business Ontology" ;
18 dct:description "Business-facing ontology for Acme Shop e-commerce platform, optimized for clarity and mapped to the analytics data warehouse." ;
19 dct:created "2026-03-03"^^xsd:date ;
20 dct:modified "2026-03-03"^^xsd:date ;
21 dct:contributor "Magnowlia Platform Team" ;
22 owl:versionInfo "0.2.0"^^xsd:string ;
23 rdfs:comment "Design decisions: (1) order_summary_view is the primary fact table - a denormalized view joining orders, customers and products. Properties like customerCountry and productCategory have domain b:Order because they are only available through this view. (2) Constants are inlined in metric expressions; bv:BusinessConstant declarations serve as documentation. (3) Metrics use structured properties (metricExpression/sourceEntity) for single-table queries and metricSql for multi-table joins." .
24
25# ===========================================================================
26# TECHNICAL LAYER - TABLES
27# ===========================================================================
28
29t:order_summary_view a m:Table ;
30 rdfs:label "Order Summary View" ;
31 rdfs:comment "Denormalized view joining orders, customers, and products. Primary fact table for order analytics." .
32
33t:customers a m:Table ;
34 rdfs:label "Customers" ;
35 rdfs:comment "Customer master data including segmentation and demographics." .
36
37t:products a m:Table ;
38 rdfs:label "Products" ;
39 rdfs:comment "Product catalog with categories and pricing." .
40
41t:service_items a m:Table ;
42 rdfs:label "Service Items" ;
43 rdfs:comment "Service offerings such as warranties, installations, and subscriptions." .
44
45t:customer_loyalty a m:Table ;
46 rdfs:label "Customer Loyalty" ;
47 rdfs:comment "Loyalty-program data for customers — tier and points balance. One row per enrolled customer." .
48
49# --- Tables backing the bridge-join + junction relationship examples ---
50t:shipments a m:Table ;
51 rdfs:label "Shipments" ;
52 rdfs:comment "One row per shipment, linking an order to the carrier that delivered it." .
53
54t:carriers a m:Table ;
55 rdfs:label "Carriers" ;
56 rdfs:comment "Shipping carrier master data." .
57
58t:customer_product_favorites a m:Table ;
59 rdfs:label "Customer Product Favorites" ;
60 rdfs:comment "Junction table linking customers to the products they have favorited (many-to-many)." .
61
62# ===========================================================================
63# TECHNICAL LAYER - COLUMNS
64# ===========================================================================
65
66t:order_summary_view.order_id a m:Column ;
67 rdfs:label "Order ID" ;
68 rdfs:comment "Unique order identifier (PK)." ;
69 m:belongsToTable t:order_summary_view .
70
71t:order_summary_view.order_date a m:Column ;
72 rdfs:label "Order Date" ;
73 rdfs:comment "Date the order was placed. Used as the primary time dimension for order metrics." ;
74 m:belongsToTable t:order_summary_view .
75
76t:order_summary_view.order_total a m:Column ;
77 rdfs:label "Order Total" ;
78 rdfs:comment "Total order amount. Currency is indicated by the currency column; may be EUR or GBP." ;
79 m:belongsToTable t:order_summary_view .
80
81t:order_summary_view.order_status a m:Column ;
82 rdfs:label "Order Status" ;
83 rdfs:comment "Current order fulfillment status: pending, confirmed, shipped, delivered, returned, cancelled." ;
84 m:belongsToTable t:order_summary_view .
85
86t:order_summary_view.customer_country a m:Column ;
87 rdfs:label "Customer Country" ;
88 rdfs:comment "ISO country code of the ordering customer. Denormalized from customer master." ;
89 m:belongsToTable t:order_summary_view .
90
91t:order_summary_view.product_category a m:Column ;
92 rdfs:label "Product Category" ;
93 rdfs:comment "Category of the ordered product. Denormalized from product catalog." ;
94 m:belongsToTable t:order_summary_view .
95
96t:order_summary_view.payment_method a m:Column ;
97 rdfs:label "Payment Method" ;
98 rdfs:comment "Payment method used for the order: credit_card, paypal, bank_transfer, apple_pay." ;
99 m:belongsToTable t:order_summary_view .
100
101t:order_summary_view.currency a m:Column ;
102 rdfs:label "Currency" ;
103 rdfs:comment "ISO currency code for the order amount (EUR, GBP)." ;
104 m:belongsToTable t:order_summary_view .
105
106t:order_summary_view.customer_type a m:Column ;
107 rdfs:label "Customer Type" ;
108 rdfs:comment "Customer classification: regular, internal (staff), wholesale." ;
109 m:belongsToTable t:order_summary_view .
110
111t:order_summary_view.is_test_order a m:Column ;
112 rdfs:label "Is Test Order" ;
113 rdfs:comment "Boolean flag indicating whether this is a test order that should be excluded from reporting." ;
114 m:belongsToTable t:order_summary_view .
115
116t:order_summary_view.customer_id a m:Column ;
117 rdfs:label "Customer ID" ;
118 rdfs:comment "FK to customers table. Denormalized into the view for join-free access." ;
119 m:belongsToTable t:order_summary_view .
120
121t:order_summary_view.quantity a m:Column ;
122 rdfs:label "Quantity" ;
123 rdfs:comment "Number of items in the order line." ;
124 m:belongsToTable t:order_summary_view .
125
126t:order_summary_view.product_id a m:Column ;
127 rdfs:label "Product ID" ;
128 rdfs:comment "FK to products table. Identifies the product in the order." ;
129 m:belongsToTable t:order_summary_view .
130
131t:customers.customer_id a m:Column ;
132 rdfs:label "Customer ID" ;
133 rdfs:comment "Customer unique identifier (PK)." ;
134 m:belongsToTable t:customers .
135
136t:customers.customer_segment a m:Column ;
137 rdfs:label "Customer Segment" ;
138 rdfs:comment "Customer segment classification: Premium, Standard, New, Churned." ;
139 m:belongsToTable t:customers .
140
141t:customers.customer_name a m:Column ;
142 rdfs:label "Customer Name" ;
143 rdfs:comment "Full name of the customer." ;
144 m:belongsToTable t:customers .
145
146t:customers.customer_email a m:Column ;
147 rdfs:label "Customer Email" ;
148 rdfs:comment "Primary email address of the customer." ;
149 m:belongsToTable t:customers .
150
151t:customers.customer_country a m:Column ;
152 rdfs:label "Customer Country" ;
153 rdfs:comment "ISO country code of the customer. Master data source for the denormalized order_summary_view.customer_country." ;
154 m:belongsToTable t:customers .
155
156t:customers.customer_type a m:Column ;
157 rdfs:label "Customer Type" ;
158 rdfs:comment "Customer classification: regular, internal (staff), wholesale. Master data source for the denormalized order_summary_view.customer_type." ;
159 m:belongsToTable t:customers .
160
161t:customers.created_at a m:Column ;
162 rdfs:label "Created At" ;
163 rdfs:comment "Timestamp when the customer record was created (registration date)." ;
164 m:belongsToTable t:customers .
165
166# --- customer_loyalty columns ---
167
168t:customer_loyalty.customer_id a m:Column ;
169 rdfs:label "Loyalty Customer ID" ;
170 rdfs:comment "Reference to the customer this loyalty record belongs to." ;
171 m:belongsToTable t:customer_loyalty .
172
173t:customer_loyalty.tier a m:Column ;
174 rdfs:label "Loyalty Tier" ;
175 rdfs:comment "Loyalty program tier: bronze, silver, gold, platinum." ;
176 m:belongsToTable t:customer_loyalty .
177
178t:customer_loyalty.points_balance a m:Column ;
179 rdfs:label "Loyalty Points Balance" ;
180 rdfs:comment "Current loyalty point balance for the customer." ;
181 m:belongsToTable t:customer_loyalty .
182
183t:products.product_id a m:Column ;
184 rdfs:label "Product ID" ;
185 rdfs:comment "Product unique identifier (PK)." ;
186 m:belongsToTable t:products .
187
188t:products.product_name a m:Column ;
189 rdfs:label "Product Name" ;
190 rdfs:comment "Display name of the product." ;
191 m:belongsToTable t:products .
192
193t:products.product_category a m:Column ;
194 rdfs:label "Product Category" ;
195 rdfs:comment "Category the product belongs to: Electronics, Clothing, Home & Garden, Sports, Books." ;
196 m:belongsToTable t:products .
197
198t:products.product_price a m:Column ;
199 rdfs:label "Product Price" ;
200 rdfs:comment "Current list price of the product in EUR." ;
201 m:belongsToTable t:products .
202
203# --- service_items columns ---
204
205t:service_items.service_id a m:Column ;
206 rdfs:label "Service ID" ;
207 rdfs:comment "Unique service item identifier (PK)." ;
208 m:belongsToTable t:service_items .
209
210t:service_items.service_name a m:Column ;
211 rdfs:label "Service Name" ;
212 rdfs:comment "Display name of the service item." ;
213 m:belongsToTable t:service_items .
214
215t:service_items.service_category a m:Column ;
216 rdfs:label "Service Category" ;
217 rdfs:comment "Category the service belongs to: Warranty, Installation, Subscription, Support." ;
218 m:belongsToTable t:service_items .
219
220t:service_items.service_price a m:Column ;
221 rdfs:label "Service Price" ;
222 rdfs:comment "Current price of the service item in EUR." ;
223 m:belongsToTable t:service_items .
224
225t:order_summary_view.service_id a m:Column ;
226 rdfs:label "Service ID" ;
227 rdfs:comment "FK to service_items table. Identifies the service in the order. Null when the order line is for a product." ;
228 m:belongsToTable t:order_summary_view .
229
230# --- shipments columns ---
231t:shipments.order_id a m:Column ;
232 rdfs:label "Order ID" ;
233 rdfs:comment "Order this shipment fulfills (FK to order_summary_view.order_id)." ;
234 m:belongsToTable t:shipments .
235
236t:shipments.carrier_code a m:Column ;
237 rdfs:label "Carrier Code" ;
238 rdfs:comment "Carrier that handled this shipment (FK to carriers.carrier_code)." ;
239 m:belongsToTable t:shipments .
240
241# --- carriers columns ---
242t:carriers.carrier_code a m:Column ;
243 rdfs:label "Carrier Code" ;
244 rdfs:comment "Unique carrier identifier (PK)." ;
245 m:belongsToTable t:carriers .
246
247t:carriers.carrier_name a m:Column ;
248 rdfs:label "Carrier Name" ;
249 rdfs:comment "Human-readable carrier name." ;
250 m:belongsToTable t:carriers .
251
252# --- customer_product_favorites columns (pure junction: two FKs, no payload) ---
253t:customer_product_favorites.customer_id a m:Column ;
254 rdfs:label "Customer ID" ;
255 rdfs:comment "Favoriting customer (FK to customers.customer_id)." ;
256 m:belongsToTable t:customer_product_favorites .
257
258t:customer_product_favorites.product_id a m:Column ;
259 rdfs:label "Product ID" ;
260 rdfs:comment "Favorited product (FK to products.product_id)." ;
261 m:belongsToTable t:customer_product_favorites .
262
263# ===========================================================================
264# BUSINESS LAYER - CLASSES
265# ===========================================================================
266
267b:Order a owl:Class ;
268 rdfs:label "Order" ;
269 rdfs:comment "A customer order placed on the Acme Shop platform. Backed by the order_summary_view which is a denormalized view joining orders, customers, and products." ;
270 rdfs:seeAlso "ttl-uri"><https://schema.org/Order> ;
271 skos:example "ORD-2025-001234, ORD-2025-005678" ;
272 m:mapsToTable t:order_summary_view .
273
274b:Customer a owl:Class ;
275 rdfs:label "Customer" ;
276 skos:altLabel "Buyer", "Account" ;
277 rdfs:comment "A registered customer of Acme Shop." ;
278 rdfs:seeAlso "ttl-uri"><https://schema.org/Person> ;
279 skos:example "Jane Smith, Acme Corporation" ;
280 m:mapsToTable t:customers .
281
282b:LoyaltyMember a owl:Class, m:BusinessView ;
283 rdfs:label "Loyalty Member" ;
284 rdfs:comment "An enrolled loyalty-program customer, with tier and points alongside the customer's name and contact details." ;
285 rdfs:seeAlso b:Customer ;
286 skos:example "Jane Smith (Gold, 12 480 pts), Acme Corporation (Platinum, 87 200 pts)" ;
287 m:mapsToTable t:customers, t:customer_loyalty ;
288 m:joinCondition "customers.customer_id = customer_loyalty.customer_id"^^xsd:string .
289
290b:loyaltyMemberTier a owl:DatatypeProperty ;
291 rdfs:label "Loyalty Tier" ;
292 rdfs:domain b:LoyaltyMember ;
293 rdfs:range xsd:string ;
294 rdfs:comment "Loyalty program tier — bronze, silver, gold, platinum." ;
295 m:mapsToColumn t:customer_loyalty.tier ;
296 bv:enumType "dynamic" .
297
298b:loyaltyMemberPoints a owl:DatatypeProperty ;
299 rdfs:label "Loyalty Points Balance" ;
300 rdfs:domain b:LoyaltyMember ;
301 rdfs:range xsd:integer ;
302 rdfs:comment "Current point balance for the member." ;
303 m:mapsToColumn t:customer_loyalty.points_balance .
304
305b:loyaltyMemberName a owl:DatatypeProperty ;
306 rdfs:label "Loyalty Member Name" ;
307 rdfs:domain b:LoyaltyMember ;
308 rdfs:range xsd:string ;
309 rdfs:comment "Full name of the loyalty member." ;
310 m:mapsToColumn t:customers.customer_name .
311
312# --- Polymorphic relationship: Purchasable (Product or ServiceItem) ---
313# An Order can reference either a Product or a ServiceItem via the common
314# superclass Purchasable. This models a polymorphic association in OWL:
315# orderHasPurchasable has range b:Purchasable, and both Product and ServiceItem
316# are subclasses, so the relationship accepts either type.
317
318b:Purchasable a owl:Class ;
319 rdfs:label "Purchasable" ;
320 rdfs:comment "Abstract superclass for anything that can appear as a line item in an order. Subclassed by Product (physical goods) and ServiceItem (services, warranties, subscriptions). This class has no direct table mapping — use the concrete subclasses Product (t:products) or ServiceItem (t:service_items) for queries." .
321
322b:Product a owl:Class ;
323 rdfs:subClassOf b:Purchasable ;
324 rdfs:label "Product" ;
325 skos:altLabel "Item", "SKU" ;
326 rdfs:comment "A physical product available in the Acme Shop catalog." ;
327 rdfs:seeAlso "ttl-uri"><https://schema.org/Product> ;
328 skos:example "Wireless Mouse Pro, Organic Cotton T-Shirt, Standing Desk" ;
329 owl:disjointWith b:ServiceItem ;
330 m:mapsToTable t:products .
331
332b:ServiceItem a owl:Class ;
333 rdfs:subClassOf b:Purchasable ;
334 rdfs:label "Service Item" ;
335 skos:altLabel "Service", "Add-on" ;
336 rdfs:comment "A service offering such as a warranty, installation, or subscription that can be purchased alongside or independently of a product." ;
337 rdfs:seeAlso "ttl-uri"><https://schema.org/Service> ;
338 skos:example "2-Year Extended Warranty, Professional Installation, Monthly Support Plan" ;
339 owl:disjointWith b:Product ;
340 m:mapsToTable t:service_items .
341
342# --- Subclasses with filters ---
343
344b:WholesaleCustomer a owl:Class, m:BusinessView ;
345 rdfs:subClassOf b:Customer ;
346 rdfs:label "Wholesale Customer" ;
347 rdfs:comment "Customer purchasing in bulk at wholesale prices. Identified by customer_type = 'wholesale' in the order view." ;
348 owl:disjointWith b:InternalCustomer ;
349 m:mapsToTable t:order_summary_view ;
350 m:joinCondition "order_summary_view.customer_type = 'wholesale'"^^xsd:string .
351
352b:InternalCustomer a owl:Class, m:BusinessView ;
353 rdfs:subClassOf b:Customer ;
354 rdfs:label "Internal Customer" ;
355 rdfs:comment "Internal staff purchases. Typically excluded from revenue reporting. Identified by customer_type = 'internal'." ;
356 m:mapsToTable t:order_summary_view ;
357 m:joinCondition "order_summary_view.customer_type = 'internal'"^^xsd:string .
358
359b:PremiumWholesaleCustomer a owl:Class, m:BusinessView ;
360 rdfs:subClassOf b:WholesaleCustomer ;
361 rdfs:label "Premium Wholesale Customer" ;
362 rdfs:comment "High-value wholesale customers with premium pricing agreements. Identified by customer_type = 'wholesale' AND customer_segment = 'Premium'." ;
363 m:mapsToTable t:order_summary_view ;
364 m:joinCondition "order_summary_view.customer_type = 'wholesale' AND customers.customer_segment = 'Premium'"^^xsd:string .
365
366b:ReturnedOrder a owl:Class, m:BusinessView ;
367 rdfs:subClassOf b:Order ;
368 rdfs:label "Returned Order" ;
369 rdfs:comment "Orders that were returned or refunded by the customer." ;
370 owl:disjointWith b:CancelledOrder ;
371 m:mapsToTable t:order_summary_view ;
372 m:joinCondition "order_summary_view.order_status = 'returned'"^^xsd:string .
373
374b:CancelledOrder a owl:Class, m:BusinessView ;
375 rdfs:subClassOf b:Order ;
376 rdfs:label "Cancelled Order" ;
377 rdfs:comment "Orders that were cancelled before fulfillment. NOTE: Mutually exclusive with ReturnedOrder - an order is either cancelled or returned, not both." ;
378 rdfs:seeAlso b:ReturnedOrder ;
379 m:mapsToTable t:order_summary_view ;
380 m:joinCondition "order_summary_view.order_status = 'cancelled'"^^xsd:string .
381
382# Carrier (range of the bridge-join example). Note: the favorites junction
383# table has NO class — a pure junction is modeled as a relationship, not an entity.
384b:Carrier a owl:Class ;
385 rdfs:label "Carrier" ;
386 rdfs:comment "A shipping carrier that delivers orders." ;
387 m:mapsToTable t:carriers .
388
389# ===========================================================================
390# BUSINESS LAYER - RELATIONSHIPS
391# ===========================================================================
392
393b:customerHasOrder a owl:ObjectProperty ;
394 rdfs:domain b:Customer ;
395 rdfs:range b:Order ;
396 rdfs:label "customer has order" ;
397 rdfs:comment "Links a customer to all orders they have placed. Joined via customer_id." ;
398 owl:inverseOf b:orderForCustomer ;
399 m:realizedBy "customers.customer_id = order_summary_view.customer_id"^^xsd:string .
400
401b:orderForCustomer a owl:ObjectProperty ;
402 rdfs:domain b:Order ;
403 rdfs:range b:Customer ;
404 rdfs:label "order for customer" ;
405 rdfs:comment "Links an order back to the customer who placed it. Inverse of customerHasOrder." ;
406 owl:inverseOf b:customerHasOrder ;
407 m:realizedBy "order_summary_view.customer_id = customers.customer_id"^^xsd:string .
408
409b:orderHasProduct a owl:ObjectProperty ;
410 rdfs:subPropertyOf b:orderHasPurchasable ;
411 rdfs:domain b:Order ;
412 rdfs:range b:Product ;
413 rdfs:label "order has product" ;
414 rdfs:comment "Links an order to the physical product purchased. Joined via product_id." ;
415 owl:inverseOf b:productInOrder ;
416 m:realizedBy "order_summary_view.product_id = products.product_id"^^xsd:string .
417
418b:productInOrder a owl:ObjectProperty ;
419 rdfs:domain b:Product ;
420 rdfs:range b:Order ;
421 rdfs:label "product in order" ;
422 rdfs:comment "Links a product to all orders in which it appears. Inverse of orderHasProduct." ;
423 owl:inverseOf b:orderHasProduct ;
424 m:realizedBy "products.product_id = order_summary_view.product_id"^^xsd:string .
425
426# --- Polymorphic purchasable relationship ---
427# orderHasPurchasable accepts any Purchasable subclass (Product or ServiceItem).
428# The specific subtype relationships (orderHasProduct, orderHasServiceItem) are
429# declared as sub-properties, so navigating orderHasPurchasable returns both.
430
431b:orderHasPurchasable a owl:ObjectProperty ;
432 rdfs:domain b:Order ;
433 rdfs:range b:Purchasable ;
434 rdfs:label "order has purchasable" ;
435 rdfs:comment "Links an order to any purchasable item (product or service). This is the polymorphic relationship — use orderHasProduct or orderHasServiceItem for type-specific access. Realized via product_id or service_id depending on the subtype." ;
436 m:realizedBy "order_summary_view.product_id = products.product_id OR order_summary_view.service_id = service_items.service_id"^^xsd:string .
437
438b:orderHasServiceItem a owl:ObjectProperty ;
439 rdfs:subPropertyOf b:orderHasPurchasable ;
440 rdfs:domain b:Order ;
441 rdfs:range b:ServiceItem ;
442 rdfs:label "order has service item" ;
443 rdfs:comment "Links an order to the service item purchased. Joined via service_id." ;
444 owl:inverseOf b:serviceItemInOrder ;
445 m:realizedBy "order_summary_view.service_id = service_items.service_id"^^xsd:string .
446
447b:serviceItemInOrder a owl:ObjectProperty ;
448 rdfs:domain b:ServiceItem ;
449 rdfs:range b:Order ;
450 rdfs:label "service item in order" ;
451 rdfs:comment "Links a service item to all orders in which it appears. Inverse of orderHasServiceItem." ;
452 owl:inverseOf b:orderHasServiceItem ;
453 m:realizedBy "service_items.service_id = order_summary_view.service_id"^^xsd:string .
454
455# --- Bridge-table join (ADR-069): Order <-> Carrier through the `shipments`
456# table. The m:realizedBy is a single linear equality chain from the domain
457# table (order_summary_view) to the range table (carriers); the engine
458# auto-joins the intermediate "bridge" table.
459b:orderShippedByCarrier a owl:ObjectProperty ;
460 rdfs:label "shipped by carrier" ;
461 rdfs:comment "Links an order to the carrier that shipped it, via the shipments bridge table." ;
462 rdfs:domain b:Order ;
463 rdfs:range b:Carrier ;
464 owl:inverseOf b:carrierShippedOrder ;
465 m:relationshipRole "Transactional" ;
466 m:realizedBy "order_summary_view.order_id = shipments.order_id AND shipments.carrier_code = carriers.carrier_code"^^xsd:string .
467
468b:carrierShippedOrder a owl:ObjectProperty ;
469 rdfs:label "shipped order" ;
470 rdfs:comment "Links a carrier to the orders it shipped, via the shipments bridge table." ;
471 rdfs:domain b:Carrier ;
472 rdfs:range b:Order ;
473 owl:inverseOf b:orderShippedByCarrier ;
474 m:relationshipRole "Transactional" ;
475 m:realizedBy "carriers.carrier_code = shipments.carrier_code AND shipments.order_id = order_summary_view.order_id"^^xsd:string .
476
477# --- Many-to-many via a pure junction: Customer <-> Product through
478# `customer_product_favorites`. The junction carries no payload, so it is
479# modeled as a single through-junction Membership relationship (no business
480# class for the junction); the engine auto-joins it as a bridge.
481b:customerFavoritedProduct a owl:ObjectProperty ;
482 rdfs:label "favorited product" ;
483 rdfs:comment "A product the customer has favorited, via the favorites junction." ;
484 rdfs:domain b:Customer ;
485 rdfs:range b:Product ;
486 owl:inverseOf b:productFavoritedByCustomer ;
487 m:relationshipRole "Membership" ;
488 m:realizedBy "customers.customer_id = customer_product_favorites.customer_id AND customer_product_favorites.product_id = products.product_id"^^xsd:string .
489
490b:productFavoritedByCustomer a owl:ObjectProperty ;
491 rdfs:label "favorited by customer" ;
492 rdfs:comment "A customer who has favorited the product, via the favorites junction." ;
493 rdfs:domain b:Product ;
494 rdfs:range b:Customer ;
495 owl:inverseOf b:customerFavoritedProduct ;
496 m:relationshipRole "Membership" ;
497 m:realizedBy "products.product_id = customer_product_favorites.product_id AND customer_product_favorites.customer_id = customers.customer_id"^^xsd:string .
498
499# ===========================================================================
500# BUSINESS LAYER - PROPERTIES (Dimensions)
501# ===========================================================================
502
503b:orderId a owl:DatatypeProperty ;
504 rdfs:label "Order ID" ;
505 rdfs:domain b:Order ;
506 rdfs:range xsd:string ;
507 rdfs:comment "Unique order identifier." ;
508 m:mapsToColumn t:order_summary_view.order_id .
509
510b:orderDate a owl:DatatypeProperty ;
511 rdfs:label "Order Date" ;
512 rdfs:domain b:Order ;
513 rdfs:range xsd:date ;
514 rdfs:comment "Date when the order was placed. Primary time dimension for all order-related metrics." ;
515 m:mapsToColumn t:order_summary_view.order_date .
516
517b:orderTotal a owl:DatatypeProperty ;
518 rdfs:label "Order Total" ;
519 rdfs:domain b:Order ;
520 rdfs:range xsd:decimal ;
521 rdfs:comment "Total monetary value of the order. Currency varies (see orderCurrency)." ;
522 m:mapsToColumn t:order_summary_view.order_total .
523
524b:orderStatus a owl:DatatypeProperty ;
525 rdfs:label "Order Status" ;
526 rdfs:domain b:Order ;
527 rdfs:range xsd:string ;
528 rdfs:comment "Current fulfillment status of the order." ;
529 m:mapsToColumn t:order_summary_view.order_status ;
530 bv:enumType "dynamic" .
531
532b:customerCountry a owl:DatatypeProperty ;
533 rdfs:label "Customer Country" ;
534 rdfs:domain b:Order ;
535 rdfs:range xsd:string ;
536 rdfs:comment "ISO country code of the ordering customer. Only available for customers who have placed orders. See b:customerCountryMaster for the master data version." ;
537 bv:masterProperty b:customerCountryMaster ;
538 rdfs:seeAlso b:customerCountryMaster ;
539 m:mapsToColumn t:order_summary_view.customer_country ;
540 bv:enumType "country" .
541
542b:productCategory a owl:DatatypeProperty ;
543 rdfs:label "Product Category" ;
544 rdfs:domain b:Order ;
545 rdfs:range xsd:string ;
546 rdfs:comment "Category of the ordered product. Only available for products that appear in orders. See b:productCategoryMaster for the master data version." ;
547 bv:masterProperty b:productCategoryMaster ;
548 rdfs:seeAlso b:productCategoryMaster ;
549 m:mapsToColumn t:order_summary_view.product_category ;
550 bv:enumType "dynamic" .
551
552b:paymentMethod a owl:DatatypeProperty ;
553 rdfs:label "Payment Method" ;
554 rdfs:domain b:Order ;
555 rdfs:range xsd:string ;
556 rdfs:comment "Method of payment used for the order." ;
557 m:mapsToColumn t:order_summary_view.payment_method ;
558 bv:enumType "dynamic" .
559
560b:orderCurrency a owl:DatatypeProperty ;
561 rdfs:label "Order Currency" ;
562 rdfs:domain b:Order ;
563 rdfs:range xsd:string ;
564 rdfs:comment "ISO currency code for the order amount." ;
565 m:mapsToColumn t:order_summary_view.currency ;
566 bv:enumType "currency" .
567
568b:customerType a owl:DatatypeProperty ;
569 rdfs:label "Customer Type" ;
570 rdfs:domain b:Order ;
571 rdfs:range xsd:string ;
572 rdfs:comment "Classification of the customer. Determines eligibility for reporting (internal/test orders are typically excluded). See b:customerTypeMaster for the master data version." ;
573 bv:masterProperty b:customerTypeMaster ;
574 rdfs:seeAlso b:customerTypeMaster ;
575 m:mapsToColumn t:order_summary_view.customer_type ;
576 bv:enumType "dynamic" .
577
578b:customerId a owl:DatatypeProperty ;
579 rdfs:label "Customer ID" ;
580 rdfs:domain b:Order ;
581 rdfs:range xsd:string ;
582 rdfs:comment "Customer identifier. FK to customers table, available directly in order_summary_view." ;
583 rdfs:seeAlso b:orderForCustomer ;
584 m:mapsToColumn t:order_summary_view.customer_id .
585
586b:orderQuantity a owl:DatatypeProperty ;
587 rdfs:label "Order Quantity" ;
588 rdfs:domain b:Order ;
589 rdfs:range xsd:integer ;
590 rdfs:comment "Number of items in the order." ;
591 m:mapsToColumn t:order_summary_view.quantity .
592
593b:isTestOrder a owl:DatatypeProperty ;
594 rdfs:label "Is Test Order" ;
595 rdfs:domain b:Order ;
596 rdfs:range xsd:boolean ;
597 rdfs:comment "Boolean flag indicating whether this is a test order. Test orders are excluded from revenue and performance metrics." ;
598 m:mapsToColumn t:order_summary_view.is_test_order ;
599 bv:enumType "boolean" .
600
601b:productId a owl:DatatypeProperty ;
602 rdfs:label "Product ID" ;
603 rdfs:domain b:Order ;
604 rdfs:range xsd:string ;
605 rdfs:comment "Product identifier. FK to products table, available directly in order_summary_view." ;
606 rdfs:seeAlso b:orderHasProduct ;
607 m:mapsToColumn t:order_summary_view.product_id .
608
609b:productName a owl:DatatypeProperty ;
610 rdfs:label "Product Name" ;
611 rdfs:domain b:Product ;
612 rdfs:range xsd:string ;
613 rdfs:comment "Display name of the product." ;
614 m:mapsToColumn t:products.product_name .
615
616b:productCategoryMaster a owl:DatatypeProperty ;
617 rdfs:label "Product Category (Master)" ;
618 rdfs:domain b:Product ;
619 rdfs:range xsd:string ;
620 rdfs:comment "Category from the product catalog master table. See also b:productCategory on b:Order for the denormalized version available in order analytics." ;
621 rdfs:seeAlso b:productCategory ;
622 m:mapsToColumn t:products.product_category ;
623 bv:enumType "dynamic" .
624
625b:productPrice a owl:DatatypeProperty ;
626 rdfs:label "Product Price" ;
627 rdfs:domain b:Product ;
628 rdfs:range xsd:decimal ;
629 rdfs:comment "Current list price of the product in EUR." ;
630 m:mapsToColumn t:products.product_price .
631
632# --- ServiceItem properties ---
633
634b:serviceId a owl:DatatypeProperty ;
635 rdfs:label "Service ID" ;
636 rdfs:domain b:ServiceItem ;
637 rdfs:range xsd:string ;
638 rdfs:comment "Unique service item identifier." ;
639 m:mapsToColumn t:service_items.service_id .
640
641b:serviceName a owl:DatatypeProperty ;
642 rdfs:label "Service Name" ;
643 rdfs:domain b:ServiceItem ;
644 rdfs:range xsd:string ;
645 rdfs:comment "Display name of the service item." ;
646 m:mapsToColumn t:service_items.service_name .
647
648b:serviceCategory a owl:DatatypeProperty ;
649 rdfs:label "Service Category" ;
650 rdfs:domain b:ServiceItem ;
651 rdfs:range xsd:string ;
652 rdfs:comment "Category of the service item." ;
653 m:mapsToColumn t:service_items.service_category ;
654 bv:enumType "dynamic" .
655
656b:servicePrice a owl:DatatypeProperty ;
657 rdfs:label "Service Price" ;
658 rdfs:domain b:ServiceItem ;
659 rdfs:range xsd:decimal ;
660 rdfs:comment "Current price of the service item in EUR." ;
661 m:mapsToColumn t:service_items.service_price .
662
663b:customerSegment a owl:DatatypeProperty ;
664 rdfs:label "Customer Segment" ;
665 rdfs:domain b:Customer ;
666 rdfs:range xsd:string ;
667 rdfs:comment "Customer segment classification from the customer master table." ;
668 m:mapsToColumn t:customers.customer_segment ;
669 bv:enumType "dynamic" .
670
671b:customerName a owl:DatatypeProperty ;
672 rdfs:label "Customer Name" ;
673 rdfs:domain b:Customer ;
674 rdfs:range xsd:string ;
675 rdfs:comment "Full name of the customer." ;
676 m:mapsToColumn t:customers.customer_name .
677
678b:customerEmail a owl:DatatypeProperty ;
679 rdfs:label "Customer Email" ;
680 rdfs:domain b:Customer ;
681 rdfs:range xsd:string ;
682 rdfs:comment "Primary email address of the customer. Contains PII — access is restricted." ;
683 bv:sensitivityLevel "Confidential" ;
684 bv:complianceCategory "PII" ;
685 bv:maskingRule "redact" ;
686 m:mapsToColumn t:customers.customer_email .
687
688b:customerCountryMaster a owl:DatatypeProperty ;
689 rdfs:label "Customer Country (Master)" ;
690 rdfs:domain b:Customer ;
691 rdfs:range xsd:string ;
692 rdfs:comment "ISO country code from the customer master table. See also b:customerCountry on b:Order for the denormalized version available in order analytics." ;
693 rdfs:seeAlso b:customerCountry ;
694 m:mapsToColumn t:customers.customer_country ;
695 bv:enumType "dynamic" .
696
697b:customerTypeMaster a owl:DatatypeProperty ;
698 rdfs:label "Customer Type (Master)" ;
699 rdfs:domain b:Customer ;
700 rdfs:range xsd:string ;
701 rdfs:comment "Customer classification from the master table. See also b:customerType on b:Order for the denormalized version available in order analytics." ;
702 rdfs:seeAlso b:customerType ;
703 m:mapsToColumn t:customers.customer_type ;
704 bv:enumType "dynamic" .
705
706b:customerCreatedAt a owl:DatatypeProperty ;
707 rdfs:label "Customer Registration Date" ;
708 rdfs:domain b:Customer ;
709 rdfs:range xsd:dateTime ;
710 rdfs:comment "Timestamp when the customer registered." ;
711 m:mapsToColumn t:customers.created_at .
712
713# --- Carrier properties ---
714b:carrierName a owl:DatatypeProperty ;
715 rdfs:label "Carrier Name" ;
716 rdfs:domain b:Carrier ;
717 rdfs:range xsd:string ;
718 rdfs:comment "The carrier's display name." ;
719 m:mapsToColumn t:carriers.carrier_name .
720
721# ===========================================================================
722# BUSINESS LAYER - CONSTANTS
723# ===========================================================================
724
725b:gbpToEurExchangeRate a bv:BusinessConstant ;
726 rdfs:label "GBP to EUR Exchange Rate" ;
727 rdfs:comment "Fixed exchange rate for converting GBP to EUR. Rate: 1 GBP = 0.85 EUR. To convert GBP amounts to EUR, divide by 0.85. This value is inlined in metric expressions." ;
728 bv:constantValue "0.85"^^xsd:decimal .
729
730# ===========================================================================
731# ACCESS CONTROL
732# ===========================================================================
733
734# Restricts revenue-bearing metrics to admin role and finance group.
735# Applied below to b:totalRevenueMetric and b:revenuePerCustomerSegmentMetric.
736b:revenueAccessPolicy a bv:AccessPolicy ;
737 rdfs:label "Revenue access policy" ;
738 rdfs:comment "Only admins and the finance group may query revenue-bearing metrics." ;
739 bv:allowRole "admin" ;
740 bv:allowGroup "finance" .
741
742# Row-level filter on order_summary_view: a non-admin user only sees
743# orders whose customer_country is in their {{user.region}} attribute.
744# Admin role is exempt. Applied to all order-sourced metrics below.
745b:customerCountryRowFilter a bv:RowFilter ;
746 rdfs:label "Customer country row filter" ;
747 rdfs:comment "Per-user region restriction on Order rows. Non-admin callers only see orders whose customer_country is in their {{user.region}} attribute." ;
748 bv:filterExpression "customer_country IN ({{user.region}})" ;
749 bv:exemptRole "admin" .
750
751# ===========================================================================
752# BUSINESS LAYER - METRICS (with structured properties)
753# ===========================================================================
754
755b:totalRevenueMetric a bv:Metric ;
756 rdfs:label "Total Revenue" ;
757 skos:altLabel "Gross Revenue", "Total Sales" ;
758 rdfs:comment "Total order revenue with automatic GBP to EUR conversion. Includes ALL order types and statuses. For order count see b:orderCountMetric; for average value see b:averageOrderValueMetric." ;
759 rdfs:seeAlso b:orderCountMetric, b:averageOrderValueMetric ;
760 bv:metricExpression "SUM(CASE WHEN b:orderCurrency = 'GBP' THEN b:orderTotal / {{gbpToEurExchangeRate}} ELSE b:orderTotal END)" ;
761 bv:sourceEntity b:Order ;
762 bv:timeDimension b:orderDate ;
763 bv:dependsOnProperty b:orderTotal, b:orderCurrency ;
764 bv:dependsOnConstant b:gbpToEurExchangeRate ;
765 bv:metricCategory "Revenue" ;
766 bv:accessPolicy b:revenueAccessPolicy ;
767 bv:rowFilter b:customerCountryRowFilter .
768
769b:orderCountMetric a bv:Metric ;
770 rdfs:label "Order Count" ;
771 skos:altLabel "Number of Orders", "Total Orders" ;
772 rdfs:comment "Total number of orders placed. Counts all orders regardless of status. For revenue see b:totalRevenueMetric." ;
773 rdfs:seeAlso b:totalRevenueMetric ;
774 bv:metricExpression "COUNT(*)" ;
775 bv:sourceEntity b:Order ;
776 bv:timeDimension b:orderDate ;
777 bv:dependsOnProperty b:orderId ;
778 bv:metricCategory "Orders" ;
779 bv:rowFilter b:customerCountryRowFilter .
780
781b:averageOrderValueMetric a bv:Metric ;
782 rdfs:label "Average Order Value" ;
783 skos:altLabel "AOV", "Avg Order Value" ;
784 rdfs:comment "Average revenue per order. Equivalent to total_revenue / order_count." ;
785 rdfs:seeAlso b:totalRevenueMetric, b:orderCountMetric ;
786 bv:metricExpression "AVG(b:orderTotal)" ;
787 bv:sourceEntity b:Order ;
788 bv:timeDimension b:orderDate ;
789 bv:dependsOnProperty b:orderTotal ;
790 bv:metricCategory "Revenue" ;
791 bv:rowFilter b:customerCountryRowFilter .
792
793b:returnRateMetric a bv:Metric ;
794 rdfs:label "Return Rate" ;
795 skos:altLabel "Return %", "Refund Rate" ;
796 rdfs:comment "Percentage of orders that were returned or refunded, excluding test orders and internal staff purchases. Formula: returned_orders / total_orders * 100. A value of 5% means one in twenty orders was returned." ;
797 bv:metricExpression """100.0 * SUM(CASE WHEN b:orderStatus = 'returned' THEN 1 ELSE 0 END)
798 / NULLIF(COUNT(*), 0)""" ;
799 bv:sourceEntity b:Order ;
800 bv:metricPreFilter "b:customerType <> 'internal' AND b:isTestOrder = false" ;
801 bv:timeDimension b:orderDate ;
802 bv:dependsOnProperty b:orderStatus, b:customerType, b:isTestOrder ;
803 bv:metricCategory "Orders" ;
804 bv:rowFilter b:customerCountryRowFilter .
805
806b:uniqueCustomersMetric a bv:Metric ;
807 rdfs:label "Unique Customers" ;
808 skos:altLabel "Distinct Customers", "Active Buyers" ;
809 rdfs:comment "Number of distinct customers who placed orders in the period. NOTE: This is an ACTIVITY-BASED count - only customers with at least one order are counted. This is NOT a master data count of all registered customers." ;
810 bv:metricExpression "COUNT(DISTINCT b:customerId)" ;
811 bv:sourceEntity b:Order ;
812 bv:timeDimension b:orderDate ;
813 bv:dependsOnProperty b:customerId ;
814 bv:metricCategory "Customers" ;
815 bv:rowFilter b:customerCountryRowFilter .
816
817b:totalItemsSoldMetric a bv:Metric ;
818 rdfs:label "Total Items Sold" ;
819 skos:altLabel "Units Sold", "Total Quantity" ;
820 rdfs:comment "Total number of items sold across all orders." ;
821 bv:metricExpression "SUM(b:orderQuantity)" ;
822 bv:sourceEntity b:Order ;
823 bv:timeDimension b:orderDate ;
824 bv:dependsOnProperty b:orderQuantity ;
825 bv:metricCategory "Orders" ;
826 bv:rowFilter b:customerCountryRowFilter .
827
828# Multi-table metric using SQL template escape hatch
829b:revenuePerCustomerSegmentMetric a bv:Metric ;
830 rdfs:label "Revenue Per Customer Segment" ;
831 rdfs:comment "Average revenue per customer, broken down by customer segment. Requires joining orders with customer master data. For total revenue without segmentation, see b:totalRevenueMetric." ;
832 rdfs:seeAlso b:totalRevenueMetric ;
833 bv:metricSql """
834 SELECT DATE_TRUNC('{{granularity}}', order_summary_view.order_date) AS time_dimension
835 {{select_dimensions}},
836 CASE WHEN COUNT(DISTINCT customers.customer_id) > 0
837 THEN SUM(order_summary_view.order_total) / COUNT(DISTINCT customers.customer_id)
838 ELSE 0 END AS metric_value
839 FROM order_summary_view
840 INNER JOIN customers ON order_summary_view.customer_id = customers.customer_id
841 {{join_clauses}}
842 WHERE order_summary_view.order_date >= '{{start_date}}' AND order_summary_view.order_date < '{{end_date}}'
843 {{where_filters}}
844 GROUP BY 1 {{group_by_dimensions}}
845 ORDER BY 1
846 """ ;
847 bv:sourceEntity b:Order ;
848 bv:timeDimension b:orderDate ;
849 bv:dependsOnProperty b:orderTotal, b:customerId, b:customerSegment ;
850 bv:dependsOnRelationship b:customerHasOrder ;
851 bv:metricCategory "Revenue" ;
852 bv:accessPolicy b:revenueAccessPolicy ;
853 bv:rowFilter b:customerCountryRowFilter .
854
855b:newCustomerRegistrationsMetric a bv:Metric ;
856 rdfs:label "New Customer Registrations" ;
857 skos:altLabel "New Signups", "Customer Registrations" ;
858 rdfs:comment "Number of new customer registrations per period. Excludes internal (staff) customers. For activity-based customer counts (customers who placed orders), see b:uniqueCustomersMetric." ;
859 rdfs:seeAlso b:uniqueCustomersMetric ;
860 bv:metricExpression "COUNT(*)" ;
861 bv:sourceEntity b:Customer ;
862 bv:metricPreFilter "b:customerTypeMaster <> 'internal'" ;
863 bv:timeDimension b:customerCreatedAt ;
864 bv:dependsOnProperty b:customerTypeMaster ;
865 bv:metricCategory "Customers" .
866
867# ================================================================
868# CORRELATIONS — How metrics relate to each other
869# ================================================================
870
871# Statistical: new customer registrations correlate with return rate
872b:newRegistrations_correlates_returnRate a bv:MetricCorrelation ;
873 rdfs:label "New Registrations ↔ Return Rate" ;
874 rdfs:comment "New customers return items at higher rates than repeat buyers — unfamiliar with sizing and product quality. The effect flattens at high registration volumes." ;
875 bv:sourceMetric b:newCustomerRegistrationsMetric ;
876 bv:targetMetric b:returnRateMetric ;
877 bv:correlationType "statistical" ;
878 bv:correlationStrength "0.62" ;
879 bv:correlationCurve "logarithmic" .
880
881# Causal: high return rates drive down average order value
882b:returnRate_drives_averageOrderValue a bv:MetricCorrelation ;
883 rdfs:label "Return Rate → AOV" ;
884 rdfs:comment "Higher return rates tend to reduce effective AOV as returned items deflate averages." ;
885 bv:sourceMetric b:returnRateMetric ;
886 bv:targetMetric b:averageOrderValueMetric ;
887 bv:correlationType "causal" ;
888 bv:correlationStrength "moderate" ;
889 bv:correlationCurve "inverse" .
890
Related resources
Ontology overview What is a business ontology? Mapping vocabulary Business vocabulary
Build your own ontology with Magnowlia

Connect your data, define metrics, and start asking questions in plain English.

Get Started Free