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 ```