Below is the architecture of a decoupled semantic layer(cube.dev) setup
![[process-flow-semantic-layer.drawio.svg]]
## 1.Mart (data warehouse + dbt)
Your mart contains your business entities(customers,orders etc.) in star schema format.
## 2.Cubes (cube.dev)
When building a data model in Cube, you work with two dataset-centric objects: **cubes** and **views**. **Cubes** usually represent business entities such as customers, line items, and orders. In cubes, you define all the calculations within the measures and dimensions of these entities. Additionally, you define relationships between cubes, such as "an order has many line items" or "a user may place multiple orders."
:warning: cubes are **not exposed** to data consumers
```
cubes:
# supply-chain data domain
 - name: orders
 - sql_table: mart-supply-chain.orders Â
Â
  dimensions: []
  measures: []
  joins:
   - name: customers
    relationship: many_to_one
    sql: "{orders.customer_id} = {customers.id}"     Â
 - name: line_items
 - sql_table: mart-supply-chain.line_items
Â
  dimensions: []
  measures: []
  joins:
   - name: orders
    relationship: many_to_one
    sql: "{line_items.order_id} = {orders.id}"  Â
# customers data domain
 - name: customers
 - sql_table: mart-customers.customers      Â
Â
  dimensions: []
  measures: []
  joins:
   - name: rentals
    relationship: one_to_many
    sql: "{customers.id} = {rentals.customer_id}"
   - name: orders
    relationship: one_to_many
    sql: "{customers.id} = {orders.customer_id}"
# rentals data domain
 - name: rentals
 - sql_table: mart-rentals.rentals Â
Â
  dimensions: []
  measures: []
  joins:
   - name: customers
    relationship: many_to_one
    sql: "{rentals.customer_id} = {customers.id}"
```
## 3.Views (cube.dev)
**Views** sit on top of a data graph of cubes and create a facade of your entire data model, with which data consumers can interact. You can think of views as **the final data products for your data consumers - BI users, data apps, AI agents, etc.** When building views, you select measures and dimensions from different connected cubes and present them as a single dataset to BI or data apps.
```
views:
 - name: order_line_items
  description: order_line_items
  public: {{ is_accessible_by_data_domain('supply-chain', COMPILE_CONTEXT) }}"
cubes:
- join_path: orders
includes:
   - orders.id
   - orders.date
- join_path: orders.line_items
includes:
   - line_items.id
   - line_items.product_name
 - name: customer_360
  description: customer_360
  public: {{ is_accessible_by_data_domain('customers', COMPILE_CONTEXT) }}"  Â
Â
- join_path: customers
includes:
- customers.id
   - customers.name
- join_path: customers.orders
includes:
   - orders.order_amount
   - orders.order_quantity
- join_path: customers.rentals
includes:
   - rentals.rental_amount
   - rentals.rental_quantity
 - name: rentals
  description: rentals
  public: {{ is_accessible_by_data_domain('rentals', COMPILE_CONTEXT) }}"  Â
Â
- join_path: rentals
includes:
- rentals.id
   - rentals.name
```
## Cube.dev project structure
Below an example of how a Cube.dev project could look like if we use data domains like (supply-chain,customers,rentals)
```
semantic-layer/
├── schema/
│ ├── cubes/
│ │ ├── supply-chain/
│ │ │ ├── orders.yml
│ │ │ ├── line_items.yml
│ │ ├── customers/
│ │ │ ├── customers.yml
│ │ ├── rentals/
│ │ │ ├── rentals.yml
│ ├── views/
│ │ ├── supply-chain/
│ │ │ ├── order_line_items.yml
│ │ ├── customers/
│ │ │ ├── customer_360.yml
│ │ ├── rentals/
│ │ │ ├── rentals.yml
```